1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 #ifndef _GLTHREAD_THREAD_H
71 #define _GLTHREAD_THREAD_H
72
73 #include <errno.h>
74 #include <stdlib.h>
75
76 #if !defined c11_threads_in_use
77 # if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC
78 # define c11_threads_in_use() 1
79 # elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK
80 # include <threads.h>
81 # pragma weak thrd_exit
82 # define c11_threads_in_use() (thrd_exit != NULL)
83 # else
84 # define c11_threads_in_use() 0
85 # endif
86 #endif
87
88
89
90 #if USE_ISOC_THREADS
91
92
93
94 # include <threads.h>
95
96 # ifdef __cplusplus
97 extern "C" {
98 # endif
99
100
101
102 typedef struct thrd_with_exitvalue *gl_thread_t;
103 extern int glthread_create (gl_thread_t *threadp,
104 void *(*func) (void *), void *arg);
105 # define glthread_sigmask(HOW, SET, OSET) \
106 pthread_sigmask (HOW, SET, OSET)
107 extern int glthread_join (gl_thread_t thread, void **return_value_ptr);
108 extern gl_thread_t gl_thread_self (void);
109 # define gl_thread_self_pointer() \
110 (void *) gl_thread_self ()
111 extern _Noreturn void gl_thread_exit (void *return_value);
112 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
113
114 # ifdef __cplusplus
115 }
116 # endif
117
118 #endif
119
120
121
122 #if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS
123
124
125
126 # include <pthread.h>
127
128
129 # if defined __sgi
130 # include <unistd.h>
131 # endif
132
133 # if USE_POSIX_THREADS_WEAK
134
135
136 # include <signal.h>
137 # endif
138
139 # ifdef __cplusplus
140 extern "C" {
141 # endif
142
143 # if PTHREAD_IN_USE_DETECTION_HARD
144
145
146 # define pthread_in_use() \
147 glthread_in_use ()
148 extern int glthread_in_use (void);
149
150 # endif
151
152 # if USE_POSIX_THREADS_WEAK
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 # ifndef pthread_sigmask
172 # pragma weak pthread_sigmask
173 # endif
174
175 # pragma weak pthread_join
176 # ifndef pthread_self
177 # pragma weak pthread_self
178 # endif
179 # pragma weak pthread_exit
180 # if HAVE_PTHREAD_ATFORK
181 # pragma weak pthread_atfork
182 # endif
183
184 # if !PTHREAD_IN_USE_DETECTION_HARD
185 # pragma weak pthread_mutexattr_gettype
186 # define pthread_in_use() \
187 (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
188 # endif
189
190 # else
191
192 # if !PTHREAD_IN_USE_DETECTION_HARD
193 # define pthread_in_use() 1
194 # endif
195
196 # endif
197
198
199
200
201
202
203 typedef pthread_t gl_thread_t;
204 # define glthread_create(THREADP, FUNC, ARG) \
205 (pthread_in_use () ? pthread_create (THREADP, NULL, FUNC, ARG) : ENOSYS)
206 # define glthread_sigmask(HOW, SET, OSET) \
207 (pthread_in_use () ? pthread_sigmask (HOW, SET, OSET) : 0)
208 # define glthread_join(THREAD, RETVALP) \
209 (pthread_in_use () ? pthread_join (THREAD, RETVALP) : 0)
210 # ifdef PTW32_VERSION
211
212
213 # define gl_thread_self() \
214 (pthread_in_use () ? pthread_self () : gl_null_thread)
215 # define gl_thread_self_pointer() \
216 (pthread_in_use () ? pthread_self ().p : NULL)
217 extern const gl_thread_t gl_null_thread;
218 # elif defined __MVS__
219
220
221
222 # define gl_thread_self() \
223 (pthread_in_use () ? pthread_self () : gl_null_thread)
224 # define gl_thread_self_pointer() \
225 (pthread_in_use () ? *((void **) pthread_self ().__) : NULL)
226 extern const gl_thread_t gl_null_thread;
227 # else
228 # define gl_thread_self() \
229 (pthread_in_use () ? pthread_self () : (pthread_t) 0)
230 # define gl_thread_self_pointer() \
231 (pthread_in_use () ? (void *) pthread_self () : NULL)
232 # endif
233 # define gl_thread_exit(RETVAL) \
234 (void) (pthread_in_use () ? (pthread_exit (RETVAL), 0) : 0)
235
236 # if HAVE_PTHREAD_ATFORK
237 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) \
238 (pthread_in_use () ? pthread_atfork (PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) : 0)
239 # else
240 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
241 # endif
242
243 # ifdef __cplusplus
244 }
245 # endif
246
247 #endif
248
249
250
251 #if USE_WINDOWS_THREADS
252
253 # define WIN32_LEAN_AND_MEAN
254 # include <windows.h>
255
256 # include "windows-thread.h"
257
258 # ifdef __cplusplus
259 extern "C" {
260 # endif
261
262
263
264 typedef glwthread_thread_t gl_thread_t;
265 # define glthread_create(THREADP, FUNC, ARG) \
266 glwthread_thread_create (THREADP, 0, FUNC, ARG)
267 # define glthread_sigmask(HOW, SET, OSET) \
268 0
269 # define glthread_join(THREAD, RETVALP) \
270 glwthread_thread_join (THREAD, RETVALP)
271 # define gl_thread_self() \
272 glwthread_thread_self ()
273 # define gl_thread_self_pointer() \
274 gl_thread_self ()
275 # define gl_thread_exit(RETVAL) \
276 glwthread_thread_exit (RETVAL)
277 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
278
279 # ifdef __cplusplus
280 }
281 # endif
282
283 #endif
284
285
286
287 #if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS)
288
289
290
291 typedef int gl_thread_t;
292 # define glthread_create(THREADP, FUNC, ARG) ENOSYS
293 # define glthread_sigmask(HOW, SET, OSET) 0
294 # define glthread_join(THREAD, RETVALP) 0
295 # define gl_thread_self() 0
296 # define gl_thread_self_pointer() \
297 ((void *) gl_thread_self ())
298 # define gl_thread_exit(RETVAL) (void)0
299 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0
300
301 #endif
302
303
304
305
306
307 #ifdef __cplusplus
308 extern "C" {
309 #endif
310
311 extern gl_thread_t gl_thread_create (void *(*func) (void *arg), void *arg);
312 #define gl_thread_sigmask(HOW, SET, OSET) \
313 do \
314 { \
315 if (glthread_sigmask (HOW, SET, OSET)) \
316 abort (); \
317 } \
318 while (0)
319 #define gl_thread_join(THREAD, RETVAL) \
320 do \
321 { \
322 if (glthread_join (THREAD, RETVAL)) \
323 abort (); \
324 } \
325 while (0)
326 #define gl_thread_atfork(PREPARE, PARENT, CHILD) \
327 do \
328 { \
329 if (glthread_atfork (PREPARE, PARENT, CHILD)) \
330 abort (); \
331 } \
332 while (0)
333
334 #ifdef __cplusplus
335 }
336 #endif
337
338 #endif