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

Last change on this file since 3721 was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 7.6 KB
Line 
1/* $Id: glthread.c,v 1.1 2000-05-23 20:40:36 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
66
67/*
68 * POSIX Threads -- The best way to go if your platform supports them.
69 * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
70 * has them, and many of the free Unixes now have them.
71 * Be sure to use appropriate -mt or -D_REENTRANT type
72 * compile flags when building.
73 */
74#ifdef PTHREADS
75
76unsigned long
77_glthread_GetID(void)
78{
79 return (unsigned long) pthread_self();
80}
81
82
83void
84_glthread_InitTSD(_glthread_TSD *tsd)
85{
86 if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
87 perror(INIT_TSD_ERROR);
88 EXIT(-1);
89 }
90 tsd->initMagic = INIT_MAGIC;
91}
92
93
94void *
95_glthread_GetTSD(_glthread_TSD *tsd)
96{
97 if (tsd->initMagic != INIT_MAGIC) {
98 _glthread_InitTSD(tsd);
99 }
100 return pthread_getspecific(tsd->key);
101}
102
103
104void
105_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
106{
107 if (tsd->initMagic != INIT_MAGIC) {
108 _glthread_InitTSD(tsd);
109 }
110 if (pthread_setspecific(tsd->key, ptr) != 0) {
111 perror(SET_TSD_ERROR);
112 EXIT(-1);
113 }
114}
115
116#endif /* PTHREADS */
117
118
119
120/*
121 * Solaris/Unix International Threads -- Use only if POSIX threads
122 * aren't available on your Unix platform. Solaris 2.[34] are examples
123 * of platforms where this is the case. Be sure to use -mt and/or
124 * -D_REENTRANT when compiling.
125 */
126#ifdef SOLARIS_THREADS
127#define USE_LOCK_FOR_KEY /* undef this to try a version without
128 lock for the global key... */
129
130unsigned long
131_glthread_GetID(void)
132{
133 ABORT(); /* XXX not implemented yet */
134 return (unsigned long) 0;
135}
136
137
138void
139_glthread_InitTSD(_glthread_TSD *tsd)
140{
141 if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
142 (errno = thr_keycreate(&(tsd->key), free)) != 0) {
143 perror(INIT_TSD_ERROR);
144 EXIT(-1);
145 }
146 tsd->initMagic = INIT_MAGIC;
147}
148
149
150void *
151_glthread_GetTSD(_glthread_TSD *tsd)
152{
153 void* ret;
154 if (tsd->initMagic != INIT_MAGIC) {
155 _glthread_InitTSD(tsd);
156 }
157#ifdef USE_LOCK_FOR_KEY
158 mutex_lock(&tsd->keylock);
159 thr_getspecific(tsd->key, &ret);
160 mutex_unlock(&tsd->keylock);
161#else
162 if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
163 perror(GET_TSD_ERROR);
164 EXIT(-1);
165 }
166#endif
167 return ret;
168}
169
170
171void
172_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
173{
174 if (tsd->initMagic != INIT_MAGIC) {
175 _glthread_InitTSD(tsd);
176 }
177 if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
178 perror(SET_TSD_ERROR);
179 EXIT(-1);
180 }
181}
182
183#undef USE_LOCK_FOR_KEY
184#endif /* SOLARIS_THREADS */
185
186
187
188/*
189 * Win32 Threads. The only available option for Windows 95/NT.
190 * Be sure that you compile using the Multithreaded runtime, otherwise
191 * bad things will happen.
192 */
193#ifdef WIN32_THREADS
194
195unsigned long
196_glthread_GetID(void)
197{
198// ABORT(); /* XXX not implemented yet */
199 return (unsigned long) 0;
200}
201
202
203void
204_glthread_InitTSD(_glthread_TSD *tsd)
205{
206 tsd->key = TlsAlloc();
207 if (tsd->key == 0xffffffff) {
208 /* Can Windows handle stderr messages for non-console
209 applications? Does Windows have perror? */
210 /* perror(SET_INIT_ERROR);*/
211 EXIT(-1);
212 }
213 tsd->initMagic = INIT_MAGIC;
214}
215
216
217void *
218_glthread_GetTSD(_glthread_TSD *tsd)
219{
220 if (tsd->initMagic != INIT_MAGIC) {
221 _glthread_InitTSD(tsd);
222 }
223 return TlsGetValue(tsd->key);
224}
225
226
227void
228_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
229{
230 /* the following code assumes that the _glthread_TSD has been initialized
231 to zero at creation */
232 if (tsd->initMagic != INIT_MAGIC) {
233 _glthread_InitTSD(tsd);
234 }
235 if (TlsSetValue(tsd->key, ptr) == 0) {
236 /* Can Windows handle stderr messages for non-console
237 applications? Does Windows have perror? */
238 /* perror(SET_TSD_ERROR);*/
239 EXIT(-1);
240 }
241}
242
243#endif /* WIN32_THREADS */
244
245#ifdef OS2_THREADS
246
247unsigned long
248_glthread_GetID(void)
249{
250 return (unsigned long) _threadstore();
251}
252
253
254void
255_glthread_InitTSD(_glthread_TSD *tsd)
256{
257 tsd->key = (ULONG) (_threadstore());
258 tsd->initMagic = INIT_MAGIC;
259}
260
261
262void *
263_glthread_GetTSD(_glthread_TSD *tsd)
264{
265 if (tsd->initMagic != INIT_MAGIC) {
266 _glthread_InitTSD(tsd);
267 }
268 return _threadstore();
269}
270
271
272void
273_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
274{
275 /* the following code assumes that the _glthread_TSD has been initialized
276 to zero at creation */
277 if (tsd->initMagic != INIT_MAGIC) {
278 _glthread_InitTSD(tsd);
279 }
280
281 (*_threadstore())=(void *)ptr;
282}
283
284#endif /* OS2_THREADS */
285
286
287
288/*
289 * XFree86 has its own thread wrapper, Xthreads.h
290 * We wrap it again for GL.
291 */
292#ifdef XTHREADS
293
294unsigned long
295_glthread_GetID(void)
296{
297 return (unsigned long) xthread_self();
298}
299
300
301void
302_glthread_InitTSD(_glthread_TSD *tsd)
303{
304 if (xthread_key_create(&tsd->key, NULL) != 0) {
305 perror(INIT_TSD_ERROR);
306 EXIT(-1);
307 }
308 tsd->initMagic = INIT_MAGIC;
309}
310
311
312void *
313_glthread_GetTSD(_glthread_TSD *tsd)
314{
315 void *ptr;
316 if (tsd->initMagic != INIT_MAGIC) {
317 _glthread_InitTSD(tsd);
318 }
319 xthread_get_specific(tsd->key, &ptr);
320 return ptr;
321}
322
323
324void
325_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
326{
327 if (tsd->initMagic != INIT_MAGIC) {
328 _glthread_InitTSD(tsd);
329 }
330 xthread_set_specific(tsd->key, ptr);
331}
332
333#endif /* XTHREAD */
334
335
336
337#else /* THREADS */
338
339
340/*
341 * no-op functions
342 */
343
344unsigned long
345_glthread_GetID(void)
346{
347 return 0;
348}
349
350
351void
352_glthread_InitTSD(_glthread_TSD *tsd)
353{
354 (void) tsd;
355}
356
357
358void *
359_glthread_GetTSD(_glthread_TSD *tsd)
360{
361 (void) tsd;
362 return NULL;
363}
364
365
366void
367_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
368{
369 (void) tsd;
370 (void) ptr;
371}
372
373
374#endif /* THREADS */
Note: See TracBrowser for help on using the repository browser.