This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perldoc -m [PATCH]
[perl5.git] / thread.h
1 /*    thread.h
2  *
3  *    Copyright (c) 1997-2002, Larry Wall
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_5005THREADS) || 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__)) /* 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 #if defined(USE_5005THREADS)
330
331 /* Accessor for per-thread SVs */
332 #  define THREADSV(i) (thr->threadsvp[i])
333
334 /*
335  * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
336  * try only locking them if there may be more than one thread in existence.
337  * Systems with very fast mutexes (and/or slow conditionals) may wish to
338  * remove the "if (threadnum) ..." test.
339  * XXX do NOT use C<if (PL_threadnum) ...> -- it sets up race conditions!
340  */
341 #  define LOCK_SV_MUTEX         MUTEX_LOCK(&PL_sv_mutex)
342 #  define UNLOCK_SV_MUTEX       MUTEX_UNLOCK(&PL_sv_mutex)
343 #  define LOCK_STRTAB_MUTEX     MUTEX_LOCK(&PL_strtab_mutex)
344 #  define UNLOCK_STRTAB_MUTEX   MUTEX_UNLOCK(&PL_strtab_mutex)
345 #  define LOCK_CRED_MUTEX       MUTEX_LOCK(&PL_cred_mutex)
346 #  define UNLOCK_CRED_MUTEX     MUTEX_UNLOCK(&PL_cred_mutex)
347 #  define LOCK_FDPID_MUTEX      MUTEX_LOCK(&PL_fdpid_mutex)
348 #  define UNLOCK_FDPID_MUTEX    MUTEX_UNLOCK(&PL_fdpid_mutex)
349 #  define LOCK_SV_LOCK_MUTEX    MUTEX_LOCK(&PL_sv_lock_mutex)
350 #  define UNLOCK_SV_LOCK_MUTEX  MUTEX_UNLOCK(&PL_sv_lock_mutex)
351
352 /* Values and macros for thr->flags */
353 #define THRf_STATE_MASK 7
354 #define THRf_R_JOINABLE 0
355 #define THRf_R_JOINED   1
356 #define THRf_R_DETACHED 2
357 #define THRf_ZOMBIE     3
358 #define THRf_DEAD       4
359
360 #define THRf_DID_DIE    8
361
362 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
363 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
364 #define ThrSETSTATE(t, s) STMT_START {          \
365         (t)->flags &= ~THRf_STATE_MASK;         \
366         (t)->flags |= (s);                      \
367         DEBUG_S(PerlIO_printf(Perl_debug_log,   \
368                               "thread %p set to state %d\n", (t), (s))); \
369     } STMT_END
370
371 typedef struct condpair {
372     perl_mutex  mutex;          /* Protects all other fields */
373     perl_cond   owner_cond;     /* For when owner changes at all */
374     perl_cond   cond;           /* For cond_signal and cond_broadcast */
375     Thread      owner;          /* Currently owning thread */
376 } condpair_t;
377
378 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
379 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
380 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
381 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
382
383 #endif /* USE_5005THREADS */
384 #endif /* USE_5005THREADS || USE_ITHREADS */
385
386 #ifndef MUTEX_LOCK
387 #  define MUTEX_LOCK(m)
388 #endif
389
390 #ifndef MUTEX_UNLOCK
391 #  define MUTEX_UNLOCK(m)
392 #endif
393
394 #ifndef MUTEX_INIT
395 #  define MUTEX_INIT(m)
396 #endif
397
398 #ifndef MUTEX_DESTROY
399 #  define MUTEX_DESTROY(m)
400 #endif
401
402 #ifndef COND_INIT
403 #  define COND_INIT(c)
404 #endif
405
406 #ifndef COND_SIGNAL
407 #  define COND_SIGNAL(c)
408 #endif
409
410 #ifndef COND_BROADCAST
411 #  define COND_BROADCAST(c)
412 #endif
413
414 #ifndef COND_WAIT
415 #  define COND_WAIT(c, m)
416 #endif
417
418 #ifndef COND_DESTROY
419 #  define COND_DESTROY(c)
420 #endif
421
422 #ifndef LOCK_SV_MUTEX
423 #  define LOCK_SV_MUTEX
424 #endif
425
426 #ifndef UNLOCK_SV_MUTEX
427 #  define UNLOCK_SV_MUTEX
428 #endif
429
430 #ifndef LOCK_STRTAB_MUTEX
431 #  define LOCK_STRTAB_MUTEX
432 #endif
433
434 #ifndef UNLOCK_STRTAB_MUTEX
435 #  define UNLOCK_STRTAB_MUTEX
436 #endif
437
438 #ifndef LOCK_CRED_MUTEX
439 #  define LOCK_CRED_MUTEX
440 #endif
441
442 #ifndef UNLOCK_CRED_MUTEX
443 #  define UNLOCK_CRED_MUTEX
444 #endif
445
446 #ifndef LOCK_FDPID_MUTEX
447 #  define LOCK_FDPID_MUTEX
448 #endif
449
450 #ifndef UNLOCK_FDPID_MUTEX
451 #  define UNLOCK_FDPID_MUTEX
452 #endif
453
454 #ifndef LOCK_SV_LOCK_MUTEX
455 #  define LOCK_SV_LOCK_MUTEX
456 #endif
457
458 #ifndef UNLOCK_SV_LOCK_MUTEX
459 #  define UNLOCK_SV_LOCK_MUTEX
460 #endif
461
462 /* THR, SET_THR, and dTHR are there for compatibility with old versions */
463 #ifndef THR
464 #  define THR           PERL_GET_THX
465 #endif
466
467 #ifndef SET_THR
468 #  define SET_THR(t)    PERL_SET_THX(t)
469 #endif
470
471 #ifndef dTHR
472 #  define dTHR dNOOP
473 #endif
474
475 #ifndef INIT_THREADS
476 #  define INIT_THREADS NOOP
477 #endif