blob: 92f2e5bf560f371f3bcdc5748ff3730f56ec134e [file] [log] [blame]
Brian Paulc11371a1999-12-16 17:31:06 +00001/*
2 * Mesa 3-D graphics library
Brian Paul385f23e2006-06-16 14:50:05 +00003 * Version: 6.5.1
Gareth Hughes22144ab2001-03-12 00:48:37 +00004 *
Brian Paul385f23e2006-06-16 14:50:05 +00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
Gareth Hughes22144ab2001-03-12 00:48:37 +00006 *
Brian Paulc11371a1999-12-16 17:31:06 +00007 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
Gareth Hughes22144ab2001-03-12 00:48:37 +000013 *
Brian Paulc11371a1999-12-16 17:31:06 +000014 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
Gareth Hughes22144ab2001-03-12 00:48:37 +000016 *
Brian Paulc11371a1999-12-16 17:31:06 +000017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26/*
Brian Paul8d365ab2000-01-28 18:57:56 +000027 * XXX There's probably some work to do in order to make this file
28 * truly reusable outside of Mesa. First, the glheader.h include must go.
Brian Paulc11371a1999-12-16 17:31:06 +000029 */
30
31
George Sapountzis32a2a092008-04-18 17:34:24 +030032#ifdef HAVE_DIX_CONFIG_H
33#include <dix-config.h>
34#endif
35
Brian Paulc11371a1999-12-16 17:31:06 +000036#include "glheader.h"
Gareth Hughes22144ab2001-03-12 00:48:37 +000037#include "glthread.h"
Brian Paulc11371a1999-12-16 17:31:06 +000038
39
Brian Paulc11371a1999-12-16 17:31:06 +000040/*
41 * This file should still compile even when THREADS is not defined.
42 * This is to make things easier to deal with on the makefile scene..
43 */
44#ifdef THREADS
45#include <errno.h>
Brian Paulc11371a1999-12-16 17:31:06 +000046
47/*
48 * Error messages
49 */
50#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
51#define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
52#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
53
54
55/*
Brian Paula9601f12000-02-10 21:27:25 +000056 * Magic number to determine if a TSD object has been initialized.
57 * Kind of a hack but there doesn't appear to be a better cross-platform
58 * solution.
Brian Paulc11371a1999-12-16 17:31:06 +000059 */
Brian Paula9601f12000-02-10 21:27:25 +000060#define INIT_MAGIC 0xff8adc98
Brian Paulc11371a1999-12-16 17:31:06 +000061
62
63
64/*
65 * POSIX Threads -- The best way to go if your platform supports them.
66 * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
67 * has them, and many of the free Unixes now have them.
68 * Be sure to use appropriate -mt or -D_REENTRANT type
69 * compile flags when building.
70 */
71#ifdef PTHREADS
72
73unsigned long
74_glthread_GetID(void)
75{
76 return (unsigned long) pthread_self();
77}
78
79
80void
81_glthread_InitTSD(_glthread_TSD *tsd)
82{
Brian Paule2b10e71999-12-17 11:13:54 +000083 if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
Brian Paulc11371a1999-12-16 17:31:06 +000084 perror(INIT_TSD_ERROR);
85 exit(-1);
86 }
Brian Paula9601f12000-02-10 21:27:25 +000087 tsd->initMagic = INIT_MAGIC;
Brian Paulc11371a1999-12-16 17:31:06 +000088}
89
90
91void *
92_glthread_GetTSD(_glthread_TSD *tsd)
93{
Brian Paulb51b0a82001-03-07 05:06:11 +000094 if (tsd->initMagic != (int) INIT_MAGIC) {
Brian Paula9601f12000-02-10 21:27:25 +000095 _glthread_InitTSD(tsd);
96 }
Brian Paulc11371a1999-12-16 17:31:06 +000097 return pthread_getspecific(tsd->key);
98}
99
100
101void
Brian Paula9601f12000-02-10 21:27:25 +0000102_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
Brian Paulc11371a1999-12-16 17:31:06 +0000103{
Brian Paulb51b0a82001-03-07 05:06:11 +0000104 if (tsd->initMagic != (int) INIT_MAGIC) {
Brian Paula9601f12000-02-10 21:27:25 +0000105 _glthread_InitTSD(tsd);
106 }
Brian Paulc11371a1999-12-16 17:31:06 +0000107 if (pthread_setspecific(tsd->key, ptr) != 0) {
108 perror(SET_TSD_ERROR);
109 exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000110 }
Brian Paulc11371a1999-12-16 17:31:06 +0000111}
112
113#endif /* PTHREADS */
114
115
116
117/*
Gareth Hughes22144ab2001-03-12 00:48:37 +0000118 * Solaris/Unix International Threads -- Use only if POSIX threads
Brian Paulc11371a1999-12-16 17:31:06 +0000119 * aren't available on your Unix platform. Solaris 2.[34] are examples
Gareth Hughes22144ab2001-03-12 00:48:37 +0000120 * of platforms where this is the case. Be sure to use -mt and/or
Brian Paulc11371a1999-12-16 17:31:06 +0000121 * -D_REENTRANT when compiling.
122 */
123#ifdef SOLARIS_THREADS
124#define USE_LOCK_FOR_KEY /* undef this to try a version without
125 lock for the global key... */
126
127unsigned long
128_glthread_GetID(void)
129{
130 abort(); /* XXX not implemented yet */
131 return (unsigned long) 0;
132}
133
134
135void
136_glthread_InitTSD(_glthread_TSD *tsd)
137{
138 if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
139 (errno = thr_keycreate(&(tsd->key), free)) != 0) {
140 perror(INIT_TSD_ERROR);
141 exit(-1);
142 }
Brian Paula9601f12000-02-10 21:27:25 +0000143 tsd->initMagic = INIT_MAGIC;
Brian Paulc11371a1999-12-16 17:31:06 +0000144}
145
146
147void *
148_glthread_GetTSD(_glthread_TSD *tsd)
149{
150 void* ret;
Brian Paula9601f12000-02-10 21:27:25 +0000151 if (tsd->initMagic != INIT_MAGIC) {
152 _glthread_InitTSD(tsd);
153 }
Brian Paulc11371a1999-12-16 17:31:06 +0000154#ifdef USE_LOCK_FOR_KEY
155 mutex_lock(&tsd->keylock);
156 thr_getspecific(tsd->key, &ret);
Gareth Hughes22144ab2001-03-12 00:48:37 +0000157 mutex_unlock(&tsd->keylock);
Brian Paulc11371a1999-12-16 17:31:06 +0000158#else
159 if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
160 perror(GET_TSD_ERROR);
161 exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000162 }
Brian Paulc11371a1999-12-16 17:31:06 +0000163#endif
164 return ret;
165}
166
167
168void
Brian Paula9601f12000-02-10 21:27:25 +0000169_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
Brian Paulc11371a1999-12-16 17:31:06 +0000170{
Brian Paula9601f12000-02-10 21:27:25 +0000171 if (tsd->initMagic != INIT_MAGIC) {
172 _glthread_InitTSD(tsd);
Brian Paulc11371a1999-12-16 17:31:06 +0000173 }
174 if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
175 perror(SET_TSD_ERROR);
176 exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000177 }
Brian Paulc11371a1999-12-16 17:31:06 +0000178}
179
180#undef USE_LOCK_FOR_KEY
181#endif /* SOLARIS_THREADS */
182
183
184
185/*
186 * Win32 Threads. The only available option for Windows 95/NT.
187 * Be sure that you compile using the Multithreaded runtime, otherwise
188 * bad things will happen.
Gareth Hughes22144ab2001-03-12 00:48:37 +0000189 */
Brian Paulfa937f62000-02-11 21:38:33 +0000190#ifdef WIN32_THREADS
Brian Paulc11371a1999-12-16 17:31:06 +0000191
Brian Paul385f23e2006-06-16 14:50:05 +0000192void FreeTSD(_glthread_TSD *p)
193{
194 if (p->initMagic==INIT_MAGIC) {
195 TlsFree(p->key);
196 p->initMagic=0;
197 }
198}
199
200void InsteadOf_exit(int nCode)
201{
202 DWORD dwErr=GetLastError();
203}
204
Brian Paulc11371a1999-12-16 17:31:06 +0000205unsigned long
206_glthread_GetID(void)
207{
Brian Paul385f23e2006-06-16 14:50:05 +0000208 return GetCurrentThreadId();
Brian Paulc11371a1999-12-16 17:31:06 +0000209}
210
211
212void
213_glthread_InitTSD(_glthread_TSD *tsd)
214{
215 tsd->key = TlsAlloc();
Brian Paul385f23e2006-06-16 14:50:05 +0000216 if (tsd->key == TLS_OUT_OF_INDEXES) {
217 perror("Mesa:_glthread_InitTSD");
218 InsteadOf_exit(-1);
Brian Paulc11371a1999-12-16 17:31:06 +0000219 }
Brian Paula9601f12000-02-10 21:27:25 +0000220 tsd->initMagic = INIT_MAGIC;
Brian Paulc11371a1999-12-16 17:31:06 +0000221}
222
223
224void *
225_glthread_GetTSD(_glthread_TSD *tsd)
226{
Brian Paula9601f12000-02-10 21:27:25 +0000227 if (tsd->initMagic != INIT_MAGIC) {
228 _glthread_InitTSD(tsd);
229 }
Brian Paulc11371a1999-12-16 17:31:06 +0000230 return TlsGetValue(tsd->key);
231}
232
233
234void
Brian Paula9601f12000-02-10 21:27:25 +0000235_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
Brian Paulc11371a1999-12-16 17:31:06 +0000236{
237 /* the following code assumes that the _glthread_TSD has been initialized
238 to zero at creation */
Brian Paula9601f12000-02-10 21:27:25 +0000239 if (tsd->initMagic != INIT_MAGIC) {
240 _glthread_InitTSD(tsd);
Brian Paulc11371a1999-12-16 17:31:06 +0000241 }
242 if (TlsSetValue(tsd->key, ptr) == 0) {
Brian Paul385f23e2006-06-16 14:50:05 +0000243 perror("Mesa:_glthread_SetTSD");
244 InsteadOf_exit(-1);
Brian Paule2b10e71999-12-17 11:13:54 +0000245 }
Brian Paulc11371a1999-12-16 17:31:06 +0000246}
247
Brian Paulfa937f62000-02-11 21:38:33 +0000248#endif /* WIN32_THREADS */
Brian Paulc11371a1999-12-16 17:31:06 +0000249
Brian Paula9601f12000-02-10 21:27:25 +0000250
251
252/*
253 * XFree86 has its own thread wrapper, Xthreads.h
254 * We wrap it again for GL.
255 */
Ian Romanick711555d2005-08-03 23:05:25 +0000256#ifdef USE_XTHREADS
Brian Paula9601f12000-02-10 21:27:25 +0000257
258unsigned long
259_glthread_GetID(void)
260{
261 return (unsigned long) xthread_self();
262}
263
264
265void
266_glthread_InitTSD(_glthread_TSD *tsd)
267{
268 if (xthread_key_create(&tsd->key, NULL) != 0) {
269 perror(INIT_TSD_ERROR);
270 exit(-1);
271 }
272 tsd->initMagic = INIT_MAGIC;
273}
274
275
276void *
277_glthread_GetTSD(_glthread_TSD *tsd)
278{
279 void *ptr;
280 if (tsd->initMagic != INIT_MAGIC) {
281 _glthread_InitTSD(tsd);
282 }
283 xthread_get_specific(tsd->key, &ptr);
284 return ptr;
285}
286
287
288void
289_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
290{
291 if (tsd->initMagic != INIT_MAGIC) {
292 _glthread_InitTSD(tsd);
293 }
294 xthread_set_specific(tsd->key, ptr);
295}
296
297#endif /* XTHREAD */
298
299
Brian Paula360ab22000-02-10 21:54:06 +0000300
Brian Paul1b37d6c2001-11-12 23:50:12 +0000301/*
302 * BeOS threads
303 */
304#ifdef BEOS_THREADS
305
306unsigned long
307_glthread_GetID(void)
308{
309 return (unsigned long) find_thread(NULL);
310}
311
312void
313_glthread_InitTSD(_glthread_TSD *tsd)
314{
315 tsd->key = tls_allocate();
316 tsd->initMagic = INIT_MAGIC;
317}
318
319void *
320_glthread_GetTSD(_glthread_TSD *tsd)
321{
322 if (tsd->initMagic != (int) INIT_MAGIC) {
323 _glthread_InitTSD(tsd);
324 }
325 return tls_get(tsd->key);
326}
327
328void
329_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
330{
331 if (tsd->initMagic != (int) INIT_MAGIC) {
332 _glthread_InitTSD(tsd);
333 }
334 tls_set(tsd->key, ptr);
335}
336
337#endif /* BEOS_THREADS */
338
339
340
Brian Paula360ab22000-02-10 21:54:06 +0000341#else /* THREADS */
342
343
344/*
345 * no-op functions
346 */
347
348unsigned long
349_glthread_GetID(void)
350{
351 return 0;
352}
353
354
355void
356_glthread_InitTSD(_glthread_TSD *tsd)
357{
358 (void) tsd;
359}
360
361
362void *
363_glthread_GetTSD(_glthread_TSD *tsd)
364{
365 (void) tsd;
366 return NULL;
367}
368
369
370void
371_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
372{
373 (void) tsd;
374 (void) ptr;
375}
376
377
Brian Paulc11371a1999-12-16 17:31:06 +0000378#endif /* THREADS */