VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/threads.c@ 24107

Last change on this file since 24107 was 18328, checked in by vboxsync, 16 years ago

crOpenGL: init mutexes as recursive, fix for #3758

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved.
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include <stdio.h>
8#include "cr_threads.h"
9#include "cr_error.h"
10
11/* perror() messages */
12#define INIT_TSD_ERROR "InitTSD: failed to allocate key"
13#define FREE_TSD_ERROR "FreeTSD: failed to destroy key"
14#define SET_TSD_ERROR "InitTSD: thread failed to set thread specific data"
15#define GET_TSD_ERROR "InitTSD: failed to get thread specific data"
16
17/* Magic number to determine if a CRtsd has been initialized */
18#define INIT_MAGIC 0xff8adc98
19
20
21/* Initialize a CRtsd */
22void crInitTSDF(CRtsd *tsd, void (*destructor)(void *))
23{
24#ifdef WINDOWS
25 tsd->key = TlsAlloc();
26 if (tsd->key == 0xffffffff) {
27 crError("crInitTSD failed!");
28 }
29 (void) destructor;
30#else
31 if (pthread_key_create(&tsd->key, destructor) != 0) {
32 perror(INIT_TSD_ERROR);
33 crError("crInitTSD failed!");
34 }
35#endif
36 tsd->initMagic = INIT_MAGIC;
37}
38
39
40void crInitTSD(CRtsd *tsd)
41{
42 crInitTSDF(tsd, NULL);
43}
44
45
46void crFreeTSD(CRtsd *tsd)
47{
48#ifdef WINDOWS
49 /* Windows returns true on success, 0 on failure */
50 if (TlsFree(tsd->key) == 0) {
51 crError("crFreeTSD failed!");
52 }
53#else
54 if (pthread_key_delete(tsd->key) != 0) {
55 perror(FREE_TSD_ERROR);
56 crError("crFreeTSD failed!");
57 }
58#endif
59 tsd->initMagic = 0x0;
60}
61
62
63/* Set thread-specific data */
64void crSetTSD(CRtsd *tsd, void *ptr)
65{
66 if (tsd->initMagic != (int) INIT_MAGIC) {
67 /* initialize this CRtsd */
68 crInitTSD(tsd);
69 }
70#ifdef WINDOWS
71 if (TlsSetValue(tsd->key, ptr) == 0) {
72 crError("crSetTSD failed!");
73 }
74#else
75 if (pthread_setspecific(tsd->key, ptr) != 0) {
76 crError("crSetTSD failed!");
77 }
78#endif
79}
80
81
82/* Get thread-specific data */
83void *crGetTSD(CRtsd *tsd)
84{
85#ifdef WINDOWS
86 void * value;
87 DWORD err;
88 LPVOID lpMsgBuf;
89#endif
90 if (tsd->initMagic != (int) INIT_MAGIC) {
91 crInitTSD(tsd);
92 }
93#ifdef WINDOWS
94 value = TlsGetValue(tsd->key);
95 if (!value) {
96 err = GetLastError();
97 if ( err != ERROR_SUCCESS ) {
98 FormatMessage(
99 FORMAT_MESSAGE_ALLOCATE_BUFFER |
100 FORMAT_MESSAGE_FROM_SYSTEM |
101 FORMAT_MESSAGE_IGNORE_INSERTS,
102 NULL,
103 err,
104 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
105 (LPTSTR) &lpMsgBuf,
106 0, NULL );
107 crError("crGetTSD failed with %d: %s", err, lpMsgBuf);
108 LocalFree(lpMsgBuf);
109 }
110 }
111 return value;
112#else
113 return pthread_getspecific(tsd->key);
114#endif
115}
116
117
118
119/* Return ID of calling thread */
120unsigned long crThreadID(void)
121{
122#ifdef WINDOWS
123 return (unsigned long) GetCurrentThreadId();
124#else
125 return (unsigned long) pthread_self();
126#endif
127}
128
129
130
131void crInitMutex(CRmutex *mutex)
132{
133#ifdef WINDOWS
134 InitializeCriticalSection(mutex);
135#else
136 pthread_mutexattr_t mta;
137 int rc;
138
139 rc = pthread_mutexattr_init(&mta);
140 CRASSERT(!rc);
141 rc = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
142 CRASSERT(!rc);
143 rc = pthread_mutex_init(mutex, &mta);
144 CRASSERT(!rc);
145 pthread_mutexattr_destroy(&mta);
146#endif
147}
148
149
150void crFreeMutex(CRmutex *mutex)
151{
152#ifdef WINDOWS
153 DeleteCriticalSection(mutex);
154#else
155 pthread_mutex_destroy(mutex);
156#endif
157}
158
159
160void crLockMutex(CRmutex *mutex)
161{
162#ifdef WINDOWS
163 EnterCriticalSection(mutex);
164#else
165 pthread_mutex_lock(mutex);
166#endif
167}
168
169
170void crUnlockMutex(CRmutex *mutex)
171{
172#ifdef WINDOWS
173 LeaveCriticalSection(mutex);
174#else
175 pthread_mutex_unlock(mutex);
176#endif
177}
178
179
180void crInitCondition(CRcondition *cond)
181{
182#ifdef WINDOWS
183 /* XXX fix me */
184 (void) cond;
185#else
186 int err = pthread_cond_init(cond, NULL);
187 if (err) {
188 crError("crInitCondition failed");
189 }
190#endif
191}
192
193
194void crFreeCondition(CRcondition *cond)
195{
196#ifdef WINDOWS
197 /* XXX fix me */
198 (void) cond;
199#else
200 int err = pthread_cond_destroy(cond);
201 if (err) {
202 crError("crFreeCondition error (threads waiting on the condition?)");
203 }
204#endif
205}
206
207/**
208 * We're basically just wrapping the pthread condition var interface.
209 * See the man page for pthread_cond_wait to learn about the mutex parameter.
210 */
211void crWaitCondition(CRcondition *cond, CRmutex *mutex)
212{
213#ifdef WINDOWS
214 /* XXX fix me */
215 (void) cond;
216 (void) mutex;
217#else
218 pthread_cond_wait(cond, mutex);
219#endif
220}
221
222
223void crSignalCondition(CRcondition *cond)
224{
225#ifdef WINDOWS
226 /* XXX fix me */
227 (void) cond;
228#else
229 pthread_cond_signal(cond);
230#endif
231}
232
233
234void crInitBarrier(CRbarrier *b, unsigned int count)
235{
236#ifdef WINDOWS
237 unsigned int i;
238 for (i = 0; i < count; i++)
239 b->hEvents[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
240#else
241 b->count = count;
242 b->waiting = 0;
243 pthread_cond_init( &(b->cond), NULL );
244 pthread_mutex_init( &(b->mutex), NULL );
245#endif
246}
247
248
249void crFreeBarrier(CRbarrier *b)
250{
251 /* XXX anything to do? */
252}
253
254
255void crWaitBarrier(CRbarrier *b)
256{
257#ifdef WINDOWS
258 DWORD dwEvent
259 = WaitForMultipleObjects( b->count, b->hEvents, FALSE, INFINITE );
260#else
261 pthread_mutex_lock( &(b->mutex) );
262 b->waiting++;
263 if (b->waiting < b->count) {
264 pthread_cond_wait( &(b->cond), &(b->mutex) );
265 }
266 else {
267 pthread_cond_broadcast( &(b->cond) );
268 b->waiting = 0;
269 }
270 pthread_mutex_unlock( &(b->mutex) );
271#endif
272}
273
274
275void crInitSemaphore(CRsemaphore *s, unsigned int count)
276{
277#ifdef WINDOWS
278 crWarning("CRsemaphore functions not implemented on Windows");
279#else
280 sem_init(s, 0, count);
281#endif
282}
283
284
285void crWaitSemaphore(CRsemaphore *s)
286{
287#ifdef WINDOWS
288 /* to do */
289#else
290 sem_wait(s);
291#endif
292}
293
294
295void crSignalSemaphore(CRsemaphore *s)
296{
297#ifdef WINDOWS
298 /* to do */
299#else
300 sem_post(s);
301#endif
302}
303
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