bd4b91052da73cb9ecbf2048183d78603947e01b
[p5sagit/p5-mst-13.2.git] / thread.h
1 /*    thread.h
2  *
3  *    Copyright (C) 1999, 2000, 2001, 2002, by Larry Wall and others
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 #if defined(USE_ITHREADS)
11
12 #if defined(VMS)
13 #include <builtins.h>
14 #endif
15
16 #ifdef WIN32
17 #  include <win32thread.h>
18 #else
19 #ifdef NETWARE
20 #  include <nw5thread.h>
21 #else
22 #  ifdef OLD_PTHREADS_API /* Here be dragons. */
23 #    define DETACH(t) \
24     STMT_START {                                                \
25         if (pthread_detach(&(t)->self)) {                       \
26             MUTEX_UNLOCK(&(t)->mutex);                          \
27             Perl_croak_nocontext("panic: DETACH");              \
28         }                                                       \
29     } STMT_END
30
31 #    define PERL_GET_CONTEXT    Perl_get_context()
32 #    define PERL_SET_CONTEXT(t) Perl_set_context((void*)t)
33
34 #    define PTHREAD_GETSPECIFIC_INT
35 #    ifdef DJGPP
36 #      define pthread_addr_t any_t
37 #      define NEED_PTHREAD_INIT
38 #      define PTHREAD_CREATE_JOINABLE (1)
39 #    endif
40 #    ifdef __OPEN_VM
41 #      define pthread_addr_t void *
42 #    endif
43 #    ifdef VMS
44 #      define pthread_attr_init(a) pthread_attr_create(a)
45 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_setdetach_np(a,s)
46 #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
47 #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
48 #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
49 #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
50 #    endif
51 #    if defined(__hpux) && defined(__ux_version) && __ux_version <= 1020
52 #      define pthread_attr_init(a) pthread_attr_create(a)
53        /* XXX pthread_setdetach_np() missing in DCE threads on HP-UX 10.20 */
54 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s)  (0)
55 #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
56 #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
57 #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
58 #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
59 #    endif
60 #    if defined(DJGPP) || defined(__OPEN_VM)
61 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,&(s))
62 #      define YIELD pthread_yield(NULL)
63 #    endif
64 #  endif
65 #  if !defined(__hpux) || !defined(__ux_version) || __ux_version > 1020
66 #    define pthread_mutexattr_default NULL
67 #    define pthread_condattr_default  NULL
68 #  endif
69 #endif  /* NETWARE */
70 #endif
71
72 #ifndef PTHREAD_CREATE
73 /* You are not supposed to pass NULL as the 2nd arg of PTHREAD_CREATE(). */
74 #  define PTHREAD_CREATE(t,a,s,d) pthread_create(t,&(a),s,d)
75 #endif
76
77 #ifndef PTHREAD_ATTR_SETDETACHSTATE
78 #  define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,s)
79 #endif
80
81 #ifndef PTHREAD_CREATE_JOINABLE
82 #  ifdef OLD_PTHREAD_CREATE_JOINABLE
83 #    define PTHREAD_CREATE_JOINABLE OLD_PTHREAD_CREATE_JOINABLE
84 #  else
85 #    define PTHREAD_CREATE_JOINABLE 0 /* Panic?  No, guess. */
86 #  endif
87 #endif
88
89 #ifdef DGUX
90 #  define THREAD_CREATE_NEEDS_STACK (32*1024)
91 #endif
92
93 #ifdef I_MACH_CTHREADS
94
95 /* cthreads interface */
96
97 /* #include <mach/cthreads.h> is in perl.h #ifdef I_MACH_CTHREADS */
98
99 #define MUTEX_INIT(m) \
100     STMT_START {                                                \
101         *m = mutex_alloc();                                     \
102         if (*m) {                                               \
103             mutex_init(*m);                                     \
104         } else {                                                \
105             Perl_croak_nocontext("panic: MUTEX_INIT");          \
106         }                                                       \
107     } STMT_END
108
109 #define MUTEX_LOCK(m)                   mutex_lock(*m)
110 #define MUTEX_UNLOCK(m)                 mutex_unlock(*m)
111 #define MUTEX_DESTROY(m) \
112     STMT_START {                                                \
113         mutex_free(*m);                                         \
114         *m = 0;                                                 \
115     } STMT_END
116
117 #define COND_INIT(c) \
118     STMT_START {                                                \
119         *c = condition_alloc();                                 \
120         if (*c) {                                               \
121             condition_init(*c);                                 \
122         }                                                       \
123         else {                                                  \
124             Perl_croak_nocontext("panic: COND_INIT");           \
125         }                                                       \
126     } STMT_END
127
128 #define COND_SIGNAL(c)          condition_signal(*c)
129 #define COND_BROADCAST(c)       condition_broadcast(*c)
130 #define COND_WAIT(c, m)         condition_wait(*c, *m)
131 #define COND_DESTROY(c) \
132     STMT_START {                                                \
133         condition_free(*c);                                     \
134         *c = 0;                                                 \
135     } STMT_END
136
137 #define THREAD_CREATE(thr, f)   (thr->self = cthread_fork(f, thr), 0)
138 #define THREAD_POST_CREATE(thr)
139
140 #define THREAD_RET_TYPE         any_t
141 #define THREAD_RET_CAST(x)      ((any_t) x)
142
143 #define DETACH(t)               cthread_detach(t->self)
144 #define JOIN(t, avp)            (*(avp) = (AV *)cthread_join(t->self))
145
146 #define PERL_SET_CONTEXT(t)     cthread_set_data(cthread_self(), t)
147 #define PERL_GET_CONTEXT        cthread_data(cthread_self())
148
149 #define INIT_THREADS            cthread_init()
150 #define YIELD                   cthread_yield()
151 #define ALLOC_THREAD_KEY        NOOP
152 #define FREE_THREAD_KEY         NOOP
153 #define SET_THREAD_SELF(thr)    (thr->self = cthread_self())
154
155 #endif /* I_MACH_CTHREADS */
156
157 #ifndef YIELD
158 #  ifdef SCHED_YIELD
159 #    define YIELD SCHED_YIELD
160 #  else
161 #    ifdef HAS_SCHED_YIELD
162 #      define YIELD sched_yield()
163 #    else
164 #      ifdef HAS_PTHREAD_YIELD
165     /* pthread_yield(NULL) platforms are expected
166      * to have #defined YIELD for themselves. */
167 #        define YIELD pthread_yield()
168 #      endif
169 #    endif
170 #  endif
171 #endif
172
173 #ifdef __hpux
174 #  define MUTEX_INIT_NEEDS_MUTEX_ZEROED
175 #endif
176
177 #ifndef MUTEX_INIT
178
179 #  ifdef MUTEX_INIT_NEEDS_MUTEX_ZEROED
180     /* Temporary workaround, true bug is deeper. --jhi 1999-02-25 */
181 #    define MUTEX_INIT(m) \
182     STMT_START {                                                \
183         Zero((m), 1, perl_mutex);                               \
184         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
185             Perl_croak_nocontext("panic: MUTEX_INIT");          \
186     } STMT_END
187 #  else
188 #    define MUTEX_INIT(m) \
189     STMT_START {                                                \
190         if (pthread_mutex_init((m), pthread_mutexattr_default)) \
191             Perl_croak_nocontext("panic: MUTEX_INIT");          \
192     } STMT_END
193 #  endif
194
195 #  define MUTEX_LOCK(m) \
196     STMT_START {                                                \
197         if (pthread_mutex_lock((m)))                            \
198             Perl_croak_nocontext("panic: MUTEX_LOCK");          \
199     } STMT_END
200
201 #  define MUTEX_UNLOCK(m) \
202     STMT_START {                                                \
203         if (pthread_mutex_unlock((m)))                          \
204             Perl_croak_nocontext("panic: MUTEX_UNLOCK");        \
205     } STMT_END
206
207 #  define MUTEX_DESTROY(m) \
208     STMT_START {                                                \
209         if (pthread_mutex_destroy((m)))                         \
210             Perl_croak_nocontext("panic: MUTEX_DESTROY");       \
211     } STMT_END
212 #endif /* MUTEX_INIT */
213
214 #ifndef COND_INIT
215 #  define COND_INIT(c) \
216     STMT_START {                                                \
217         if (pthread_cond_init((c), pthread_condattr_default))   \
218             Perl_croak_nocontext("panic: COND_INIT");           \
219     } STMT_END
220
221 #  define COND_SIGNAL(c) \
222     STMT_START {                                                \
223         if (pthread_cond_signal((c)))                           \
224             Perl_croak_nocontext("panic: COND_SIGNAL");         \
225     } STMT_END
226
227 #  define COND_BROADCAST(c) \
228     STMT_START {                                                \
229         if (pthread_cond_broadcast((c)))                        \
230             Perl_croak_nocontext("panic: COND_BROADCAST");      \
231     } STMT_END
232
233 #  define COND_WAIT(c, m) \
234     STMT_START {                                                \
235         if (pthread_cond_wait((c), (m)))                        \
236             Perl_croak_nocontext("panic: COND_WAIT");           \
237     } STMT_END
238
239 #  define COND_DESTROY(c) \
240     STMT_START {                                                \
241         if (pthread_cond_destroy((c)))                          \
242             Perl_croak_nocontext("panic: COND_DESTROY");        \
243     } STMT_END
244 #endif /* COND_INIT */
245
246 /* DETACH(t) must only be called while holding t->mutex */
247 #ifndef DETACH
248 #  define DETACH(t) \
249     STMT_START {                                                \
250         if (pthread_detach((t)->self)) {                        \
251             MUTEX_UNLOCK(&(t)->mutex);                          \
252             Perl_croak_nocontext("panic: DETACH");              \
253         }                                                       \
254     } STMT_END
255 #endif /* DETACH */
256
257 #ifndef JOIN
258 #  define JOIN(t, avp) \
259     STMT_START {                                                \
260         if (pthread_join((t)->self, (void**)(avp)))             \
261             Perl_croak_nocontext("panic: pthread_join");        \
262     } STMT_END
263 #endif /* JOIN */
264
265 /* Use an unchecked fetch of thread-specific data instead of a checked one.
266  * It would fail if the key were bogus, but if the key were bogus then
267  * Really Bad Things would be happening anyway. --dan */
268 #if (defined(__ALPHA) && (__VMS_VER >= 70000000)) || \
269     (defined(__alpha) && defined(__osf__) && !defined(__GNUC__)) /* Available only on >= 4.0 */
270 #  define HAS_PTHREAD_UNCHECKED_GETSPECIFIC_NP /* Configure test needed */
271 #endif
272
273 #ifdef HAS_PTHREAD_UNCHECKED_GETSPECIFIC_NP
274 #  define PTHREAD_GETSPECIFIC(key) pthread_unchecked_getspecific_np(key)
275 #else
276 #  define PTHREAD_GETSPECIFIC(key) pthread_getspecific(key)
277 #endif
278
279 #ifndef PERL_GET_CONTEXT
280 #  define PERL_GET_CONTEXT      PTHREAD_GETSPECIFIC(PL_thr_key)
281 #endif
282
283 #ifndef PERL_SET_CONTEXT
284 #  define PERL_SET_CONTEXT(t) \
285     STMT_START {                                                \
286         if (pthread_setspecific(PL_thr_key, (void *)(t)))       \
287             Perl_croak_nocontext("panic: pthread_setspecific"); \
288     } STMT_END
289 #endif /* PERL_SET_CONTEXT */
290
291 #ifndef INIT_THREADS
292 #  ifdef NEED_PTHREAD_INIT
293 #    define INIT_THREADS pthread_init()
294 #  endif
295 #endif
296
297 #ifndef ALLOC_THREAD_KEY
298 #  define ALLOC_THREAD_KEY \
299     STMT_START {                                                \
300         if (pthread_key_create(&PL_thr_key, 0)) {               \
301             PerlIO_printf(PerlIO_stderr(), "panic: pthread_key_create");        \
302             exit(1);                                            \
303         }                                                       \
304     } STMT_END
305 #endif
306
307 #ifndef FREE_THREAD_KEY
308 #  define FREE_THREAD_KEY \
309     STMT_START {                                                \
310         pthread_key_delete(PL_thr_key);                         \
311     } STMT_END
312 #endif
313
314 #ifndef PTHREAD_ATFORK
315 #  ifdef HAS_PTHREAD_ATFORK
316 #    define PTHREAD_ATFORK(prepare,parent,child)                \
317         pthread_atfork(prepare,parent,child)
318 #  else
319 #    define PTHREAD_ATFORK(prepare,parent,child)                \
320         NOOP
321 #  endif
322 #endif
323
324 #ifndef THREAD_RET_TYPE
325 #  define THREAD_RET_TYPE       void *
326 #  define THREAD_RET_CAST(p)    ((void *)(p))
327 #endif /* THREAD_RET */
328
329 #  define LOCK_DOLLARZERO_MUTEX         MUTEX_LOCK(&PL_dollarzero_mutex)
330 #  define UNLOCK_DOLLARZERO_MUTEX       MUTEX_UNLOCK(&PL_dollarzero_mutex)
331
332 #endif /* USE_ITHREADS */
333
334 #ifndef MUTEX_LOCK
335 #  define MUTEX_LOCK(m)
336 #endif
337
338 #ifndef MUTEX_UNLOCK
339 #  define MUTEX_UNLOCK(m)
340 #endif
341
342 #ifndef MUTEX_INIT
343 #  define MUTEX_INIT(m)
344 #endif
345
346 #ifndef MUTEX_DESTROY
347 #  define MUTEX_DESTROY(m)
348 #endif
349
350 #ifndef COND_INIT
351 #  define COND_INIT(c)
352 #endif
353
354 #ifndef COND_SIGNAL
355 #  define COND_SIGNAL(c)
356 #endif
357
358 #ifndef COND_BROADCAST
359 #  define COND_BROADCAST(c)
360 #endif
361
362 #ifndef COND_WAIT
363 #  define COND_WAIT(c, m)
364 #endif
365
366 #ifndef COND_DESTROY
367 #  define COND_DESTROY(c)
368 #endif
369
370 #ifndef LOCK_SV_MUTEX
371 #  define LOCK_SV_MUTEX
372 #endif
373
374 #ifndef UNLOCK_SV_MUTEX
375 #  define UNLOCK_SV_MUTEX
376 #endif
377
378 #ifndef LOCK_STRTAB_MUTEX
379 #  define LOCK_STRTAB_MUTEX
380 #endif
381
382 #ifndef UNLOCK_STRTAB_MUTEX
383 #  define UNLOCK_STRTAB_MUTEX
384 #endif
385
386 #ifndef LOCK_CRED_MUTEX
387 #  define LOCK_CRED_MUTEX
388 #endif
389
390 #ifndef UNLOCK_CRED_MUTEX
391 #  define UNLOCK_CRED_MUTEX
392 #endif
393
394 #ifndef LOCK_FDPID_MUTEX
395 #  define LOCK_FDPID_MUTEX
396 #endif
397
398 #ifndef UNLOCK_FDPID_MUTEX
399 #  define UNLOCK_FDPID_MUTEX
400 #endif
401
402 #ifndef LOCK_SV_LOCK_MUTEX
403 #  define LOCK_SV_LOCK_MUTEX
404 #endif
405
406 #ifndef UNLOCK_SV_LOCK_MUTEX
407 #  define UNLOCK_SV_LOCK_MUTEX
408 #endif
409
410 #ifndef LOCK_DOLLARZERO_MUTEX
411 #  define LOCK_DOLLARZERO_MUTEX
412 #endif
413
414 #ifndef UNLOCK_DOLLARZERO_MUTEX
415 #  define UNLOCK_DOLLARZERO_MUTEX
416 #endif
417
418 /* THR, SET_THR, and dTHR are there for compatibility with old versions */
419 #ifndef THR
420 #  define THR           PERL_GET_THX
421 #endif
422
423 #ifndef SET_THR
424 #  define SET_THR(t)    PERL_SET_THX(t)
425 #endif
426
427 #ifndef dTHR
428 #  define dTHR dNOOP
429 #endif
430
431 #ifndef INIT_THREADS
432 #  define INIT_THREADS NOOP
433 #endif