VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/SUPLibSem.cpp@ 94503

Last change on this file since 94503 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/* $Id: SUPLibSem.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VirtualBox Support Library - Semaphores, ring-3 implementation.
4 */
5
6/*
7 * Copyright (C) 2009-2022 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/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP LOG_GROUP_SUP
32#include <VBox/sup.h>
33
34#include <iprt/errcore.h>
35#include <VBox/param.h>
36#include <iprt/assert.h>
37#include <iprt/semaphore.h>
38#include <iprt/time.h>
39
40#include "SUPLibInternal.h"
41#include "SUPDrvIOC.h"
42
43
44/**
45 * Worker that makes a SUP_IOCTL_SEM_OP2 request.
46 *
47 * @returns VBox status code.
48 * @param pSession The session handle.
49 * @param uType The semaphore type.
50 * @param hSem The semaphore handle.
51 * @param uOp The operation.
52 * @param u64Arg The argument if applicable, otherwise 0.
53 */
54DECLINLINE(int) supSemOp2(PSUPDRVSESSION pSession, uint32_t uType, uintptr_t hSem, uint32_t uOp, uint64_t u64Arg)
55{
56 NOREF(pSession);
57 SUPSEMOP2 Req;
58 Req.Hdr.u32Cookie = g_u32Cookie;
59 Req.Hdr.u32SessionCookie = g_u32SessionCookie;
60 Req.Hdr.cbIn = SUP_IOCTL_SEM_OP2_SIZE_IN;
61 Req.Hdr.cbOut = SUP_IOCTL_SEM_OP2_SIZE_OUT;
62 Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
63 Req.Hdr.rc = VERR_INTERNAL_ERROR;
64 Req.u.In.uType = uType;
65 Req.u.In.hSem = (uint32_t)hSem;
66 AssertReturn(Req.u.In.hSem == hSem, VERR_INVALID_HANDLE);
67 Req.u.In.uOp = uOp;
68 Req.u.In.uReserved = 0;
69 Req.u.In.uArg.u64 = u64Arg;
70 int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_OP2, &Req, sizeof(Req));
71 if (RT_SUCCESS(rc))
72 rc = Req.Hdr.rc;
73
74 return rc;
75}
76
77
78/**
79 * Worker that makes a SUP_IOCTL_SEM_OP3 request.
80 *
81 * @returns VBox status code.
82 * @param pSession The session handle.
83 * @param uType The semaphore type.
84 * @param hSem The semaphore handle.
85 * @param uOp The operation.
86 * @param pReq The request structure. The caller should pick
87 * the output data from it himself.
88 */
89DECLINLINE(int) supSemOp3(PSUPDRVSESSION pSession, uint32_t uType, uintptr_t hSem, uint32_t uOp, PSUPSEMOP3 pReq)
90{
91 NOREF(pSession);
92 pReq->Hdr.u32Cookie = g_u32Cookie;
93 pReq->Hdr.u32SessionCookie = g_u32SessionCookie;
94 pReq->Hdr.cbIn = SUP_IOCTL_SEM_OP3_SIZE_IN;
95 pReq->Hdr.cbOut = SUP_IOCTL_SEM_OP3_SIZE_OUT;
96 pReq->Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
97 pReq->Hdr.rc = VERR_INTERNAL_ERROR;
98 pReq->u.In.uType = uType;
99 pReq->u.In.hSem = (uint32_t)hSem;
100 AssertReturn(pReq->u.In.hSem == hSem, VERR_INVALID_HANDLE);
101 pReq->u.In.uOp = uOp;
102 pReq->u.In.u32Reserved = 0;
103 pReq->u.In.u64Reserved = 0;
104 int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_OP3, pReq, sizeof(*pReq));
105 if (RT_SUCCESS(rc))
106 rc = pReq->Hdr.rc;
107
108 return rc;
109}
110
111
112SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent)
113{
114 AssertPtrReturn(phEvent, VERR_INVALID_POINTER);
115
116 int rc;
117 if (!g_supLibData.fDriverless)
118 {
119 SUPSEMOP3 Req;
120 rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)NIL_SUPSEMEVENT, SUPSEMOP3_CREATE, &Req);
121 if (RT_SUCCESS(rc))
122 *phEvent = (SUPSEMEVENT)(uintptr_t)Req.u.Out.hSem;
123 }
124 else
125 {
126 RTSEMEVENT hEvent;
127 rc = RTSemEventCreate(&hEvent);
128 if (RT_SUCCESS(rc))
129 *phEvent = (SUPSEMEVENT)hEvent;
130 }
131 return rc;
132}
133
134
135SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
136{
137 if (hEvent == NIL_SUPSEMEVENT)
138 return VINF_SUCCESS;
139 int rc;
140 if (!g_supLibData.fDriverless)
141 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_CLOSE, 0);
142 else
143 rc = RTSemEventDestroy((RTSEMEVENT)hEvent);
144 return rc;
145}
146
147
148SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
149{
150 int rc;
151 if (!g_supLibData.fDriverless)
152 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_SIGNAL, 0);
153 else
154 rc = RTSemEventSignal((RTSEMEVENT)hEvent);
155 return rc;
156}
157
158
159SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
160{
161 int rc;
162 if (!g_supLibData.fDriverless)
163 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_WAIT_MS_REL, cMillies);
164 else
165 rc = RTSemEventWaitNoResume((RTSEMEVENT)hEvent, cMillies);
166 return rc;
167}
168
169
170SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
171{
172 int rc;
173 if (!g_supLibData.fDriverless)
174 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_WAIT_NS_ABS, uNsTimeout);
175 else
176 {
177#if 0
178 rc = RTSemEventWaitEx((RTSEMEVENT)hEvent,
179 RTSEMWAIT_FLAGS_ABSOLUTE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_NORESUME, uNsTimeout);
180#else
181 uint64_t nsNow = RTTimeNanoTS();
182 if (nsNow < uNsTimeout)
183 rc = RTSemEventWaitNoResume((RTSEMEVENT)hEvent, (uNsTimeout - nsNow + RT_NS_1MS - 1) / RT_NS_1MS);
184 else
185 rc = VERR_TIMEOUT;
186#endif
187 }
188 return rc;
189}
190
191
192SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
193{
194 int rc;
195 if (!g_supLibData.fDriverless)
196 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_WAIT_NS_REL, cNsTimeout);
197 else
198 {
199#if 0
200 rc = RTSemEventWaitEx((RTSEMEVENT)hEvent,
201 RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_NORESUME, cNsTimeout);
202#else
203 rc = RTSemEventWaitNoResume((RTSEMEVENT)hEvent, (cNsTimeout + RT_NS_1MS - 1) / RT_NS_1MS);
204#endif
205 }
206 return rc;
207}
208
209
210SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession)
211{
212 if (!g_supLibData.fDriverless)
213 {
214 SUPSEMOP3 Req;
215 int rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)NIL_SUPSEMEVENT, SUPSEMOP3_GET_RESOLUTION, &Req);
216 if (RT_SUCCESS(rc))
217 return Req.u.Out.cNsResolution;
218 return 1000 / 100;
219 }
220#if 0
221 return RTSemEventGetResolution();
222#else
223 return RT_NS_1MS;
224#endif
225}
226
227
228
229
230
231SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti)
232{
233 AssertPtrReturn(phEventMulti, VERR_INVALID_POINTER);
234
235 int rc;
236 if (!g_supLibData.fDriverless)
237 {
238 SUPSEMOP3 Req;
239 rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)NIL_SUPSEMEVENTMULTI, SUPSEMOP3_CREATE, &Req);
240 if (RT_SUCCESS(rc))
241 *phEventMulti = (SUPSEMEVENTMULTI)(uintptr_t)Req.u.Out.hSem;
242 }
243 else
244 {
245 RTSEMEVENTMULTI hEventMulti;
246 rc = RTSemEventMultiCreate(&hEventMulti);
247 if (RT_SUCCESS(rc))
248 *phEventMulti = (SUPSEMEVENTMULTI)hEventMulti;
249 }
250 return rc;
251}
252
253
254SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
255{
256 if (hEventMulti == NIL_SUPSEMEVENTMULTI)
257 return VINF_SUCCESS;
258 int rc;
259 if (!g_supLibData.fDriverless)
260 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_CLOSE, 0);
261 else
262 rc = RTSemEventMultiDestroy((RTSEMEVENTMULTI)hEventMulti);
263 return rc;
264}
265
266
267SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
268{
269 int rc;
270 if (!g_supLibData.fDriverless)
271 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_SIGNAL, 0);
272 else
273 rc = RTSemEventMultiSignal((RTSEMEVENTMULTI)hEventMulti);
274 return rc;
275}
276
277
278SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
279{
280 int rc;
281 if (!g_supLibData.fDriverless)
282 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_RESET, 0);
283 else
284 rc = RTSemEventMultiReset((RTSEMEVENTMULTI)hEventMulti);
285 return rc;
286}
287
288
289SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
290{
291 int rc;
292 if (!g_supLibData.fDriverless)
293 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_WAIT_MS_REL, cMillies);
294 else
295 rc = RTSemEventMultiWaitNoResume((RTSEMEVENTMULTI)hEventMulti, cMillies);
296 return rc;
297}
298
299
300SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout)
301{
302 int rc;
303 if (!g_supLibData.fDriverless)
304 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_WAIT_NS_ABS, uNsTimeout);
305 else
306 {
307#if 0
308 rc = RTSemEventMultiWaitEx((RTSEMEVENTMULTI)hEventMulti,
309 RTSEMWAIT_FLAGS_ABSOLUTE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_NORESUME, uNsTimeout);
310#else
311 uint64_t nsNow = RTTimeNanoTS();
312 if (nsNow < uNsTimeout)
313 rc = RTSemEventMultiWaitNoResume((RTSEMEVENTMULTI)hEventMulti, (uNsTimeout - nsNow + RT_NS_1MS - 1) / RT_NS_1MS);
314 else
315 rc = VERR_TIMEOUT;
316#endif
317 }
318 return rc;
319}
320
321
322SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout)
323{
324 int rc;
325 if (!g_supLibData.fDriverless)
326 rc = supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_WAIT_NS_REL, cNsTimeout);
327 else
328 {
329#if 0
330 rc = RTSemEventMultiWaitEx((RTSEMEVENTMULTI)hEventMulti,
331 RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_NORESUME, cNsTimeout);
332#else
333 rc = RTSemEventMultiWaitNoResume((RTSEMEVENTMULTI)hEventMulti, (cNsTimeout + RT_NS_1MS - 1) / RT_NS_1MS);
334#endif
335 }
336 return rc;
337}
338
339
340SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession)
341{
342 if (!g_supLibData.fDriverless)
343 {
344 SUPSEMOP3 Req;
345 int rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)NIL_SUPSEMEVENTMULTI, SUPSEMOP3_GET_RESOLUTION, &Req);
346 if (RT_SUCCESS(rc))
347 return Req.u.Out.cNsResolution;
348 return 1000 / 100;
349 }
350#if 0
351 return RTSemEventMultiGetResolution();
352#else
353 return RT_NS_1MS;
354#endif
355}
356
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