This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
integrate changes#2978,2979 from mainline
[perl5.git] / thread.h
CommitLineData
ea0efc06 1#ifdef USE_THREADS
12ca11f6 2
ea0efc06 3#ifdef WIN32
d55594ae
GS
4# include <win32thread.h>
5#else
12ca11f6 6
9731c6ca 7#ifndef DJGPP
12ca11f6 8/* POSIXish threads */
11343788 9#ifdef OLD_PTHREADS_API
ea0efc06
MB
10# define pthread_mutexattr_init(a) pthread_mutexattr_create(a)
11# define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t)
12# define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d))
13# define YIELD pthread_yield()
14# define DETACH(t) \
15 STMT_START { \
46930d8f 16 if (pthread_detach(&(t)->self)) { \
ea0efc06
MB
17 MUTEX_UNLOCK(&(t)->mutex); \
18 croak("panic: DETACH"); \
19 } \
20 } STMT_END
11343788 21#else
ea0efc06
MB
22# define pthread_mutexattr_default NULL
23# define pthread_condattr_default NULL
11343788 24#endif /* OLD_PTHREADS_API */
d55594ae 25#endif
9731c6ca 26#endif
11343788 27
940cb80d
MB
28#ifdef PTHREADS_CREATED_JOINABLE
29# define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
30#else
31# ifdef PTHREAD_CREATE_UNDETACHED
32# define ATTR_JOINABLE PTHREAD_CREATE_UNDETACHED
33# else
34# define ATTR_JOINABLE PTHREAD_CREATE_JOINABLE
35# endif
36#endif
37
6a9db2ce
BH
38#ifdef I_MACH_CTHREADS
39
40/* cthreads interface */
41
42/* #include <mach/cthreads.h> is in perl.h #ifdef I_MACH_CTHREADS */
43
44#define MUTEX_INIT(m) \
45 STMT_START { \
46 *m = mutex_alloc(); \
47 if (*m) { \
48 mutex_init(*m); \
49 } else { \
50 croak("panic: MUTEX_INIT"); \
51 } \
52 } STMT_END
53
54#define MUTEX_LOCK(m) mutex_lock(*m)
55#define MUTEX_UNLOCK(m) mutex_unlock(*m)
56#define MUTEX_DESTROY(m) \
57 STMT_START { \
58 mutex_free(*m); \
59 *m = 0; \
60 } STMT_END
61
62#define COND_INIT(c) \
63 STMT_START { \
64 *c = condition_alloc(); \
65 if (*c) { \
66 condition_init(*c); \
67 } else { \
68 croak("panic: COND_INIT"); \
69 } \
70 } STMT_END
71
72#define COND_SIGNAL(c) condition_signal(*c)
73#define COND_BROADCAST(c) condition_broadcast(*c)
74#define COND_WAIT(c, m) condition_wait(*c, *m)
75#define COND_DESTROY(c) \
76 STMT_START { \
77 condition_free(*c); \
78 *c = 0; \
79 } STMT_END
80
81#define THREAD_CREATE(thr, f) (thr->self = cthread_fork(f, thr), 0)
82#define THREAD_POST_CREATE(thr)
83
84#define THREAD_RET_TYPE any_t
85#define THREAD_RET_CAST(x) ((any_t) x)
86
87#define DETACH(t) cthread_detach(t->self)
88#define JOIN(t, avp) (*(avp) = (AV *)cthread_join(t->self))
89
90#define SET_THR(thr) cthread_set_data(cthread_self(), thr)
91#define THR cthread_data(cthread_self())
92
93#define INIT_THREADS cthread_init()
94#define YIELD cthread_yield()
95#define ALLOC_THREAD_KEY
96#define SET_THREAD_SELF(thr) (thr->self = cthread_self())
97
98#endif /* I_MACH_CTHREADS */
99
ea0efc06 100#ifndef YIELD
6ee623d5 101# ifdef HAS_SCHED_YIELD
52e1cb5e 102# define YIELD sched_yield()
6ee623d5
GS
103# else
104# ifdef HAS_PTHREAD_YIELD
105# define YIELD pthread_yield()
106# endif
52e1cb5e 107# endif
ea0efc06
MB
108#endif
109
d9761d5f
JO
110#ifdef __hpux
111# define MUTEX_INIT_NEEDS_MUTEX_ZEROED
112#endif
113
ea0efc06 114#ifndef MUTEX_INIT
d9761d5f
JO
115#ifdef MUTEX_INIT_NEEDS_MUTEX_ZEROED
116 /* Temporary workaround, true bug is deeper. --jhi 1999-02-25 */
117#define MUTEX_INIT(m) \
118 STMT_START { \
119 Zero((m), 1, perl_mutex); \
120 if (pthread_mutex_init((m), pthread_mutexattr_default)) \
121 croak("panic: MUTEX_INIT"); \
122 } STMT_END
123#else
ea0efc06
MB
124#define MUTEX_INIT(m) \
125 STMT_START { \
126 if (pthread_mutex_init((m), pthread_mutexattr_default)) \
127 croak("panic: MUTEX_INIT"); \
128 } STMT_END
d9761d5f 129#endif
ea0efc06
MB
130#define MUTEX_LOCK(m) \
131 STMT_START { \
132 if (pthread_mutex_lock((m))) \
133 croak("panic: MUTEX_LOCK"); \
134 } STMT_END
135#define MUTEX_UNLOCK(m) \
136 STMT_START { \
137 if (pthread_mutex_unlock((m))) \
138 croak("panic: MUTEX_UNLOCK"); \
139 } STMT_END
140#define MUTEX_DESTROY(m) \
141 STMT_START { \
142 if (pthread_mutex_destroy((m))) \
143 croak("panic: MUTEX_DESTROY"); \
144 } STMT_END
145#endif /* MUTEX_INIT */
146
147#ifndef COND_INIT
148#define COND_INIT(c) \
149 STMT_START { \
150 if (pthread_cond_init((c), pthread_condattr_default)) \
151 croak("panic: COND_INIT"); \
152 } STMT_END
153#define COND_SIGNAL(c) \
154 STMT_START { \
155 if (pthread_cond_signal((c))) \
156 croak("panic: COND_SIGNAL"); \
157 } STMT_END
158#define COND_BROADCAST(c) \
159 STMT_START { \
160 if (pthread_cond_broadcast((c))) \
161 croak("panic: COND_BROADCAST"); \
162 } STMT_END
163#define COND_WAIT(c, m) \
164 STMT_START { \
165 if (pthread_cond_wait((c), (m))) \
166 croak("panic: COND_WAIT"); \
167 } STMT_END
168#define COND_DESTROY(c) \
169 STMT_START { \
170 if (pthread_cond_destroy((c))) \
171 croak("panic: COND_DESTROY"); \
172 } STMT_END
173#endif /* COND_INIT */
33f46ff6 174
f826a10b 175/* DETACH(t) must only be called while holding t->mutex */
ea0efc06
MB
176#ifndef DETACH
177#define DETACH(t) \
178 STMT_START { \
46930d8f 179 if (pthread_detach((t)->self)) { \
ea0efc06
MB
180 MUTEX_UNLOCK(&(t)->mutex); \
181 croak("panic: DETACH"); \
182 } \
183 } STMT_END
184#endif /* DETACH */
33f46ff6 185
ea0efc06
MB
186#ifndef JOIN
187#define JOIN(t, avp) \
188 STMT_START { \
46930d8f 189 if (pthread_join((t)->self, (void**)(avp))) \
ea0efc06
MB
190 croak("panic: pthread_join"); \
191 } STMT_END
192#endif /* JOIN */
193
194#ifndef SET_THR
195#define SET_THR(t) \
196 STMT_START { \
533c011a 197 if (pthread_setspecific(PL_thr_key, (void *) (t))) \
ea0efc06
MB
198 croak("panic: pthread_setspecific"); \
199 } STMT_END
200#endif /* SET_THR */
201
202#ifndef THR
203# ifdef OLD_PTHREADS_API
52e1cb5e 204struct perl_thread *getTHR _((void));
ea0efc06
MB
205# define THR getTHR()
206# else
533c011a 207# define THR ((struct perl_thread *) pthread_getspecific(PL_thr_key))
ea0efc06
MB
208# endif /* OLD_PTHREADS_API */
209#endif /* THR */
210
940cb80d
MB
211/*
212 * dTHR is performance-critical. Here, we only do the pthread_get_specific
213 * if there may be more than one thread in existence, otherwise we get thr
214 * from thrsv which is cached in the per-interpreter structure.
215 * Systems with very fast pthread_get_specific (which should be all systems
216 * but unfortunately isn't) may wish to simplify to "...*thr = THR".
36596149
GB
217 *
218 * The use of PL_threadnum should be safe here.
940cb80d 219 */
ea0efc06 220#ifndef dTHR
940cb80d 221# define dTHR \
533c011a 222 struct perl_thread *thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv)
ea0efc06 223#endif /* dTHR */
11343788 224
33f46ff6
MB
225#ifndef INIT_THREADS
226# ifdef NEED_PTHREAD_INIT
227# define INIT_THREADS pthread_init()
228# else
229# define INIT_THREADS NOOP
230# endif
231#endif
11343788 232
940cb80d
MB
233/* Accessor for per-thread SVs */
234#define THREADSV(i) (thr->threadsvp[i])
235
236/*
237 * LOCK_SV_MUTEX and UNLOCK_SV_MUTEX are performance-critical. Here, we
238 * try only locking them if there may be more than one thread in existence.
239 * Systems with very fast mutexes (and/or slow conditionals) may wish to
240 * remove the "if (threadnum) ..." test.
36596149 241 * XXX do NOT use C<if (PL_threadnum) ...> -- it sets up race conditions!
940cb80d 242 */
31e3abc2
GB
243#define LOCK_SV_MUTEX \
244 STMT_START { \
36596149 245 MUTEX_LOCK(&PL_sv_mutex); \
31e3abc2
GB
246 } STMT_END
247
248#define UNLOCK_SV_MUTEX \
249 STMT_START { \
36596149 250 MUTEX_UNLOCK(&PL_sv_mutex); \
940cb80d
MB
251 } STMT_END
252
31e3abc2
GB
253/* Likewise for strtab_mutex */
254#define LOCK_STRTAB_MUTEX \
255 STMT_START { \
36596149 256 MUTEX_LOCK(&PL_strtab_mutex); \
31e3abc2
GB
257 } STMT_END
258
259#define UNLOCK_STRTAB_MUTEX \
260 STMT_START { \
36596149 261 MUTEX_UNLOCK(&PL_strtab_mutex); \
940cb80d 262 } STMT_END
d55594ae 263
ea0efc06
MB
264#ifndef THREAD_RET_TYPE
265# define THREAD_RET_TYPE void *
266# define THREAD_RET_CAST(p) ((void *)(p))
267#endif /* THREAD_RET */
268
11343788 269
33f46ff6 270/* Values and macros for thr->flags */
605e5515
MB
271#define THRf_STATE_MASK 7
272#define THRf_R_JOINABLE 0
273#define THRf_R_JOINED 1
274#define THRf_R_DETACHED 2
275#define THRf_ZOMBIE 3
276#define THRf_DEAD 4
f93b4edd 277
458fb581 278#define THRf_DID_DIE 8
07b73707 279
f826a10b 280/* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
458fb581 281#define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
f93b4edd 282#define ThrSETSTATE(t, s) STMT_START { \
605e5515 283 (t)->flags &= ~THRf_STATE_MASK; \
33f46ff6 284 (t)->flags |= (s); \
8b73bbec 285 DEBUG_S(PerlIO_printf(PerlIO_stderr(), \
605e5515 286 "thread %p set to state %d\n", (t), (s))); \
f93b4edd
MB
287 } STMT_END
288
289typedef struct condpair {
f826a10b
MB
290 perl_mutex mutex; /* Protects all other fields */
291 perl_cond owner_cond; /* For when owner changes at all */
292 perl_cond cond; /* For cond_signal and cond_broadcast */
293 Thread owner; /* Currently owning thread */
f93b4edd
MB
294} condpair_t;
295
296#define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
297#define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
298#define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
299#define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
300
ea0efc06
MB
301#else
302/* USE_THREADS is not defined */
303#define MUTEX_LOCK(m)
304#define MUTEX_UNLOCK(m)
305#define MUTEX_INIT(m)
306#define MUTEX_DESTROY(m)
307#define COND_INIT(c)
308#define COND_SIGNAL(c)
309#define COND_BROADCAST(c)
310#define COND_WAIT(c, m)
311#define COND_DESTROY(c)
93bce2dc
GS
312#define LOCK_SV_MUTEX
313#define UNLOCK_SV_MUTEX
31e3abc2
GB
314#define LOCK_STRTAB_MUTEX
315#define UNLOCK_STRTAB_MUTEX
ea0efc06
MB
316
317#define THR
318/* Rats: if dTHR is just blank then the subsequent ";" throws an error */
76e3520e 319#ifdef WIN32
e3b8966e 320#define dTHR extern int Perl___notused
76e3520e 321#else
ea0efc06 322#define dTHR extern int errno
76e3520e 323#endif
11343788 324#endif /* USE_THREADS */