source: trunk/src/opengl/mesa/glthread.c@ 4859

Last change on this file since 4859 was 4311, checked in by jeroen, 25 years ago

* empty log message *

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