VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c@ 44417

Last change on this file since 44417 was 43363, checked in by vboxsync, 12 years ago

Haiku Additions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
Line 
1/* $Id: semeventmulti-r0drv-haiku.c 43363 2012-09-20 09:56:07Z vboxsync $ */
2/** @file
3 * IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Haiku.
4 */
5
6/*
7 * Copyright (C) 2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include "the-haiku-kernel.h"
31#include "internal/iprt.h"
32#include <iprt/semaphore.h>
33
34#include <iprt/assert.h>
35#include <iprt/asm.h>
36#include <iprt/err.h>
37#include <iprt/mem.h>
38#include <iprt/lockvalidator.h>
39
40#include "internal/magics.h"
41
42
43/*******************************************************************************
44* Structures and Typedefs *
45*******************************************************************************/
46/**
47 * Haiku multiple release event semaphore.
48 */
49typedef struct RTSEMEVENTMULTIINTERNAL
50{
51 /** Magic value (RTSEMEVENTMULTI_MAGIC). */
52 uint32_t volatile u32Magic;
53 /** Reference counter. */
54 uint32_t volatile cRefs;
55 /** The semaphore Id. */
56 sem_id SemId;
57} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
58
59
60RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
61{
62 return RTSemEventMultiCreateEx(phEventMultiSem, 0 /* fFlags */, NIL_RTLOCKVALCLASS, NULL);
63}
64
65
66RTDECL(int) RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
67 const char *pszNameFmt, ...)
68{
69 PRTSEMEVENTMULTIINTERNAL pThis;
70
71 AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
72 pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
73 if (!pThis)
74 return VERR_NO_MEMORY;
75
76 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
77 pThis->cRefs = 1;
78 pThis->SemId = create_sem(0, "IPRT Semaphore Event Multi");
79 if (pThis->SemId < B_OK)
80 {
81 set_sem_owner(pThis->SemId, B_SYSTEM_TEAM);
82 *phEventMultiSem = pThis;
83 return VINF_SUCCESS;
84 }
85
86 RTMemFree(pThis);
87 return VERR_TOO_MANY_SEMAPHORES; /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
88}
89
90
91/**
92 * Retain a reference to the semaphore.
93 *
94 * @param pThis The semaphore.
95 */
96DECLINLINE(void) rtR0SemEventMultiHkuRetain(PRTSEMEVENTMULTIINTERNAL pThis)
97{
98 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
99 Assert(cRefs && cRefs < 100000);
100}
101
102
103/**
104 * Release a reference, destroy the thing if necessary.
105 *
106 * @param pThis The semaphore.
107 */
108DECLINLINE(void) rtR0SemEventMultiHkuRelease(PRTSEMEVENTMULTIINTERNAL pThis)
109{
110 if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
111 {
112 Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC);
113 RTMemFree(pThis);
114 }
115}
116
117
118RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
119{
120 /*
121 * Validate input.
122 */
123 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
124 if (pThis == NIL_RTSEMEVENTMULTI)
125 return VINF_SUCCESS;
126 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
127 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
128 Assert(pThis->cRefs > 0);
129
130 /*
131 * Invalidate it and signal the object just in case.
132 */
133 ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC);
134 delete_sem(pThis->SemId);
135 pThis->SemId = -1;
136 rtR0SemEventMultiHkuRelease(pThis);
137 return VINF_SUCCESS;
138}
139
140
141RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
142{
143 /*
144 * Validate input.
145 */
146 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
147 if (!pThis)
148 return VERR_INVALID_PARAMETER;
149 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
150 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
151 rtR0SemEventMultiHkuRetain(pThis);
152
153 /*
154 * Signal the event object.
155 * We must use B_DO_NOT_RESCHEDULE since we are being used from an irq handler.
156 */
157 release_sem_etc(pThis->SemId, 1, B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
158 rtR0SemEventMultiHkuRelease(pThis);
159 return VINF_SUCCESS;
160}
161
162
163RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)
164{
165 /*
166 * Validate input.
167 */
168 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
169 if (!pThis)
170 return VERR_INVALID_PARAMETER;
171 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
172 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
173 rtR0SemEventMultiHkuRetain(pThis);
174
175 /*
176 * Reset it.
177 */
178 //FIXME: what should I do ???
179 // delete_sem + create_sem ??
180 rtR0SemEventMultiHkuRelease(pThis);
181 return VINF_SUCCESS;
182}
183
184
185/**
186 * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.
187 *
188 * @returns VBox status code.
189 * @param pThis The event semaphore.
190 * @param fFlags See RTSemEventMultiWaitEx.
191 * @param uTimeout See RTSemEventMultiWaitEx.
192 * @param pSrcPos The source code position of the wait.
193 */
194static int rtR0SemEventMultiHkuWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
195 PCRTLOCKVALSRCPOS pSrcPos)
196{
197 status_t status;
198 int rc;
199 int32 flags = 0;
200 bigtime_t timeout; /* in microseconds */
201
202 /*
203 * Validate the input.
204 */
205 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
206 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
207 AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
208
209 if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
210 timeout = B_INFINITE_TIMEOUT;
211 else
212 {
213 if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
214 timeout = uTimeout / 1000;
215 else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
216 timeout = uTimeout * 1000;
217 else
218 return VERR_INVALID_PARAMETER;
219
220 if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
221 flags |= B_RELATIVE_TIMEOUT;
222 else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
223 flags |= B_ABSOLUTE_TIMEOUT;
224 else
225 return VERR_INVALID_PARAMETER;
226 }
227
228 if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
229 flags |= B_CAN_INTERRUPT;
230 // likely not:
231 //else
232 // flags |= B_KILL_CAN_INTERRUPT;
233
234 rtR0SemEventMultiHkuRetain(pThis);
235
236 status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
237
238 switch (status)
239 {
240 case B_OK:
241 rc = VINF_SUCCESS;
242 break;
243 case B_BAD_SEM_ID:
244 rc = VERR_SEM_DESTROYED;
245 break;
246 case B_INTERRUPTED:
247 rc = VERR_INTERRUPTED;
248 break;
249 case B_WOULD_BLOCK:
250 /* fallthrough? */
251 case B_TIMED_OUT:
252 rc = VERR_TIMEOUT;
253 break;
254 default:
255 rc = RTErrConvertFromHaikuKernReturn(status);
256 break;
257 }
258
259 rtR0SemEventMultiHkuRelease(pThis);
260 return rc;
261}
262
263
264RTDECL(int) RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
265{
266#ifndef RTSEMEVENT_STRICT
267 return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, NULL);
268#else
269 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
270 return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
271#endif
272}
273RT_EXPORT_SYMBOL(RTSemEventMultiWaitEx);
274
275
276RTDECL(int) RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
277 RTHCUINTPTR uId, RT_SRC_POS_DECL)
278{
279 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
280 return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
281}
282RT_EXPORT_SYMBOL(RTSemEventMultiWaitExDebug);
283
284
285RTDECL(uint32_t) RTSemEventMultiGetResolution(void)
286{
287 /* At least that's what the API supports. */
288 return 1000;
289}
290RT_EXPORT_SYMBOL(RTSemEventMultiGetResolution);
291
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette