xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/thread.h (revision 0:68f95e015346)
1 /*    thread.h
2  *
3  *    Copyright (C) 1999, 2000, 2001, 2002, 2004, 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_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 	int _eC_;						\
26 	if ((_eC_ = pthread_detach(&(t)->self))) {		\
27 	    MUTEX_UNLOCK(&(t)->mutex);				\
28 	    Perl_croak_nocontext("panic: DETACH (%d) [%s:%d]",	\
29 				 _eC_, __FILE__, __LINE__);	\
30 	}							\
31     } STMT_END
32 
33 #    define PERL_GET_CONTEXT	Perl_get_context()
34 #    define PERL_SET_CONTEXT(t)	Perl_set_context((void*)t)
35 
36 #    define PTHREAD_GETSPECIFIC_INT
37 #    ifdef DJGPP
38 #      define pthread_addr_t any_t
39 #      define NEED_PTHREAD_INIT
40 #      define PTHREAD_CREATE_JOINABLE (1)
41 #    endif
42 #    ifdef __OPEN_VM
43 #      define pthread_addr_t void *
44 #    endif
45 #    ifdef OEMVS
46 #      define pthread_addr_t void *
47 #      define pthread_create(t,a,s,d)        pthread_create(t,&(a),s,d)
48 #      define pthread_keycreate              pthread_key_create
49 #    endif
50 #    ifdef VMS
51 #      define pthread_attr_init(a) pthread_attr_create(a)
52 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_setdetach_np(a,s)
53 #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
54 #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
55 #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
56 #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
57 #    endif
58 #    if defined(__hpux) && defined(__ux_version) && __ux_version <= 1020
59 #      define pthread_attr_init(a) pthread_attr_create(a)
60        /* XXX pthread_setdetach_np() missing in DCE threads on HP-UX 10.20 */
61 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s)	(0)
62 #      define PTHREAD_CREATE(t,a,s,d) pthread_create(t,a,s,d)
63 #      define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
64 #      define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
65 #      define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
66 #    endif
67 #    if defined(DJGPP) || defined(__OPEN_VM) || defined(OEMVS)
68 #      define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,&(s))
69 #      define YIELD pthread_yield(NULL)
70 #    endif
71 #  endif
72 #  if !defined(__hpux) || !defined(__ux_version) || __ux_version > 1020
73 #    define pthread_mutexattr_default NULL
74 #    define pthread_condattr_default  NULL
75 #  endif
76 #endif	/* NETWARE */
77 #endif
78 
79 #ifndef PTHREAD_CREATE
80 /* You are not supposed to pass NULL as the 2nd arg of PTHREAD_CREATE(). */
81 #  define PTHREAD_CREATE(t,a,s,d) pthread_create(t,&(a),s,d)
82 #endif
83 
84 #ifndef PTHREAD_ATTR_SETDETACHSTATE
85 #  define PTHREAD_ATTR_SETDETACHSTATE(a,s) pthread_attr_setdetachstate(a,s)
86 #endif
87 
88 #ifndef PTHREAD_CREATE_JOINABLE
89 #  ifdef OLD_PTHREAD_CREATE_JOINABLE
90 #    define PTHREAD_CREATE_JOINABLE OLD_PTHREAD_CREATE_JOINABLE
91 #  else
92 #    define PTHREAD_CREATE_JOINABLE 0 /* Panic?  No, guess. */
93 #  endif
94 #endif
95 
96 #ifdef DGUX
97 #  define THREAD_CREATE_NEEDS_STACK (32*1024)
98 #endif
99 
100 #ifdef I_MACH_CTHREADS
101 
102 /* cthreads interface */
103 
104 /* #include <mach/cthreads.h> is in perl.h #ifdef I_MACH_CTHREADS */
105 
106 #define MUTEX_INIT(m) \
107     STMT_START {						\
108 	*m = mutex_alloc();					\
109 	if (*m) {						\
110 	    mutex_init(*m);					\
111 	} else {						\
112 	    Perl_croak_nocontext("panic: MUTEX_INIT [%s:%d]",	\
113 				 __FILE__, __LINE__);		\
114 	}							\
115     } STMT_END
116 
117 #define MUTEX_LOCK(m)			mutex_lock(*m)
118 #define MUTEX_UNLOCK(m)			mutex_unlock(*m)
119 #define MUTEX_DESTROY(m) \
120     STMT_START {						\
121 	mutex_free(*m);						\
122 	*m = 0;							\
123     } STMT_END
124 
125 #define COND_INIT(c) \
126     STMT_START {						\
127 	*c = condition_alloc();					\
128 	if (*c) {						\
129 	    condition_init(*c);					\
130 	}							\
131 	else {							\
132 	    Perl_croak_nocontext("panic: COND_INIT [%s:%d]",	\
133 				 __FILE__, __LINE__);		\
134 	}							\
135     } STMT_END
136 
137 #define COND_SIGNAL(c)		condition_signal(*c)
138 #define COND_BROADCAST(c)	condition_broadcast(*c)
139 #define COND_WAIT(c, m)		condition_wait(*c, *m)
140 #define COND_DESTROY(c) \
141     STMT_START {						\
142 	condition_free(*c);					\
143 	*c = 0;							\
144     } STMT_END
145 
146 #define THREAD_CREATE(thr, f)	(thr->self = cthread_fork(f, thr), 0)
147 #define THREAD_POST_CREATE(thr)
148 
149 #define THREAD_RET_TYPE		any_t
150 #define THREAD_RET_CAST(x)	((any_t) x)
151 
152 #define DETACH(t)		cthread_detach(t->self)
153 #define JOIN(t, avp)		(*(avp) = (AV *)cthread_join(t->self))
154 
155 #define PERL_SET_CONTEXT(t)	cthread_set_data(cthread_self(), t)
156 #define PERL_GET_CONTEXT	cthread_data(cthread_self())
157 
158 #define INIT_THREADS		cthread_init()
159 #define YIELD			cthread_yield()
160 #define ALLOC_THREAD_KEY	NOOP
161 #define FREE_THREAD_KEY		NOOP
162 #define SET_THREAD_SELF(thr)	(thr->self = cthread_self())
163 
164 #endif /* I_MACH_CTHREADS */
165 
166 #ifndef YIELD
167 #  ifdef SCHED_YIELD
168 #    define YIELD SCHED_YIELD
169 #  else
170 #    ifdef HAS_SCHED_YIELD
171 #      define YIELD sched_yield()
172 #    else
173 #      ifdef HAS_PTHREAD_YIELD
174     /* pthread_yield(NULL) platforms are expected
175      * to have #defined YIELD for themselves. */
176 #        define YIELD pthread_yield()
177 #      endif
178 #    endif
179 #  endif
180 #endif
181 
182 #ifdef __hpux
183 #  define MUTEX_INIT_NEEDS_MUTEX_ZEROED
184 #endif
185 
186 #ifndef MUTEX_INIT
187 
188 #  ifdef MUTEX_INIT_NEEDS_MUTEX_ZEROED
189     /* Temporary workaround, true bug is deeper. --jhi 1999-02-25 */
190 #    define MUTEX_INIT(m) \
191     STMT_START {						\
192 	int _eC_;						\
193 	Zero((m), 1, perl_mutex);                               \
194  	if ((_eC_ = pthread_mutex_init((m), pthread_mutexattr_default)))	\
195 	    Perl_croak_nocontext("panic: MUTEX_INIT (%d) [%s:%d]",	\
196 				 _eC_, __FILE__, __LINE__);	\
197     } STMT_END
198 #  else
199 #    define MUTEX_INIT(m) \
200     STMT_START {						\
201 	int _eC_;						\
202 	if ((_eC_ = pthread_mutex_init((m), pthread_mutexattr_default)))	\
203 	    Perl_croak_nocontext("panic: MUTEX_INIT (%d) [%s:%d]",	\
204 				 _eC_, __FILE__, __LINE__);	\
205     } STMT_END
206 #  endif
207 
208 #  define MUTEX_LOCK(m) \
209     STMT_START {						\
210 	int _eC_;						\
211 	if ((_eC_ = pthread_mutex_lock((m))))			\
212 	    Perl_croak_nocontext("panic: MUTEX_LOCK (%d) [%s:%d]",	\
213 				 _eC_, __FILE__, __LINE__);	\
214     } STMT_END
215 
216 #  define MUTEX_UNLOCK(m) \
217     STMT_START {						\
218 	int _eC_;						\
219 	if ((_eC_ = pthread_mutex_unlock((m))))			\
220 	    Perl_croak_nocontext("panic: MUTEX_UNLOCK (%d) [%s:%d]",	\
221 				 _eC_, __FILE__, __LINE__);	\
222     } STMT_END
223 
224 #  define MUTEX_DESTROY(m) \
225     STMT_START {						\
226 	int _eC_;						\
227 	if ((_eC_ = pthread_mutex_destroy((m))))		\
228 	    Perl_croak_nocontext("panic: MUTEX_DESTROY (%d) [%s:%d]",	\
229 				 _eC_, __FILE__, __LINE__);	\
230     } STMT_END
231 #endif /* MUTEX_INIT */
232 
233 #ifndef COND_INIT
234 #  define COND_INIT(c) \
235     STMT_START {						\
236 	int _eC_;						\
237 	if ((_eC_ = pthread_cond_init((c), pthread_condattr_default)))	\
238 	    Perl_croak_nocontext("panic: COND_INIT (%d) [%s:%d]",	\
239 				 _eC_, __FILE__, __LINE__);	\
240     } STMT_END
241 
242 #  define COND_SIGNAL(c) \
243     STMT_START {						\
244 	int _eC_;						\
245 	if ((_eC_ = pthread_cond_signal((c))))			\
246 	    Perl_croak_nocontext("panic: COND_SIGNAL (%d) [%s:%d]",	\
247 				 _eC_, __FILE__, __LINE__);	\
248     } STMT_END
249 
250 #  define COND_BROADCAST(c) \
251     STMT_START {						\
252 	int _eC_;						\
253 	if ((_eC_ = pthread_cond_broadcast((c))))		\
254 	    Perl_croak_nocontext("panic: COND_BROADCAST (%d) [%s:%d]",	\
255 				 _eC_, __FILE__, __LINE__);	\
256     } STMT_END
257 
258 #  define COND_WAIT(c, m) \
259     STMT_START {						\
260 	int _eC_;						\
261 	if ((_eC_ = pthread_cond_wait((c), (m))))		\
262 	    Perl_croak_nocontext("panic: COND_WAIT (%d) [%s:%d]",	\
263 				 _eC_, __FILE__, __LINE__);	\
264     } STMT_END
265 
266 #  define COND_DESTROY(c) \
267     STMT_START {						\
268 	int _eC_;						\
269 	if ((_eC_ = pthread_cond_destroy((c))))			\
270 	    Perl_croak_nocontext("panic: COND_DESTROY (%d) [%s:%d]",	\
271 				 _eC_, __FILE__, __LINE__);	\
272     } STMT_END
273 #endif /* COND_INIT */
274 
275 /* DETACH(t) must only be called while holding t->mutex */
276 #ifndef DETACH
277 #  define DETACH(t) \
278     STMT_START {						\
279 	int _eC_;						\
280 	if ((_eC_ = pthread_detach((t)->self))) {		\
281 	    MUTEX_UNLOCK(&(t)->mutex);				\
282 	    Perl_croak_nocontext("panic: DETACH (%d) [%s:%d]",	\
283 				 _eC_, __FILE__, __LINE__);	\
284 	}							\
285     } STMT_END
286 #endif /* DETACH */
287 
288 #ifndef JOIN
289 #  define JOIN(t, avp) \
290     STMT_START {						\
291 	int _eC_;						\
292 	if ((_eC_ = pthread_join((t)->self, (void**)(avp))))	\
293 	    Perl_croak_nocontext("panic: pthread_join (%d) [%s:%d]",	\
294 				 _eC_, __FILE__, __LINE__);	\
295     } STMT_END
296 #endif /* JOIN */
297 
298 /* Use an unchecked fetch of thread-specific data instead of a checked one.
299  * It would fail if the key were bogus, but if the key were bogus then
300  * Really Bad Things would be happening anyway. --dan */
301 #if (defined(__ALPHA) && (__VMS_VER >= 70000000)) || \
302     (defined(__alpha) && defined(__osf__) && !defined(__GNUC__)) /* Available only on >= 4.0 */
303 #  define HAS_PTHREAD_UNCHECKED_GETSPECIFIC_NP /* Configure test needed */
304 #endif
305 
306 #ifdef HAS_PTHREAD_UNCHECKED_GETSPECIFIC_NP
307 #  define PTHREAD_GETSPECIFIC(key) pthread_unchecked_getspecific_np(key)
308 #else
309 #    define PTHREAD_GETSPECIFIC(key) pthread_getspecific(key)
310 #endif
311 
312 #ifndef PERL_GET_CONTEXT
313 #  define PERL_GET_CONTEXT	PTHREAD_GETSPECIFIC(PL_thr_key)
314 #endif
315 
316 #ifndef PERL_SET_CONTEXT
317 #  define PERL_SET_CONTEXT(t) \
318     STMT_START {						\
319 	int _eC_;						\
320 	if ((_eC_ = pthread_setspecific(PL_thr_key, (void *)(t))))	\
321 	    Perl_croak_nocontext("panic: pthread_setspecific (%d) [%s:%d]",	\
322 				 _eC_, __FILE__, __LINE__);	\
323     } STMT_END
324 #endif /* PERL_SET_CONTEXT */
325 
326 #ifndef INIT_THREADS
327 #  ifdef NEED_PTHREAD_INIT
328 #    define INIT_THREADS pthread_init()
329 #  endif
330 #endif
331 
332 #ifndef ALLOC_THREAD_KEY
333 #  define ALLOC_THREAD_KEY \
334     STMT_START {						\
335 	int _eC_;						\
336 	if ((_eC_ = pthread_key_create(&PL_thr_key, 0))) {	\
337 	    PerlIO_printf(PerlIO_stderr(), "panic: pthread_key_create (%d) [%s:%d]",	\
338 				 _eC_, __FILE__, __LINE__);	\
339 	    exit(1);						\
340 	}							\
341     } STMT_END
342 #endif
343 
344 #ifndef FREE_THREAD_KEY
345 #  define FREE_THREAD_KEY \
346     STMT_START {						\
347 	pthread_key_delete(PL_thr_key);				\
348     } STMT_END
349 #endif
350 
351 #ifndef PTHREAD_ATFORK
352 #  ifdef HAS_PTHREAD_ATFORK
353 #    define PTHREAD_ATFORK(prepare,parent,child)		\
354 	pthread_atfork(prepare,parent,child)
355 #  else
356 #    define PTHREAD_ATFORK(prepare,parent,child)		\
357 	NOOP
358 #  endif
359 #endif
360 
361 #ifndef THREAD_RET_TYPE
362 #  define THREAD_RET_TYPE	void *
363 #  define THREAD_RET_CAST(p)	((void *)(p))
364 #endif /* THREAD_RET */
365 
366 #if defined(USE_5005THREADS)
367 
368 /* Accessor for per-thread SVs */
369 #  define THREADSV(i) (thr->threadsvp[i])
370 
371 /*
372  * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
373  * try only locking them if there may be more than one thread in existence.
374  * Systems with very fast mutexes (and/or slow conditionals) may wish to
375  * remove the "if (threadnum) ..." test.
376  * XXX do NOT use C<if (PL_threadnum) ...> -- it sets up race conditions!
377  */
378 #  define LOCK_SV_MUTEX		MUTEX_LOCK(&PL_sv_mutex)
379 #  define UNLOCK_SV_MUTEX	MUTEX_UNLOCK(&PL_sv_mutex)
380 #  define LOCK_STRTAB_MUTEX	MUTEX_LOCK(&PL_strtab_mutex)
381 #  define UNLOCK_STRTAB_MUTEX	MUTEX_UNLOCK(&PL_strtab_mutex)
382 #  define LOCK_CRED_MUTEX	MUTEX_LOCK(&PL_cred_mutex)
383 #  define UNLOCK_CRED_MUTEX	MUTEX_UNLOCK(&PL_cred_mutex)
384 #  define LOCK_FDPID_MUTEX	MUTEX_LOCK(&PL_fdpid_mutex)
385 #  define UNLOCK_FDPID_MUTEX	MUTEX_UNLOCK(&PL_fdpid_mutex)
386 #  define LOCK_SV_LOCK_MUTEX	MUTEX_LOCK(&PL_sv_lock_mutex)
387 #  define UNLOCK_SV_LOCK_MUTEX	MUTEX_UNLOCK(&PL_sv_lock_mutex)
388 
389 /* Values and macros for thr->flags */
390 #define THRf_STATE_MASK	7
391 #define THRf_R_JOINABLE	0
392 #define THRf_R_JOINED	1
393 #define THRf_R_DETACHED	2
394 #define THRf_ZOMBIE	3
395 #define THRf_DEAD	4
396 
397 #define THRf_DID_DIE	8
398 
399 /* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
400 #define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
401 #define ThrSETSTATE(t, s) STMT_START {		\
402 	(t)->flags &= ~THRf_STATE_MASK;		\
403 	(t)->flags |= (s);			\
404 	DEBUG_S(PerlIO_printf(Perl_debug_log,	\
405 			      "thread %p set to state %d\n", (t), (s))); \
406     } STMT_END
407 
408 typedef struct condpair {
409     perl_mutex	mutex;		/* Protects all other fields */
410     perl_cond	owner_cond;	/* For when owner changes at all */
411     perl_cond	cond;		/* For cond_signal and cond_broadcast */
412     Thread	owner;		/* Currently owning thread */
413 } condpair_t;
414 
415 #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
416 #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
417 #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
418 #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
419 
420 #endif /* USE_5005THREADS */
421 
422 #  define LOCK_DOLLARZERO_MUTEX		MUTEX_LOCK(&PL_dollarzero_mutex)
423 #  define UNLOCK_DOLLARZERO_MUTEX	MUTEX_UNLOCK(&PL_dollarzero_mutex)
424 
425 #endif /* USE_5005THREADS || USE_ITHREADS */
426 
427 #ifndef MUTEX_LOCK
428 #  define MUTEX_LOCK(m)
429 #endif
430 
431 #ifndef MUTEX_UNLOCK
432 #  define MUTEX_UNLOCK(m)
433 #endif
434 
435 #ifndef MUTEX_INIT
436 #  define MUTEX_INIT(m)
437 #endif
438 
439 #ifndef MUTEX_DESTROY
440 #  define MUTEX_DESTROY(m)
441 #endif
442 
443 #ifndef COND_INIT
444 #  define COND_INIT(c)
445 #endif
446 
447 #ifndef COND_SIGNAL
448 #  define COND_SIGNAL(c)
449 #endif
450 
451 #ifndef COND_BROADCAST
452 #  define COND_BROADCAST(c)
453 #endif
454 
455 #ifndef COND_WAIT
456 #  define COND_WAIT(c, m)
457 #endif
458 
459 #ifndef COND_DESTROY
460 #  define COND_DESTROY(c)
461 #endif
462 
463 #ifndef LOCK_SV_MUTEX
464 #  define LOCK_SV_MUTEX
465 #endif
466 
467 #ifndef UNLOCK_SV_MUTEX
468 #  define UNLOCK_SV_MUTEX
469 #endif
470 
471 #ifndef LOCK_STRTAB_MUTEX
472 #  define LOCK_STRTAB_MUTEX
473 #endif
474 
475 #ifndef UNLOCK_STRTAB_MUTEX
476 #  define UNLOCK_STRTAB_MUTEX
477 #endif
478 
479 #ifndef LOCK_CRED_MUTEX
480 #  define LOCK_CRED_MUTEX
481 #endif
482 
483 #ifndef UNLOCK_CRED_MUTEX
484 #  define UNLOCK_CRED_MUTEX
485 #endif
486 
487 #ifndef LOCK_FDPID_MUTEX
488 #  define LOCK_FDPID_MUTEX
489 #endif
490 
491 #ifndef UNLOCK_FDPID_MUTEX
492 #  define UNLOCK_FDPID_MUTEX
493 #endif
494 
495 #ifndef LOCK_SV_LOCK_MUTEX
496 #  define LOCK_SV_LOCK_MUTEX
497 #endif
498 
499 #ifndef UNLOCK_SV_LOCK_MUTEX
500 #  define UNLOCK_SV_LOCK_MUTEX
501 #endif
502 
503 #ifndef LOCK_DOLLARZERO_MUTEX
504 #  define LOCK_DOLLARZERO_MUTEX
505 #endif
506 
507 #ifndef UNLOCK_DOLLARZERO_MUTEX
508 #  define UNLOCK_DOLLARZERO_MUTEX
509 #endif
510 
511 /* THR, SET_THR, and dTHR are there for compatibility with old versions */
512 #ifndef THR
513 #  define THR		PERL_GET_THX
514 #endif
515 
516 #ifndef SET_THR
517 #  define SET_THR(t)	PERL_SET_THX(t)
518 #endif
519 
520 #ifndef dTHR
521 #  define dTHR dNOOP
522 #endif
523 
524 #ifndef INIT_THREADS
525 #  define INIT_THREADS NOOP
526 #endif
527