blob: 5fa8313975c223606400b130e52b4686b57be3b6 [file] [log] [blame]
Brian Paulc11371a1999-12-16 17:31:06 +00001
2/*
3 * Mesa 3-D graphics library
Brian Paul3c634522002-10-24 23:57:19 +00004 * Version: 4.1
Gareth Hughes22144ab2001-03-12 00:48:37 +00005 *
Brian Paul3c634522002-10-24 23:57:19 +00006 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
Gareth Hughes22144ab2001-03-12 00:48:37 +00007 *
Brian Paulc11371a1999-12-16 17:31:06 +00008 * 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:
Gareth Hughes22144ab2001-03-12 00:48:37 +000014 *
Brian Paulc11371a1999-12-16 17:31:06 +000015 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
Gareth Hughes22144ab2001-03-12 00:48:37 +000017 *
Brian Paulc11371a1999-12-16 17:31:06 +000018 * 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/*
Brian Paul8d365ab2000-01-28 18:57:56 +000028 * 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.
Brian Paulc11371a1999-12-16 17:31:06 +000030 */
31
32
Brian Paulc11371a1999-12-16 17:31:06 +000033#include "glheader.h"
Gareth Hughes22144ab2001-03-12 00:48:37 +000034#include "glthread.h"
Brian Paulc11371a1999-12-16 17:31:06 +000035
36
Brian Paulc11371a1999-12-16 17:31:06 +000037/*
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>
Brian Paulc11371a1999-12-16 17:31:06 +000043
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/*
Brian Paula9601f12000-02-10 21:27:25 +000053 * 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.
Brian Paulc11371a1999-12-16 17:31:06 +000056 */
Brian Paula9601f12000-02-10 21:27:25 +000057#define INIT_MAGIC 0xff8adc98
Brian Paulc11371a1999-12-16 17:31:06 +000058
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
70unsigned long
71_glthread_GetID(void)
72{
73 return (unsigned long) pthread_self();
74}
75
76
77void
78_glthread_InitTSD(_glthread_TSD *tsd)
79{
Brian Paule2b10e71999-12-17 11:13:54 +000080 if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
Brian Paulc11371a1999-12-16 17:31:06 +000081 perror(INIT_TSD_ERROR);
82 exit(-1);
83 }
Brian Paula9601f12000-02-10 21:27:25 +000084 tsd->initMagic = INIT_MAGIC;
Brian Paulc11371a1999-12-16 17:31:06 +000085}
86
87
88void *
89_glthread_GetTSD(_glthread_TSD *tsd)
90{
Brian Paulb51b0a82001-03-07 05:06:11 +000091 if (tsd->initMagic != (int) INIT_MAGIC) {
Brian Paula9601f12000-02-10 21:27:25 +000092 _glthread_InitTSD(tsd);
93 }
Brian Paulc11371a1999-12-16 17:31:06 +000094 return pthread_getspecific(tsd->key);
95}
96
97
98void
Brian Paula9601f12000-02-10 21:27:25 +000099_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
Brian Paulc11371a1999-12-16 17:31:06 +0000100{
Brian Paulb51b0a82001-03-07 05:06:11 +0000101 if (tsd->initMagic != (int) INIT_MAGIC) {
Brian Paula9601f12000-02-10 21:27:25 +0000102 _glthread_InitTSD(tsd);
103 }
Brian Paulc11371a1999-12-16 17:31:06 +0000104 if (pthread_setspecific(tsd->key, ptr) != 0) {
105 perror(SET_TSD_ERROR);
106 exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000107 }
Brian Paulc11371a1999-12-16 17:31:06 +0000108}
109
110#endif /* PTHREADS */
111
112
113
114/*
Gareth Hughes22144ab2001-03-12 00:48:37 +0000115 * Solaris/Unix International Threads -- Use only if POSIX threads
Brian Paulc11371a1999-12-16 17:31:06 +0000116 * aren't available on your Unix platform. Solaris 2.[34] are examples
Gareth Hughes22144ab2001-03-12 00:48:37 +0000117 * of platforms where this is the case. Be sure to use -mt and/or
Brian Paulc11371a1999-12-16 17:31:06 +0000118 * -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
124unsigned long
125_glthread_GetID(void)
126{
127 abort(); /* XXX not implemented yet */
128 return (unsigned long) 0;
129}
130
131
132void
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 }
Brian Paula9601f12000-02-10 21:27:25 +0000140 tsd->initMagic = INIT_MAGIC;
Brian Paulc11371a1999-12-16 17:31:06 +0000141}
142
143
144void *
145_glthread_GetTSD(_glthread_TSD *tsd)
146{
147 void* ret;
Brian Paula9601f12000-02-10 21:27:25 +0000148 if (tsd->initMagic != INIT_MAGIC) {
149 _glthread_InitTSD(tsd);
150 }
Brian Paulc11371a1999-12-16 17:31:06 +0000151#ifdef USE_LOCK_FOR_KEY
152 mutex_lock(&tsd->keylock);
153 thr_getspecific(tsd->key, &ret);
Gareth Hughes22144ab2001-03-12 00:48:37 +0000154 mutex_unlock(&tsd->keylock);
Brian Paulc11371a1999-12-16 17:31:06 +0000155#else
156 if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
157 perror(GET_TSD_ERROR);
158 exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000159 }
Brian Paulc11371a1999-12-16 17:31:06 +0000160#endif
161 return ret;
162}
163
164
165void
Brian Paula9601f12000-02-10 21:27:25 +0000166_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
Brian Paulc11371a1999-12-16 17:31:06 +0000167{
Brian Paula9601f12000-02-10 21:27:25 +0000168 if (tsd->initMagic != INIT_MAGIC) {
169 _glthread_InitTSD(tsd);
Brian Paulc11371a1999-12-16 17:31:06 +0000170 }
171 if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
172 perror(SET_TSD_ERROR);
173 exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000174 }
Brian Paulc11371a1999-12-16 17:31:06 +0000175}
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.
Gareth Hughes22144ab2001-03-12 00:48:37 +0000186 */
Brian Paulfa937f62000-02-11 21:38:33 +0000187#ifdef WIN32_THREADS
Brian Paulc11371a1999-12-16 17:31:06 +0000188
189unsigned long
190_glthread_GetID(void)
191{
192 abort(); /* XXX not implemented yet */
193 return (unsigned long) 0;
194}
195
196
197void
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 }
Brian Paula9601f12000-02-10 21:27:25 +0000207 tsd->initMagic = INIT_MAGIC;
Brian Paulc11371a1999-12-16 17:31:06 +0000208}
209
210
211void *
212_glthread_GetTSD(_glthread_TSD *tsd)
213{
Brian Paula9601f12000-02-10 21:27:25 +0000214 if (tsd->initMagic != INIT_MAGIC) {
215 _glthread_InitTSD(tsd);
216 }
Brian Paulc11371a1999-12-16 17:31:06 +0000217 return TlsGetValue(tsd->key);
218}
219
220
221void
Brian Paula9601f12000-02-10 21:27:25 +0000222_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
Brian Paulc11371a1999-12-16 17:31:06 +0000223{
224 /* the following code assumes that the _glthread_TSD has been initialized
225 to zero at creation */
Brian Paula9601f12000-02-10 21:27:25 +0000226 if (tsd->initMagic != INIT_MAGIC) {
227 _glthread_InitTSD(tsd);
Brian Paulc11371a1999-12-16 17:31:06 +0000228 }
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);
Brian Paule2b10e71999-12-17 11:13:54 +0000234 }
Brian Paulc11371a1999-12-16 17:31:06 +0000235}
236
Brian Paulfa937f62000-02-11 21:38:33 +0000237#endif /* WIN32_THREADS */
Brian Paulc11371a1999-12-16 17:31:06 +0000238
Brian Paula9601f12000-02-10 21:27:25 +0000239
240
241/*
242 * XFree86 has its own thread wrapper, Xthreads.h
243 * We wrap it again for GL.
244 */
245#ifdef XTHREADS
246
247unsigned long
248_glthread_GetID(void)
249{
250 return (unsigned long) xthread_self();
251}
252
253
254void
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
265void *
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
277void
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
Brian Paula360ab22000-02-10 21:54:06 +0000289
Brian Paul1b37d6c2001-11-12 23:50:12 +0000290/*
291 * BeOS threads
292 */
293#ifdef BEOS_THREADS
294
295unsigned long
296_glthread_GetID(void)
297{
298 return (unsigned long) find_thread(NULL);
299}
300
301void
302_glthread_InitTSD(_glthread_TSD *tsd)
303{
304 tsd->key = tls_allocate();
305 tsd->initMagic = INIT_MAGIC;
306}
307
308void *
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
317void
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
Brian Paula360ab22000-02-10 21:54:06 +0000330#else /* THREADS */
331
332
333/*
334 * no-op functions
335 */
336
337unsigned long
338_glthread_GetID(void)
339{
340 return 0;
341}
342
343
344void
345_glthread_InitTSD(_glthread_TSD *tsd)
346{
347 (void) tsd;
348}
349
350
351void *
352_glthread_GetTSD(_glthread_TSD *tsd)
353{
354 (void) tsd;
355 return NULL;
356}
357
358
359void
360_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
361{
362 (void) tsd;
363 (void) ptr;
364}
365
366
Brian Paulc11371a1999-12-16 17:31:06 +0000367#endif /* THREADS */