Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mapi / mapi / u_thread.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 #include <stdio.h>
27 #include <stdlib.h>
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 <errno.h>
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 unsigned long
117 u_thread_self(void)
118 {
119    return GetCurrentThreadId();
120 }
121
122
123 void
124 u_tsd_init(struct u_tsd *tsd)
125 {
126    tsd->key = TlsAlloc();
127    if (tsd->key == TLS_OUT_OF_INDEXES) {
128       perror(INIT_TSD_ERROR);
129       exit(-1);
130    }
131    tsd->initMagic = INIT_MAGIC;
132 }
133
134
135 void
136 u_tsd_destroy(struct u_tsd *tsd)
137 {
138    if (tsd->initMagic != INIT_MAGIC) {
139       return;
140    }
141    TlsFree(tsd->key);
142    tsd->initMagic = 0x0;
143 }
144
145
146 void *
147 u_tsd_get(struct u_tsd *tsd)
148 {
149    if (tsd->initMagic != INIT_MAGIC) {
150       u_tsd_init(tsd);
151    }
152    return TlsGetValue(tsd->key);
153 }
154
155
156 void
157 u_tsd_set(struct u_tsd *tsd, void *ptr)
158 {
159    /* the following code assumes that the struct u_tsd has been initialized
160       to zero at creation */
161    if (tsd->initMagic != INIT_MAGIC) {
162       u_tsd_init(tsd);
163    }
164    if (TlsSetValue(tsd->key, ptr) == 0) {
165       perror(SET_TSD_ERROR);
166       exit(-1);
167    }
168 }
169
170 #endif /* WIN32 */
171
172 /*
173  * BeOS threads
174  */
175 #ifdef BEOS_THREADS
176
177 unsigned long
178 u_thread_self(void)
179 {
180    return (unsigned long) find_thread(NULL);
181 }
182
183 void
184 u_tsd_init(struct u_tsd *tsd)
185 {
186    tsd->key = tls_allocate();
187    tsd->initMagic = INIT_MAGIC;
188 }
189
190 void *
191 u_tsd_get(struct u_tsd *tsd)
192 {
193    if (tsd->initMagic != (int) INIT_MAGIC) {
194       u_tsd_init(tsd);
195    }
196    return tls_get(tsd->key);
197 }
198
199 void
200 u_tsd_set(struct u_tsd *tsd, void *ptr)
201 {
202    if (tsd->initMagic != (int) INIT_MAGIC) {
203       u_tsd_init(tsd);
204    }
205    tls_set(tsd->key, ptr);
206 }
207
208 #endif /* BEOS_THREADS */
209
210
211
212 #else  /* THREADS */
213
214
215 /*
216  * no-op functions
217  */
218
219 unsigned long
220 u_thread_self(void)
221 {
222    return 0;
223 }
224
225
226 void
227 u_tsd_init(struct u_tsd *tsd)
228 {
229    (void) tsd;
230 }
231
232
233 void *
234 u_tsd_get(struct u_tsd *tsd)
235 {
236    (void) tsd;
237    return NULL;
238 }
239
240
241 void
242 u_tsd_set(struct u_tsd *tsd, void *ptr)
243 {
244    (void) tsd;
245    (void) ptr;
246 }
247
248
249 #endif /* THREADS */