test version of startmenu root with big icons
[reactos.git] / reactos / lib / mesa32 / src / glapi / glthread.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 4.1
5 *
6 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 /*
28 * XXX There's probably some work to do in order to make this file
29 * truly reusable outside of Mesa. First, the glheader.h include must go.
30 */
31
32
33 #include "glheader.h"
34 #include "glthread.h"
35
36
37 /*
38 * This file should still compile even when THREADS is not defined.
39 * This is to make things easier to deal with on the makefile scene..
40 */
41 #ifdef THREADS
42 #include <errno.h>
43
44 /*
45 * Error messages
46 */
47 #define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
48 #define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
49 #define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
50
51
52 /*
53 * Magic number to determine if a TSD object has been initialized.
54 * Kind of a hack but there doesn't appear to be a better cross-platform
55 * solution.
56 */
57 #define INIT_MAGIC 0xff8adc98
58
59
60
61 /*
62 * POSIX Threads -- The best way to go if your platform supports them.
63 * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
64 * has them, and many of the free Unixes now have them.
65 * Be sure to use appropriate -mt or -D_REENTRANT type
66 * compile flags when building.
67 */
68 #ifdef PTHREADS
69
70 unsigned long
71 _glthread_GetID(void)
72 {
73 return (unsigned long) pthread_self();
74 }
75
76
77 void
78 _glthread_InitTSD(_glthread_TSD *tsd)
79 {
80 if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
81 perror(INIT_TSD_ERROR);
82 exit(-1);
83 }
84 tsd->initMagic = INIT_MAGIC;
85 }
86
87
88 void *
89 _glthread_GetTSD(_glthread_TSD *tsd)
90 {
91 if (tsd->initMagic != (int) INIT_MAGIC) {
92 _glthread_InitTSD(tsd);
93 }
94 return pthread_getspecific(tsd->key);
95 }
96
97
98 void
99 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
100 {
101 if (tsd->initMagic != (int) INIT_MAGIC) {
102 _glthread_InitTSD(tsd);
103 }
104 if (pthread_setspecific(tsd->key, ptr) != 0) {
105 perror(SET_TSD_ERROR);
106 exit(-1);
107 }
108 }
109
110 #endif /* PTHREADS */
111
112
113
114 /*
115 * Solaris/Unix International Threads -- Use only if POSIX threads
116 * aren't available on your Unix platform. Solaris 2.[34] are examples
117 * of platforms where this is the case. Be sure to use -mt and/or
118 * -D_REENTRANT when compiling.
119 */
120 #ifdef SOLARIS_THREADS
121 #define USE_LOCK_FOR_KEY /* undef this to try a version without
122 lock for the global key... */
123
124 unsigned long
125 _glthread_GetID(void)
126 {
127 abort(); /* XXX not implemented yet */
128 return (unsigned long) 0;
129 }
130
131
132 void
133 _glthread_InitTSD(_glthread_TSD *tsd)
134 {
135 if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
136 (errno = thr_keycreate(&(tsd->key), free)) != 0) {
137 perror(INIT_TSD_ERROR);
138 exit(-1);
139 }
140 tsd->initMagic = INIT_MAGIC;
141 }
142
143
144 void *
145 _glthread_GetTSD(_glthread_TSD *tsd)
146 {
147 void* ret;
148 if (tsd->initMagic != INIT_MAGIC) {
149 _glthread_InitTSD(tsd);
150 }
151 #ifdef USE_LOCK_FOR_KEY
152 mutex_lock(&tsd->keylock);
153 thr_getspecific(tsd->key, &ret);
154 mutex_unlock(&tsd->keylock);
155 #else
156 if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
157 perror(GET_TSD_ERROR);
158 exit(-1);
159 }
160 #endif
161 return ret;
162 }
163
164
165 void
166 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
167 {
168 if (tsd->initMagic != INIT_MAGIC) {
169 _glthread_InitTSD(tsd);
170 }
171 if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
172 perror(SET_TSD_ERROR);
173 exit(-1);
174 }
175 }
176
177 #undef USE_LOCK_FOR_KEY
178 #endif /* SOLARIS_THREADS */
179
180
181
182 /*
183 * Win32 Threads. The only available option for Windows 95/NT.
184 * Be sure that you compile using the Multithreaded runtime, otherwise
185 * bad things will happen.
186 */
187 #ifdef WIN32_THREADS
188
189 unsigned long
190 _glthread_GetID(void)
191 {
192 abort(); /* XXX not implemented yet */
193 return (unsigned long) 0;
194 }
195
196
197 void
198 _glthread_InitTSD(_glthread_TSD *tsd)
199 {
200 tsd->key = TlsAlloc();
201 if (tsd->key == 0xffffffff) {
202 /* Can Windows handle stderr messages for non-console
203 applications? Does Windows have perror? */
204 /* perror(SET_INIT_ERROR);*/
205 exit(-1);
206 }
207 tsd->initMagic = INIT_MAGIC;
208 }
209
210
211 void *
212 _glthread_GetTSD(_glthread_TSD *tsd)
213 {
214 if (tsd->initMagic != INIT_MAGIC) {
215 _glthread_InitTSD(tsd);
216 }
217 return TlsGetValue(tsd->key);
218 }
219
220
221 void
222 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
223 {
224 /* the following code assumes that the _glthread_TSD has been initialized
225 to zero at creation */
226 if (tsd->initMagic != INIT_MAGIC) {
227 _glthread_InitTSD(tsd);
228 }
229 if (TlsSetValue(tsd->key, ptr) == 0) {
230 /* Can Windows handle stderr messages for non-console
231 applications? Does Windows have perror? */
232 /* perror(SET_TSD_ERROR);*/
233 exit(-1);
234 }
235 }
236
237 #endif /* WIN32_THREADS */
238
239
240
241 /*
242 * XFree86 has its own thread wrapper, Xthreads.h
243 * We wrap it again for GL.
244 */
245 #ifdef XTHREADS
246
247 unsigned long
248 _glthread_GetID(void)
249 {
250 return (unsigned long) xthread_self();
251 }
252
253
254 void
255 _glthread_InitTSD(_glthread_TSD *tsd)
256 {
257 if (xthread_key_create(&tsd->key, NULL) != 0) {
258 perror(INIT_TSD_ERROR);
259 exit(-1);
260 }
261 tsd->initMagic = INIT_MAGIC;
262 }
263
264
265 void *
266 _glthread_GetTSD(_glthread_TSD *tsd)
267 {
268 void *ptr;
269 if (tsd->initMagic != INIT_MAGIC) {
270 _glthread_InitTSD(tsd);
271 }
272 xthread_get_specific(tsd->key, &ptr);
273 return ptr;
274 }
275
276
277 void
278 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
279 {
280 if (tsd->initMagic != INIT_MAGIC) {
281 _glthread_InitTSD(tsd);
282 }
283 xthread_set_specific(tsd->key, ptr);
284 }
285
286 #endif /* XTHREAD */
287
288
289
290 /*
291 * BeOS threads
292 */
293 #ifdef BEOS_THREADS
294
295 unsigned long
296 _glthread_GetID(void)
297 {
298 return (unsigned long) find_thread(NULL);
299 }
300
301 void
302 _glthread_InitTSD(_glthread_TSD *tsd)
303 {
304 tsd->key = tls_allocate();
305 tsd->initMagic = INIT_MAGIC;
306 }
307
308 void *
309 _glthread_GetTSD(_glthread_TSD *tsd)
310 {
311 if (tsd->initMagic != (int) INIT_MAGIC) {
312 _glthread_InitTSD(tsd);
313 }
314 return tls_get(tsd->key);
315 }
316
317 void
318 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
319 {
320 if (tsd->initMagic != (int) INIT_MAGIC) {
321 _glthread_InitTSD(tsd);
322 }
323 tls_set(tsd->key, ptr);
324 }
325
326 #endif /* BEOS_THREADS */
327
328
329
330 #else /* THREADS */
331
332
333 /*
334 * no-op functions
335 */
336
337 unsigned long
338 _glthread_GetID(void)
339 {
340 return 0;
341 }
342
343
344 void
345 _glthread_InitTSD(_glthread_TSD *tsd)
346 {
347 (void) tsd;
348 }
349
350
351 void *
352 _glthread_GetTSD(_glthread_TSD *tsd)
353 {
354 (void) tsd;
355 return NULL;
356 }
357
358
359 void
360 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
361 {
362 (void) tsd;
363 (void) ptr;
364 }
365
366
367 #endif /* THREADS */