VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp@ 25638

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

iprt,pdmcritsect: Added RTSemEvent[Set|Add|Remove]Signaller so that we can validate who is signalling an event if we like and, more importantly, detect deadlocks involving event semaphores. More attempts at dealing with the races (and bugs) in the all-other-threads-blocking detection in tstRTLockValidator.cpp, adding RTThreadGetReallySleeping and RTThreadGetNativeState in the process.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1/* $Id: sems-os2.cpp 25638 2010-01-04 16:08:04Z vboxsync $ */
2/** @file
3 * IPRT - Semaphores, OS/2.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define INCL_DOSSEMAPHORES
36#define INCL_ERRORS
37#include <os2.h>
38#undef RT_MAX
39
40#include <iprt/semaphore.h>
41#include <iprt/assert.h>
42#include <iprt/err.h>
43
44
45/** Converts semaphore to OS/2 handle. */
46#define SEM2HND(Sem) ((LHANDLE)(uintptr_t)Sem)
47
48
49/* Undefine debug mappings. */
50#undef RTSemMutexRequest
51#undef RTSemMutexRequestNoResume
52
53
54RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem)
55{
56 /*
57 * Create the semaphore.
58 * (Auto reset, not signaled, private event object.)
59 */
60 HEV hev;
61 int rc = DosCreateEventSem(NULL, &hev, DCE_AUTORESET | DCE_POSTONE, 0);
62 if (!rc)
63 {
64 *pEventSem = (RTSEMEVENT)(void *)hev;
65 return VINF_SUCCESS;
66 }
67 return RTErrConvertFromOS2(rc);
68}
69
70
71RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem)
72{
73 if (EventSem == NIL_RTSEMEVENT) /* don't bitch */
74 return VERR_INVALID_HANDLE;
75
76 /*
77 * Close semaphore handle.
78 */
79 int rc = DosCloseEventSem(SEM2HND(EventSem));
80 if (!rc)
81 return VINF_SUCCESS;
82 AssertMsgFailed(("Destroy EventSem %p failed, rc=%d\n", EventSem, rc));
83 return RTErrConvertFromOS2(rc);
84}
85
86
87RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
88{
89 /*
90 * Wait for condition.
91 */
92 int rc = DosWaitEventSem(SEM2HND(EventSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
93 switch (rc)
94 {
95 case NO_ERROR: return VINF_SUCCESS;
96 case ERROR_SEM_TIMEOUT:
97 case ERROR_TIMEOUT: return VERR_TIMEOUT;
98 case ERROR_INTERRUPT: return VERR_INTERRUPTED;
99 default:
100 {
101 AssertMsgFailed(("Wait on EventSem %p failed, rc=%d\n", EventSem, rc));
102 return RTErrConvertFromOS2(rc);
103 }
104 }
105}
106
107
108RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem)
109{
110 /*
111 * Signal the object.
112 */
113 int rc = DosPostEventSem(SEM2HND(EventSem));
114 switch (rc)
115 {
116 case NO_ERROR:
117 case ERROR_ALREADY_POSTED:
118 case ERROR_TOO_MANY_POSTS:
119 return VINF_SUCCESS;
120 default:
121 return RTErrConvertFromOS2(rc);
122 }
123}
124
125
126RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
127{
128/** @todo implement RTSemEventSetSignaller and friends for OS/2 */
129}
130
131
132RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
133{
134
135}
136
137
138RTDECL(void) RTSemEventRemoverSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
139{
140
141}
142
143
144
145
146RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
147{
148 /*
149 * Create the semaphore.
150 * (Manual reset, not signaled, private event object.)
151 */
152 HEV hev;
153 int rc = DosCreateEventSem(NULL, &hev, 0, FALSE);
154 if (!rc)
155 {
156 *pEventMultiSem = (RTSEMEVENTMULTI)(void *)hev;
157 return VINF_SUCCESS;
158 }
159 return RTErrConvertFromOS2(rc);
160}
161
162
163RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
164{
165 /*
166 * Close semaphore handle.
167 */
168 int rc = DosCloseEventSem(SEM2HND(EventMultiSem));
169 if (!rc)
170 return VINF_SUCCESS;
171 AssertMsgFailed(("Destroy EventMultiSem %p failed, rc=%d\n", EventMultiSem, rc));
172 return RTErrConvertFromOS2(rc);
173}
174
175
176RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
177{
178 /*
179 * Signal the object.
180 */
181 int rc = DosPostEventSem(SEM2HND(EventMultiSem));
182 switch (rc)
183 {
184 case NO_ERROR:
185 case ERROR_ALREADY_POSTED:
186 case ERROR_TOO_MANY_POSTS:
187 return VINF_SUCCESS;
188 default:
189 return RTErrConvertFromOS2(rc);
190 }
191}
192
193
194RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
195{
196 /*
197 * Reset the object.
198 */
199 ULONG ulIgnore;
200 int rc = DosResetEventSem(SEM2HND(EventMultiSem), &ulIgnore);
201 switch (rc)
202 {
203 case NO_ERROR:
204 case ERROR_ALREADY_RESET:
205 return VINF_SUCCESS;
206 default:
207 return RTErrConvertFromOS2(rc);
208 }
209}
210
211
212RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
213{
214 /*
215 * Wait for condition.
216 */
217 int rc = DosWaitEventSem(SEM2HND(EventMultiSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
218 switch (rc)
219 {
220 case NO_ERROR: return VINF_SUCCESS;
221 case ERROR_SEM_TIMEOUT:
222 case ERROR_TIMEOUT: return VERR_TIMEOUT;
223 case ERROR_INTERRUPT: return VERR_INTERRUPTED;
224 default:
225 {
226 AssertMsgFailed(("Wait on EventMultiSem %p failed, rc=%d\n", EventMultiSem, rc));
227 return RTErrConvertFromOS2(rc);
228 }
229 }
230}
231
232
233
234
235RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
236{
237 /*
238 * Create the semaphore.
239 */
240 HMTX hmtx;
241 int rc = DosCreateMutexSem(NULL, &hmtx, 0, FALSE);
242 if (!rc)
243 {
244 *pMutexSem = (RTSEMMUTEX)(void *)hmtx;
245 return VINF_SUCCESS;
246 }
247
248 return RTErrConvertFromOS2(rc);
249}
250
251
252RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
253{
254 /*
255 * Close semaphore handle.
256 */
257 int rc = DosCloseMutexSem(SEM2HND(MutexSem));
258 if (!rc)
259 return VINF_SUCCESS;
260 AssertMsgFailed(("Destroy MutexSem %p failed, rc=%d\n", MutexSem, rc));
261 return RTErrConvertFromOS2(rc);
262}
263
264
265RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
266{
267 /*
268 * Lock mutex semaphore.
269 */
270 int rc = DosRequestMutexSem(SEM2HND(MutexSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
271 switch (rc)
272 {
273 case NO_ERROR: return VINF_SUCCESS;
274 case ERROR_SEM_TIMEOUT:
275 case ERROR_TIMEOUT: return VERR_TIMEOUT;
276 case ERROR_INTERRUPT: return VERR_INTERRUPTED;
277 case ERROR_SEM_OWNER_DIED: return VERR_SEM_OWNER_DIED;
278 default:
279 {
280 AssertMsgFailed(("Wait on MutexSem %p failed, rc=%d\n", MutexSem, rc));
281 return RTErrConvertFromOS2(rc);
282 }
283 }
284}
285
286RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
287{
288 /*
289 * Unlock mutex semaphore.
290 */
291 int rc = DosReleaseMutexSem(SEM2HND(MutexSem));
292 if (!rc)
293 return VINF_SUCCESS;
294 AssertMsgFailed(("Release MutexSem %p failed, rc=%d\n", MutexSem, rc));
295 return RTErrConvertFromOS2(rc);
296}
297
298
299RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex);
300{
301 /*
302 * Unlock mutex semaphore.
303 */
304 PID pid;
305 TID tid;
306 ULONG cRecursions;
307 int rc = DosQueryMutexSem(SEM2HND(MutexSem), &pid, &tid, &cRecursions);
308 if (!rc)
309 return cRecursions != 0;
310 AssertMsgFailed(("DosQueryMutexSem %p failed, rc=%d\n", MutexSem, rc));
311 return rc == ERROR_SEM_OWNER_DIED;
312}
313
314
315
Note: See TracBrowser for help on using the repository browser.

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