VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/SUPDrvSem.c@ 26512

Last change on this file since 26512 was 25465, checked in by vboxsync, 15 years ago

SUPDrv,++: Made SUPDrv.c platform agnostic and renamed SUPDrvAgnostic.c to SUPDrvSem.c. dprintf and dprintf2 are no more (Log/Log2), while OSDBGPRINT simply calls SUPR0Printf.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 KB
Line 
1/* $Revision: 25465 $ */
2/** @file
3 * VBoxDrv - The VirtualBox Support Driver - Common OS agnostic.
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#define LOG_GROUP LOG_GROUP_SUP_DRV
35#define SUPDRV_AGNOSTIC
36#include "SUPDrvInternal.h"
37
38/** @todo trim this down. */
39#include <iprt/param.h>
40#include <iprt/alloc.h>
41#include <iprt/cpuset.h>
42#include <iprt/handletable.h>
43#include <iprt/mp.h>
44#include <iprt/power.h>
45#include <iprt/process.h>
46#include <iprt/semaphore.h>
47#include <iprt/spinlock.h>
48#include <iprt/thread.h>
49#include <iprt/uuid.h>
50
51#include <VBox/param.h>
52#include <VBox/log.h>
53#include <VBox/err.h>
54
55
56/**
57 * Destructor for objects created by SUPSemEventCreate.
58 *
59 * @param pvObj The object handle.
60 * @param pvUser1 The IPRT event handle.
61 * @param pvUser2 NULL.
62 */
63static DECLCALLBACK(void) supR0SemEventDestructor(void *pvObj, void *pvUser1, void *pvUser2)
64{
65 Assert(pvUser2 == NULL);
66 NOREF(pvObj);
67 RTSemEventDestroy((RTSEMEVENT)pvUser1);
68}
69
70
71SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent)
72{
73 int rc;
74 RTSEMEVENT hEventReal;
75
76 /*
77 * Input validation.
78 */
79 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
80 AssertPtrReturn(phEvent, VERR_INVALID_POINTER);
81
82 /*
83 * Create the event semaphore object.
84 */
85 rc = RTSemEventCreate(&hEventReal);
86 if (RT_SUCCESS(rc))
87 {
88 void *pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_SEM_EVENT, supR0SemEventDestructor, hEventReal, NULL);
89 if (pvObj)
90 {
91 uint32_t h32;
92 rc = RTHandleTableAllocWithCtx(pSession->hHandleTable, pvObj, SUPDRV_HANDLE_CTX_EVENT, &h32);
93 if (RT_SUCCESS(rc))
94 {
95 *phEvent = (SUPSEMEVENT)(uintptr_t)h32;
96 return VINF_SUCCESS;
97 }
98 SUPR0ObjRelease(pvObj, pSession);
99 }
100 else
101 RTSemEventDestroy(hEventReal);
102 }
103 return rc;
104}
105
106
107SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
108{
109 uint32_t h32;
110 PSUPDRVOBJ pObj;
111
112 /*
113 * Input validation.
114 */
115 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
116 if (hEvent == NIL_SUPSEMEVENT)
117 return VINF_SUCCESS;
118 h32 = (uint32_t)(uintptr_t)hEvent;
119 if (h32 != (uintptr_t)hEvent)
120 return VERR_INVALID_HANDLE;
121
122 /*
123 * Do the job.
124 */
125 pObj = (PSUPDRVOBJ)RTHandleTableFreeWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT);
126 if (!pObj)
127 return VERR_INVALID_HANDLE;
128
129 Assert(pObj->cUsage >= 2);
130 SUPR0ObjRelease(pObj, pSession); /* The free call above. */
131 return SUPR0ObjRelease(pObj, pSession); /* The handle table reference. */
132}
133
134
135SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
136{
137 int rc;
138 uint32_t h32;
139 PSUPDRVOBJ pObj;
140
141 /*
142 * Input validation.
143 */
144 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
145 h32 = (uint32_t)(uintptr_t)hEvent;
146 if (h32 != (uintptr_t)hEvent)
147 return VERR_INVALID_HANDLE;
148 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT);
149 if (!pObj)
150 return VERR_INVALID_HANDLE;
151
152 /*
153 * Do the job.
154 */
155 rc = RTSemEventSignal((RTSEMEVENT)pObj->pvUser1);
156
157 SUPR0ObjRelease(pObj, pSession);
158 return rc;
159}
160
161
162SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
163{
164 int rc;
165 uint32_t h32;
166 PSUPDRVOBJ pObj;
167
168 /*
169 * Input validation.
170 */
171 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
172 h32 = (uint32_t)(uintptr_t)hEvent;
173 if (h32 != (uintptr_t)hEvent)
174 return VERR_INVALID_HANDLE;
175 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT);
176 if (!pObj)
177 return VERR_INVALID_HANDLE;
178
179 /*
180 * Do the job.
181 */
182 rc = RTSemEventWait((RTSEMEVENT)pObj->pvUser1, cMillies);
183
184 SUPR0ObjRelease(pObj, pSession);
185 return rc;
186}
187
188
189SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
190{
191 int rc;
192 uint32_t h32;
193 PSUPDRVOBJ pObj;
194
195 /*
196 * Input validation.
197 */
198 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
199 h32 = (uint32_t)(uintptr_t)hEvent;
200 if (h32 != (uintptr_t)hEvent)
201 return VERR_INVALID_HANDLE;
202 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT);
203 if (!pObj)
204 return VERR_INVALID_HANDLE;
205
206 /*
207 * Do the job.
208 */
209 rc = RTSemEventWaitNoResume((RTSEMEVENT)pObj->pvUser1, cMillies);
210
211 SUPR0ObjRelease(pObj, pSession);
212 return rc;
213}
214
215
216/**
217 * Destructor for objects created by SUPSemEventMultiCreate.
218 *
219 * @param pvObj The object handle.
220 * @param pvUser1 The IPRT event handle.
221 * @param pvUser2 NULL.
222 */
223static DECLCALLBACK(void) supR0SemEventMultiDestructor(void *pvObj, void *pvUser1, void *pvUser2)
224{
225 Assert(pvUser2 == NULL);
226 NOREF(pvObj);
227 RTSemEventMultiDestroy((RTSEMEVENTMULTI)pvUser1);
228}
229
230
231SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti)
232{
233 int rc;
234 RTSEMEVENTMULTI hEventMultReal;
235
236 /*
237 * Input validation.
238 */
239 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
240 AssertPtrReturn(phEventMulti, VERR_INVALID_POINTER);
241
242 /*
243 * Create the event semaphore object.
244 */
245 rc = RTSemEventMultiCreate(&hEventMultReal);
246 if (RT_SUCCESS(rc))
247 {
248 void *pvObj = SUPR0ObjRegister(pSession, SUPDRVOBJTYPE_SEM_EVENT_MULTI, supR0SemEventMultiDestructor, hEventMultReal, NULL);
249 if (pvObj)
250 {
251 uint32_t h32;
252 rc = RTHandleTableAllocWithCtx(pSession->hHandleTable, pvObj, SUPDRV_HANDLE_CTX_EVENT_MULTI, &h32);
253 if (RT_SUCCESS(rc))
254 {
255 *phEventMulti = (SUPSEMEVENTMULTI)(uintptr_t)h32;
256 return VINF_SUCCESS;
257 }
258 SUPR0ObjRelease(pvObj, pSession);
259 }
260 else
261 RTSemEventMultiDestroy(hEventMultReal);
262 }
263 return rc;
264}
265
266
267SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
268{
269 uint32_t h32;
270 PSUPDRVOBJ pObj;
271
272 /*
273 * Input validation.
274 */
275 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
276 if (hEventMulti == NIL_SUPSEMEVENTMULTI)
277 return VINF_SUCCESS;
278 h32 = (uint32_t)(uintptr_t)hEventMulti;
279 if (h32 != (uintptr_t)hEventMulti)
280 return VERR_INVALID_HANDLE;
281
282 /*
283 * Do the job.
284 */
285 pObj = (PSUPDRVOBJ)RTHandleTableFreeWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI);
286 if (!pObj)
287 return VERR_INVALID_HANDLE;
288
289 Assert(pObj->cUsage >= 2);
290 SUPR0ObjRelease(pObj, pSession); /* The free call above. */
291 return SUPR0ObjRelease(pObj, pSession); /* The handle table reference. */
292}
293
294
295SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
296{
297 int rc;
298 uint32_t h32;
299 PSUPDRVOBJ pObj;
300
301 /*
302 * Input validation.
303 */
304 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
305 h32 = (uint32_t)(uintptr_t)hEventMulti;
306 if (h32 != (uintptr_t)hEventMulti)
307 return VERR_INVALID_HANDLE;
308 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI);
309 if (!pObj)
310 return VERR_INVALID_HANDLE;
311
312 /*
313 * Do the job.
314 */
315 rc = RTSemEventMultiSignal((RTSEMEVENTMULTI)pObj->pvUser1);
316
317 SUPR0ObjRelease(pObj, pSession);
318 return rc;
319}
320
321
322SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
323{
324 int rc;
325 uint32_t h32;
326 PSUPDRVOBJ pObj;
327
328 /*
329 * Input validation.
330 */
331 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
332 h32 = (uint32_t)(uintptr_t)hEventMulti;
333 if (h32 != (uintptr_t)hEventMulti)
334 return VERR_INVALID_HANDLE;
335 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI);
336 if (!pObj)
337 return VERR_INVALID_HANDLE;
338
339 /*
340 * Do the job.
341 */
342 rc = RTSemEventMultiReset((RTSEMEVENTMULTI)pObj->pvUser1);
343
344 SUPR0ObjRelease(pObj, pSession);
345 return rc;
346}
347
348
349SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
350{
351 int rc;
352 uint32_t h32;
353 PSUPDRVOBJ pObj;
354
355 /*
356 * Input validation.
357 */
358 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
359 h32 = (uint32_t)(uintptr_t)hEventMulti;
360 if (h32 != (uintptr_t)hEventMulti)
361 return VERR_INVALID_HANDLE;
362 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI);
363 if (!pObj)
364 return VERR_INVALID_HANDLE;
365
366 /*
367 * Do the job.
368 */
369 rc = RTSemEventMultiWait((RTSEMEVENTMULTI)pObj->pvUser1, cMillies);
370
371 SUPR0ObjRelease(pObj, pSession);
372 return rc;
373}
374
375
376SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
377{
378 int rc;
379 uint32_t h32;
380 PSUPDRVOBJ pObj;
381
382 /*
383 * Input validation.
384 */
385 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
386 h32 = (uint32_t)(uintptr_t)hEventMulti;
387 if (h32 != (uintptr_t)hEventMulti)
388 return VERR_INVALID_HANDLE;
389 pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI);
390 if (!pObj)
391 return VERR_INVALID_HANDLE;
392
393 /*
394 * Do the job.
395 */
396 rc = RTSemEventMultiWaitNoResume((RTSEMEVENTMULTI)pObj->pvUser1, cMillies);
397
398 SUPR0ObjRelease(pObj, pSession);
399 return rc;
400}
401
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