1 | /* $Id: mthreads.c,v 1.2 2000-03-03 07:57:50 sandervl Exp $ */
|
---|
2 |
|
---|
3 | /*
|
---|
4 | * Mesa 3-D graphics library
|
---|
5 | * Version: 3.1
|
---|
6 | *
|
---|
7 | * Copyright (C) 1999 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 |
|
---|
30 | /*
|
---|
31 | * mthreads.c -- platform dependent thread support for Mesa
|
---|
32 | *
|
---|
33 | * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu)
|
---|
34 | * and Christoph Poliwoda (poliwoda@volumegraphics.com)
|
---|
35 | *
|
---|
36 | * Revised by Keith Whitwell
|
---|
37 | */
|
---|
38 |
|
---|
39 |
|
---|
40 | #ifndef XFree86Server
|
---|
41 | #include <stdio.h> /* for printing errors etc. */
|
---|
42 | #include <stdlib.h> /* malloc/free and the boys. */
|
---|
43 | #include <errno.h> /* error determination for system calls */
|
---|
44 | /* NOTE: Some platforms will do bad things with errno */
|
---|
45 | /* if correct compile-time options are not used. */
|
---|
46 | /* See mthreads.h for specific examples. */
|
---|
47 | #else
|
---|
48 | #include "GL/xf86glx.h"
|
---|
49 | #endif
|
---|
50 |
|
---|
51 |
|
---|
52 | /*
|
---|
53 | * This file should still compile even when THREADS is not defined.
|
---|
54 | * This is to make things easier to deal with on the makefile scene..
|
---|
55 | */
|
---|
56 | #ifdef THREADS
|
---|
57 | #include "mthreads.h"
|
---|
58 |
|
---|
59 |
|
---|
60 | /*
|
---|
61 | * POSIX Threads -- The best way to go if your platform supports them.
|
---|
62 | * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
|
---|
63 | * has them, and many of the free Unixes now have them.
|
---|
64 | * Be sure to use appropriate -mt or -D_REENTRANT type
|
---|
65 | * compile flags when building.
|
---|
66 | */
|
---|
67 | #ifdef PTHREADS
|
---|
68 | void MesaInitTSD(MesaTSD * tsd) {
|
---|
69 | if (pthread_key_create(&tsd->key, free) != 0) {
|
---|
70 | perror(MESA_INIT_TSD_ERROR);
|
---|
71 | exit(-1);
|
---|
72 | }
|
---|
73 | }
|
---|
74 |
|
---|
75 | void * MesaGetTSD(MesaTSD * tsd) {
|
---|
76 | return pthread_getspecific(tsd->key);
|
---|
77 | }
|
---|
78 |
|
---|
79 | void MesaSetTSD(MesaTSD * tsd, void * ptr, void (*initfunc)(void)) {
|
---|
80 | pthread_once(&tsd->once, initfunc);
|
---|
81 | if (pthread_setspecific(tsd->key, ptr) != 0) {
|
---|
82 | perror(MESA_SET_TSD_ERROR);
|
---|
83 | exit(-1);
|
---|
84 | };
|
---|
85 | }
|
---|
86 |
|
---|
87 | #endif /* PTHREADS */
|
---|
88 |
|
---|
89 |
|
---|
90 |
|
---|
91 | /*
|
---|
92 | * Solaris/Unix International Threads -- Use only if POSIX threads
|
---|
93 | * aren't available on your Unix platform. Solaris 2.[34] are examples
|
---|
94 | * of platforms where this is the case. Be sure to use -mt and/or
|
---|
95 | * -D_REENTRANT when compiling.
|
---|
96 | */
|
---|
97 | #ifdef SOLARIS_THREADS
|
---|
98 | #define USE_LOCK_FOR_KEY /* undef this to try a version without
|
---|
99 | lock for the global key... */
|
---|
100 |
|
---|
101 | void MesaInitTSD(MesaTSD * tsd) {
|
---|
102 | if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
|
---|
103 | (errno = thr_keycreate(&(tsd->key), free)) != 0) {
|
---|
104 | perror(MESA_INIT_TSD_ERROR);
|
---|
105 | exit(-1);
|
---|
106 | }
|
---|
107 | }
|
---|
108 |
|
---|
109 | void * MesaGetTSD(MesaTSD * tsd) {
|
---|
110 | void* ret;
|
---|
111 | #ifdef USE_LOCK_FOR_KEY
|
---|
112 | mutex_lock(&tsd->keylock);
|
---|
113 | thr_getspecific(tsd->key, &ret);
|
---|
114 | mutex_unlock(&tsd->keylock);
|
---|
115 | #else
|
---|
116 | if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
|
---|
117 | perror(MESA_GET_TSD_ERROR);
|
---|
118 | exit(-1);
|
---|
119 | };
|
---|
120 | #endif
|
---|
121 | return ret;
|
---|
122 | }
|
---|
123 |
|
---|
124 | void MesaSetTSD(MesaTSD * tsd, void * ptr, void (*initfunc)(void)) {
|
---|
125 | /* the following code assumes that the MesaTSD has been initialized
|
---|
126 | to zero at creation */
|
---|
127 | fprintf(stderr, "initfuncCalled = %d\n", tsd->initfuncCalled);
|
---|
128 | if (tsd->initfuncCalled != INITFUNC_CALLED_MAGIC) {
|
---|
129 | initfunc();
|
---|
130 | tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
|
---|
131 | }
|
---|
132 | if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
|
---|
133 | perror(MESA_SET_TSD_ERROR);
|
---|
134 | exit(-1);
|
---|
135 | };
|
---|
136 | }
|
---|
137 |
|
---|
138 | #undef USE_LOCK_FOR_KEY
|
---|
139 | #endif /* SOLARIS_THREADS */
|
---|
140 |
|
---|
141 |
|
---|
142 |
|
---|
143 | /*
|
---|
144 | * Win32 Threads. The only available option for Windows 95/NT.
|
---|
145 | * Be sure that you compile using the Multithreaded runtime, otherwise
|
---|
146 | * bad things will happen.
|
---|
147 | */
|
---|
148 | #if defined(WIN32) || defined(__WIN32OS2__)
|
---|
149 |
|
---|
150 | void MesaInitTSD(MesaTSD * tsd) {
|
---|
151 | tsd->key = TlsAlloc();
|
---|
152 | if (tsd->key == 0xffffffff) {
|
---|
153 | /* Can Windows handle stderr messages for non-console
|
---|
154 | applications? Does Windows have perror? */
|
---|
155 | /* perror(MESA_SET_INIT_ERROR);*/
|
---|
156 | exit(-1);
|
---|
157 | }
|
---|
158 | }
|
---|
159 |
|
---|
160 | #ifdef __WIN32OS2__
|
---|
161 | void *MesaGetTSD(MesaTSD * tsd, void (*initfunc)(void))
|
---|
162 | {
|
---|
163 | if (tsd->initfuncCalled != INITFUNC_CALLED_MAGIC) {
|
---|
164 | initfunc();
|
---|
165 | tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
|
---|
166 | }
|
---|
167 | return TlsGetValue(tsd->key);
|
---|
168 | }
|
---|
169 | #else
|
---|
170 | void *MesaGetTSD(MesaTSD * tsd)
|
---|
171 | {
|
---|
172 | return TlsGetValue(tsd->key);
|
---|
173 | }
|
---|
174 | #endif
|
---|
175 |
|
---|
176 | void MesaSetTSD(MesaTSD * tsd, void * ptr, void (*initfunc)(void)) {
|
---|
177 | /* the following code assumes that the MesaTSD has been initialized
|
---|
178 | to zero at creation */
|
---|
179 | if (tsd->initfuncCalled != INITFUNC_CALLED_MAGIC) {
|
---|
180 | initfunc();
|
---|
181 | tsd->initfuncCalled = INITFUNC_CALLED_MAGIC;
|
---|
182 | }
|
---|
183 | if (TlsSetValue(tsd->key, ptr) == 0) {
|
---|
184 | /* Can Windows handle stderr messages for non-console
|
---|
185 | applications? Does Windows have perror? */
|
---|
186 | /* perror(MESA_SET_TSD_ERROR);*/
|
---|
187 | exit(-1);
|
---|
188 | };
|
---|
189 | }
|
---|
190 |
|
---|
191 | #endif /* WIN32 */
|
---|
192 |
|
---|
193 | #endif /* THREADS */
|
---|
194 |
|
---|
195 |
|
---|