Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1901 | serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * Version: 6.5.1 |
||
4 | * |
||
5 | * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. |
||
6 | * |
||
7 | * 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: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice shall be included |
||
15 | * in all copies or substantial portions of the Software. |
||
16 | * |
||
17 | * 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 | #include |
||
27 | #include |
||
28 | #include "u_compiler.h" |
||
29 | #include "u_thread.h" |
||
30 | |||
31 | |||
32 | /* |
||
33 | * This file should still compile even when THREADS is not defined. |
||
34 | * This is to make things easier to deal with on the makefile scene.. |
||
35 | */ |
||
36 | #ifdef THREADS |
||
37 | #include |
||
38 | |||
39 | /* |
||
40 | * Error messages |
||
41 | */ |
||
42 | #define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data" |
||
43 | #define GET_TSD_ERROR "_glthread_: failed to get thread specific data" |
||
44 | #define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data" |
||
45 | |||
46 | |||
47 | /* |
||
48 | * Magic number to determine if a TSD object has been initialized. |
||
49 | * Kind of a hack but there doesn't appear to be a better cross-platform |
||
50 | * solution. |
||
51 | */ |
||
52 | #define INIT_MAGIC 0xff8adc98 |
||
53 | |||
54 | |||
55 | |||
56 | /* |
||
57 | * POSIX Threads -- The best way to go if your platform supports them. |
||
58 | * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly |
||
59 | * has them, and many of the free Unixes now have them. |
||
60 | * Be sure to use appropriate -mt or -D_REENTRANT type |
||
61 | * compile flags when building. |
||
62 | */ |
||
63 | #ifdef PTHREADS |
||
64 | |||
65 | unsigned long |
||
66 | u_thread_self(void) |
||
67 | { |
||
68 | return (unsigned long) pthread_self(); |
||
69 | } |
||
70 | |||
71 | |||
72 | void |
||
73 | u_tsd_init(struct u_tsd *tsd) |
||
74 | { |
||
75 | if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { |
||
76 | perror(INIT_TSD_ERROR); |
||
77 | exit(-1); |
||
78 | } |
||
79 | tsd->initMagic = INIT_MAGIC; |
||
80 | } |
||
81 | |||
82 | |||
83 | void * |
||
84 | u_tsd_get(struct u_tsd *tsd) |
||
85 | { |
||
86 | if (tsd->initMagic != (int) INIT_MAGIC) { |
||
87 | u_tsd_init(tsd); |
||
88 | } |
||
89 | return pthread_getspecific(tsd->key); |
||
90 | } |
||
91 | |||
92 | |||
93 | void |
||
94 | u_tsd_set(struct u_tsd *tsd, void *ptr) |
||
95 | { |
||
96 | if (tsd->initMagic != (int) INIT_MAGIC) { |
||
97 | u_tsd_init(tsd); |
||
98 | } |
||
99 | if (pthread_setspecific(tsd->key, ptr) != 0) { |
||
100 | perror(SET_TSD_ERROR); |
||
101 | exit(-1); |
||
102 | } |
||
103 | } |
||
104 | |||
105 | #endif /* PTHREADS */ |
||
106 | |||
107 | |||
108 | |||
109 | /* |
||
110 | * Win32 Threads. The only available option for Windows 95/NT. |
||
111 | * Be sure that you compile using the Multithreaded runtime, otherwise |
||
112 | * bad things will happen. |
||
113 | */ |
||
114 | #ifdef WIN32 |
||
115 | |||
116 | static void InsteadOf_exit(int nCode) |
||
117 | { |
||
118 | DWORD dwErr = GetLastError(); |
||
119 | } |
||
120 | |||
121 | unsigned long |
||
122 | u_thread_self(void) |
||
123 | { |
||
124 | return GetCurrentThreadId(); |
||
125 | } |
||
126 | |||
127 | |||
128 | void |
||
129 | u_tsd_init(struct u_tsd *tsd) |
||
130 | { |
||
131 | tsd->key = TlsAlloc(); |
||
132 | if (tsd->key == TLS_OUT_OF_INDEXES) { |
||
133 | perror(INIT_TSD_ERROR); |
||
134 | InsteadOf_exit(-1); |
||
135 | } |
||
136 | tsd->initMagic = INIT_MAGIC; |
||
137 | } |
||
138 | |||
139 | |||
140 | void |
||
141 | u_tsd_destroy(struct u_tsd *tsd) |
||
142 | { |
||
143 | if (tsd->initMagic != INIT_MAGIC) { |
||
144 | return; |
||
145 | } |
||
146 | TlsFree(tsd->key); |
||
147 | tsd->initMagic = 0x0; |
||
148 | } |
||
149 | |||
150 | |||
151 | void * |
||
152 | u_tsd_get(struct u_tsd *tsd) |
||
153 | { |
||
154 | if (tsd->initMagic != INIT_MAGIC) { |
||
155 | u_tsd_init(tsd); |
||
156 | } |
||
157 | return TlsGetValue(tsd->key); |
||
158 | } |
||
159 | |||
160 | |||
161 | void |
||
162 | u_tsd_set(struct u_tsd *tsd, void *ptr) |
||
163 | { |
||
164 | /* the following code assumes that the struct u_tsd has been initialized |
||
165 | to zero at creation */ |
||
166 | if (tsd->initMagic != INIT_MAGIC) { |
||
167 | u_tsd_init(tsd); |
||
168 | } |
||
169 | if (TlsSetValue(tsd->key, ptr) == 0) { |
||
170 | perror(SET_TSD_ERROR); |
||
171 | InsteadOf_exit(-1); |
||
172 | } |
||
173 | } |
||
174 | |||
175 | #endif /* WIN32 */ |
||
176 | |||
177 | /* |
||
178 | * BeOS threads |
||
179 | */ |
||
180 | #ifdef BEOS_THREADS |
||
181 | |||
182 | unsigned long |
||
183 | u_thread_self(void) |
||
184 | { |
||
185 | return (unsigned long) find_thread(NULL); |
||
186 | } |
||
187 | |||
188 | void |
||
189 | u_tsd_init(struct u_tsd *tsd) |
||
190 | { |
||
191 | tsd->key = tls_allocate(); |
||
192 | tsd->initMagic = INIT_MAGIC; |
||
193 | } |
||
194 | |||
195 | void * |
||
196 | u_tsd_get(struct u_tsd *tsd) |
||
197 | { |
||
198 | if (tsd->initMagic != (int) INIT_MAGIC) { |
||
199 | u_tsd_init(tsd); |
||
200 | } |
||
201 | return tls_get(tsd->key); |
||
202 | } |
||
203 | |||
204 | void |
||
205 | u_tsd_set(struct u_tsd *tsd, void *ptr) |
||
206 | { |
||
207 | if (tsd->initMagic != (int) INIT_MAGIC) { |
||
208 | u_tsd_init(tsd); |
||
209 | } |
||
210 | tls_set(tsd->key, ptr); |
||
211 | } |
||
212 | |||
213 | #endif /* BEOS_THREADS */ |
||
214 | |||
215 | |||
216 | |||
217 | #else /* THREADS */ |
||
218 | |||
219 | |||
220 | /* |
||
221 | * no-op functions |
||
222 | */ |
||
223 | |||
224 | unsigned long |
||
225 | _glthread_GetID(void) |
||
226 | { |
||
227 | return 0; |
||
228 | } |
||
229 | |||
230 | |||
231 | void |
||
232 | u_tsd_init(struct u_tsd *tsd) |
||
233 | { |
||
234 | (void) tsd; |
||
235 | } |
||
236 | |||
237 | |||
238 | void * |
||
239 | u_tsd_get(struct u_tsd *tsd) |
||
240 | { |
||
241 | (void) tsd; |
||
242 | return NULL; |
||
243 | } |
||
244 | |||
245 | |||
246 | void |
||
247 | u_tsd_set(struct u_tsd *tsd, void *ptr) |
||
248 | { |
||
249 | (void) tsd; |
||
250 | (void) ptr; |
||
251 | } |
||
252 | |||
253 | |||
254 | #endif /* THREADS */ |