Add mouse and keyboard configuration file
[profile/ivi/xorg-x11-server.git] / glx / glthread.c
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 /*
27  * XXX There's probably some work to do in order to make this file
28  * truly reusable outside of Mesa.
29  */
30
31
32 #ifdef HAVE_DIX_CONFIG_H
33 #include <dix-config.h>
34 #include <X11/Xfuncproto.h>
35 #endif
36
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include "glthread.h"
40
41
42 /*
43  * This file should still compile even when THREADS is not defined.
44  * This is to make things easier to deal with on the makefile scene..
45  */
46 #ifdef THREADS
47 #include <errno.h>
48
49 /*
50  * Error messages
51  */
52 #define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
53 #define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
54 #define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
55
56
57 /*
58  * Magic number to determine if a TSD object has been initialized.
59  * Kind of a hack but there doesn't appear to be a better cross-platform
60  * solution.
61  */
62 #define INIT_MAGIC 0xff8adc98
63
64
65
66 /*
67  * POSIX Threads -- The best way to go if your platform supports them.
68  *                  Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
69  *                  has them, and many of the free Unixes now have them.
70  *                  Be sure to use appropriate -mt or -D_REENTRANT type
71  *                  compile flags when building.
72  */
73 #ifdef PTHREADS
74
75 _X_EXPORT unsigned long
76 _glthread_GetID(void)
77 {
78    return (unsigned long) pthread_self();
79 }
80
81
82 void
83 _glthread_InitTSD(_glthread_TSD *tsd)
84 {
85    if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
86       perror(INIT_TSD_ERROR);
87       exit(-1);
88    }
89    tsd->initMagic = INIT_MAGIC;
90 }
91
92
93 void *
94 _glthread_GetTSD(_glthread_TSD *tsd)
95 {
96    if (tsd->initMagic != (int) INIT_MAGIC) {
97       _glthread_InitTSD(tsd);
98    }
99    return pthread_getspecific(tsd->key);
100 }
101
102
103 void
104 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
105 {
106    if (tsd->initMagic != (int) INIT_MAGIC) {
107       _glthread_InitTSD(tsd);
108    }
109    if (pthread_setspecific(tsd->key, ptr) != 0) {
110       perror(SET_TSD_ERROR);
111       exit(-1);
112    }
113 }
114
115 #endif /* PTHREADS */
116
117
118
119 /*
120  * Solaris/Unix International Threads -- Use only if POSIX threads
121  *   aren't available on your Unix platform.  Solaris 2.[34] are examples
122  *   of platforms where this is the case.  Be sure to use -mt and/or
123  *   -D_REENTRANT when compiling.
124  */
125 #ifdef SOLARIS_THREADS
126 #define USE_LOCK_FOR_KEY        /* undef this to try a version without
127                                    lock for the global key... */
128
129 _X_EXPORT unsigned long
130 _glthread_GetID(void)
131 {
132    OsAbort();   /* XXX not implemented yet */
133    return (unsigned long) 0;
134 }
135
136
137 void
138 _glthread_InitTSD(_glthread_TSD *tsd)
139 {
140    if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 ||
141       (errno = thr_keycreate(&(tsd->key), free)) != 0) {
142       perror(INIT_TSD_ERROR);
143       exit(-1);
144    }
145    tsd->initMagic = INIT_MAGIC;
146 }
147
148
149 void *
150 _glthread_GetTSD(_glthread_TSD *tsd)
151 {
152    void* ret;
153    if (tsd->initMagic != INIT_MAGIC) {
154       _glthread_InitTSD(tsd);
155    }
156 #ifdef USE_LOCK_FOR_KEY
157    mutex_lock(&tsd->keylock);
158    thr_getspecific(tsd->key, &ret);
159    mutex_unlock(&tsd->keylock);
160 #else
161    if ((errno = thr_getspecific(tsd->key, &ret)) != 0) {
162       perror(GET_TSD_ERROR);
163       exit(-1);
164    }
165 #endif
166    return ret;
167 }
168
169
170 void
171 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
172 {
173    if (tsd->initMagic != INIT_MAGIC) {
174       _glthread_InitTSD(tsd);
175    }
176    if ((errno = thr_setspecific(tsd->key, ptr)) != 0) {
177       perror(SET_TSD_ERROR);
178       exit(-1);
179    }
180 }
181
182 #undef USE_LOCK_FOR_KEY
183 #endif /* SOLARIS_THREADS */
184
185
186
187 /*
188  * Win32 Threads.  The only available option for Windows 95/NT.
189  * Be sure that you compile using the Multithreaded runtime, otherwise
190  * bad things will happen.
191  */
192 #ifdef WIN32_THREADS
193
194 void FreeTSD(_glthread_TSD *p)
195 {
196    if (p->initMagic==INIT_MAGIC) {
197       TlsFree(p->key);
198       p->initMagic=0;
199    }
200 }
201
202 void InsteadOf_exit(int nCode)
203 {
204    DWORD dwErr=GetLastError();
205 }
206
207 unsigned long
208 _glthread_GetID(void)
209 {
210    return GetCurrentThreadId();
211 }
212
213
214 void
215 _glthread_InitTSD(_glthread_TSD *tsd)
216 {
217    tsd->key = TlsAlloc();
218    if (tsd->key == TLS_OUT_OF_INDEXES) {
219       perror("Mesa:_glthread_InitTSD");
220       InsteadOf_exit(-1);
221    }
222    tsd->initMagic = INIT_MAGIC;
223 }
224
225
226 void *
227 _glthread_GetTSD(_glthread_TSD *tsd)
228 {
229    if (tsd->initMagic != INIT_MAGIC) {
230       _glthread_InitTSD(tsd);
231    }
232    return TlsGetValue(tsd->key);
233 }
234
235
236 void
237 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
238 {
239    /* the following code assumes that the _glthread_TSD has been initialized
240       to zero at creation */
241    if (tsd->initMagic != INIT_MAGIC) {
242       _glthread_InitTSD(tsd);
243    }
244    if (TlsSetValue(tsd->key, ptr) == 0) {
245           perror("Mesa:_glthread_SetTSD");
246           InsteadOf_exit(-1);
247    }
248 }
249
250 #endif /* WIN32_THREADS */
251
252
253
254 /*
255  * XFree86 has its own thread wrapper, Xthreads.h
256  * We wrap it again for GL.
257  */
258 #ifdef USE_XTHREADS
259
260 _X_EXPORT unsigned long
261 _glthread_GetID(void)
262 {
263    return (unsigned long) xthread_self();
264 }
265
266
267 void
268 _glthread_InitTSD(_glthread_TSD *tsd)
269 {
270    if (xthread_key_create(&tsd->key, NULL) != 0) {
271       perror(INIT_TSD_ERROR);
272       exit(-1);
273    }
274    tsd->initMagic = INIT_MAGIC;
275 }
276
277
278 void *
279 _glthread_GetTSD(_glthread_TSD *tsd)
280 {
281    void *ptr;
282    if (tsd->initMagic != INIT_MAGIC) {
283       _glthread_InitTSD(tsd);
284    }
285    xthread_get_specific(tsd->key, &ptr);
286    return ptr;
287 }
288
289
290 void
291 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
292 {
293    if (tsd->initMagic != INIT_MAGIC) {
294       _glthread_InitTSD(tsd);
295    }
296    xthread_set_specific(tsd->key, ptr);
297 }
298
299 #endif /* XTHREAD */
300
301
302
303 /*
304  * BeOS threads
305  */
306 #ifdef BEOS_THREADS
307
308 unsigned long
309 _glthread_GetID(void)
310 {
311    return (unsigned long) find_thread(NULL);
312 }
313
314 void
315 _glthread_InitTSD(_glthread_TSD *tsd)
316 {
317    tsd->key = tls_allocate();
318    tsd->initMagic = INIT_MAGIC;
319 }
320
321 void *
322 _glthread_GetTSD(_glthread_TSD *tsd)
323 {
324    if (tsd->initMagic != (int) INIT_MAGIC) {
325       _glthread_InitTSD(tsd);
326    }
327    return tls_get(tsd->key);
328 }
329
330 void
331 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
332 {
333    if (tsd->initMagic != (int) INIT_MAGIC) {
334       _glthread_InitTSD(tsd);
335    }
336    tls_set(tsd->key, ptr);
337 }
338
339 #endif /* BEOS_THREADS */
340
341
342
343 #else  /* THREADS */
344
345
346 /*
347  * no-op functions
348  */
349
350 _X_EXPORT unsigned long
351 _glthread_GetID(void)
352 {
353    return 0;
354 }
355
356
357 void
358 _glthread_InitTSD(_glthread_TSD *tsd)
359 {
360    (void) tsd;
361 }
362
363
364 void *
365 _glthread_GetTSD(_glthread_TSD *tsd)
366 {
367    (void) tsd;
368    return NULL;
369 }
370
371
372 void
373 _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
374 {
375    (void) tsd;
376    (void) ptr;
377 }
378
379
380 #endif /* THREADS */