xref: /openbsd/gnu/usr.bin/perl/thread.h (revision db3296cf)
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
478