This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Two more delays added to test suite to help *-solaris-thread.
[perl5.git] / thread.h
... / ...
CommitLineData
1#ifdef USE_THREADS
2
3#ifdef WIN32
4# include <win32thread.h>
5#else
6
7/* POSIXish threads */
8typedef pthread_t perl_thread;
9#ifdef OLD_PTHREADS_API
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 { \
16 if (pthread_detach(&(t)->self)) { \
17 MUTEX_UNLOCK(&(t)->mutex); \
18 croak("panic: DETACH"); \
19 } \
20 } STMT_END
21#else
22# define pthread_mutexattr_default NULL
23# define pthread_condattr_default NULL
24# define pthread_attr_default NULL
25#endif /* OLD_PTHREADS_API */
26#endif
27
28#ifndef YIELD
29# define YIELD sched_yield()
30#endif
31
32#ifndef MUTEX_INIT
33#define MUTEX_INIT(m) \
34 STMT_START { \
35 if (pthread_mutex_init((m), pthread_mutexattr_default)) \
36 croak("panic: MUTEX_INIT"); \
37 } STMT_END
38#define MUTEX_LOCK(m) \
39 STMT_START { \
40 if (pthread_mutex_lock((m))) \
41 croak("panic: MUTEX_LOCK"); \
42 } STMT_END
43#define MUTEX_UNLOCK(m) \
44 STMT_START { \
45 if (pthread_mutex_unlock((m))) \
46 croak("panic: MUTEX_UNLOCK"); \
47 } STMT_END
48#define MUTEX_DESTROY(m) \
49 STMT_START { \
50 if (pthread_mutex_destroy((m))) \
51 croak("panic: MUTEX_DESTROY"); \
52 } STMT_END
53#endif /* MUTEX_INIT */
54
55#ifndef COND_INIT
56#define COND_INIT(c) \
57 STMT_START { \
58 if (pthread_cond_init((c), pthread_condattr_default)) \
59 croak("panic: COND_INIT"); \
60 } STMT_END
61#define COND_SIGNAL(c) \
62 STMT_START { \
63 if (pthread_cond_signal((c))) \
64 croak("panic: COND_SIGNAL"); \
65 } STMT_END
66#define COND_BROADCAST(c) \
67 STMT_START { \
68 if (pthread_cond_broadcast((c))) \
69 croak("panic: COND_BROADCAST"); \
70 } STMT_END
71#define COND_WAIT(c, m) \
72 STMT_START { \
73 if (pthread_cond_wait((c), (m))) \
74 croak("panic: COND_WAIT"); \
75 } STMT_END
76#define COND_DESTROY(c) \
77 STMT_START { \
78 if (pthread_cond_destroy((c))) \
79 croak("panic: COND_DESTROY"); \
80 } STMT_END
81#endif /* COND_INIT */
82
83/* DETACH(t) must only be called while holding t->mutex */
84#ifndef DETACH
85#define DETACH(t) \
86 STMT_START { \
87 if (pthread_detach((t)->self)) { \
88 MUTEX_UNLOCK(&(t)->mutex); \
89 croak("panic: DETACH"); \
90 } \
91 } STMT_END
92#endif /* DETACH */
93
94#ifndef JOIN
95#define JOIN(t, avp) \
96 STMT_START { \
97 if (pthread_join((t)->self, (void**)(avp))) \
98 croak("panic: pthread_join"); \
99 } STMT_END
100#endif /* JOIN */
101
102#ifndef SET_THR
103#define SET_THR(t) \
104 STMT_START { \
105 if (pthread_setspecific(thr_key, (void *) (t))) \
106 croak("panic: pthread_setspecific"); \
107 } STMT_END
108#endif /* SET_THR */
109
110#ifndef THR
111# ifdef OLD_PTHREADS_API
112struct thread *getTHR _((void));
113# define THR getTHR()
114# else
115# define THR ((struct thread *) pthread_getspecific(thr_key))
116# endif /* OLD_PTHREADS_API */
117#endif /* THR */
118
119#ifndef dTHR
120# define dTHR struct thread *thr = THR
121#endif /* dTHR */
122
123#ifndef INIT_THREADS
124# ifdef NEED_PTHREAD_INIT
125# define INIT_THREADS pthread_init()
126# else
127# define INIT_THREADS NOOP
128# endif
129#endif
130
131
132#ifndef THREAD_RET_TYPE
133# define THREAD_RET_TYPE void *
134# define THREAD_RET_CAST(p) ((void *)(p))
135#endif /* THREAD_RET */
136
137struct thread {
138 /* The fields that used to be global */
139 /* Important ones in the first cache line (if alignment is done right) */
140 SV ** Tstack_sp;
141#ifdef OP_IN_REGISTER
142 OP * Topsave;
143#else
144 OP * Top;
145#endif
146 SV ** Tcurpad;
147 SV ** Tstack_base;
148
149 SV ** Tstack_max;
150
151 I32 * Tscopestack;
152 I32 Tscopestack_ix;
153 I32 Tscopestack_max;
154
155 ANY * Tsavestack;
156 I32 Tsavestack_ix;
157 I32 Tsavestack_max;
158
159 OP ** Tretstack;
160 I32 Tretstack_ix;
161 I32 Tretstack_max;
162
163 I32 * Tmarkstack;
164 I32 * Tmarkstack_ptr;
165 I32 * Tmarkstack_max;
166
167 SV * TSv;
168 XPV * TXpv;
169 struct stat Tstatbuf;
170 struct tms Ttimesbuf;
171
172 /* XXX What about regexp stuff? */
173
174 /* Now the fields that used to be "per interpreter" (even when global) */
175
176 /* Fields used by magic variables such as $@, $/ and so on */
177 bool Ttainted;
178 PMOP * Tcurpm;
179 SV * Tnrs;
180 SV * Trs;
181 GV * Tlast_in_gv;
182 char * Tofs;
183 STRLEN Tofslen;
184 GV * Tdefoutgv;
185 char * Tchopset;
186 SV * Tformtarget;
187 SV * Tbodytarget;
188 SV * Ttoptarget;
189
190 /* Stashes */
191 HV * Tdefstash;
192 HV * Tcurstash;
193
194 /* Stacks */
195 SV ** Ttmps_stack;
196 I32 Ttmps_ix;
197 I32 Ttmps_floor;
198 I32 Ttmps_max;
199
200 int Tin_eval;
201 OP * Trestartop;
202 int Tdelaymagic;
203 bool Tdirty;
204 U8 Tlocalizing;
205 COP * Tcurcop;
206
207 PERL_CONTEXT * Tcxstack;
208 I32 Tcxstack_ix;
209 I32 Tcxstack_max;
210
211 AV * Tcurstack;
212 AV * Tmainstack;
213 JMPENV * Ttop_env;
214 I32 Trunlevel;
215
216 /* XXX Sort stuff, firstgv, secongv and so on? */
217
218 SV * oursv;
219 HV * cvcache;
220 perl_thread self; /* Underlying thread object */
221 U32 flags;
222 AV * magicals; /* Per-thread magicals */
223 AV * specific; /* Thread-specific user data */
224 SV * errsv; /* Backing SV for $@ */
225 HV * errhv; /* HV for what was %@ in pp_ctl.c */
226 perl_mutex mutex; /* For the fields others can change */
227 U32 tid;
228 struct thread *next, *prev; /* Circular linked list of threads */
229 JMPENV Tstart_env; /* Top of top_env longjmp() chain */
230#ifdef HAVE_THREAD_INTERN
231 struct thread_intern i; /* Platform-dependent internals */
232#endif
233 char trailing_nul; /* For the sake of thrsv and oursv */
234};
235
236typedef struct thread *Thread;
237
238/* Values and macros for thr->flags */
239#define THRf_STATE_MASK 7
240#define THRf_R_JOINABLE 0
241#define THRf_R_JOINED 1
242#define THRf_R_DETACHED 2
243#define THRf_ZOMBIE 3
244#define THRf_DEAD 4
245
246#define THRf_DID_DIE 8
247
248/* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
249#define ThrSTATE(t) ((t)->flags & THRf_STATE_MASK)
250#define ThrSETSTATE(t, s) STMT_START { \
251 (t)->flags &= ~THRf_STATE_MASK; \
252 (t)->flags |= (s); \
253 DEBUG_L(PerlIO_printf(PerlIO_stderr(), \
254 "thread %p set to state %d\n", (t), (s))); \
255 } STMT_END
256
257typedef struct condpair {
258 perl_mutex mutex; /* Protects all other fields */
259 perl_cond owner_cond; /* For when owner changes at all */
260 perl_cond cond; /* For cond_signal and cond_broadcast */
261 Thread owner; /* Currently owning thread */
262} condpair_t;
263
264#define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
265#define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
266#define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
267#define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
268
269#undef stack_base
270#undef stack_sp
271#undef stack_max
272#undef curstack
273#undef mainstack
274#undef markstack
275#undef markstack_ptr
276#undef markstack_max
277#undef scopestack
278#undef scopestack_ix
279#undef scopestack_max
280#undef savestack
281#undef savestack_ix
282#undef savestack_max
283#undef retstack
284#undef retstack_ix
285#undef retstack_max
286#undef curcop
287#undef cxstack
288#undef cxstack_ix
289#undef cxstack_max
290#undef defstash
291#undef curstash
292#undef tmps_stack
293#undef tmps_floor
294#undef tmps_ix
295#undef tmps_max
296#undef curpad
297#undef Sv
298#undef Xpv
299#undef statbuf
300#undef timesbuf
301#undef tainted
302#undef curpm
303#undef nrs
304#undef rs
305#undef last_in_gv
306#undef ofs
307#undef ofslen
308#undef defoutgv
309#undef chopset
310#undef formtarget
311#undef bodytarget
312#undef toptarget
313#undef top_env
314#undef runlevel
315#undef in_eval
316#undef restartop
317#undef delaymagic
318#undef dirty
319#undef localizing
320
321#define stack_base (thr->Tstack_base)
322#define stack_sp (thr->Tstack_sp)
323#define stack_max (thr->Tstack_max)
324#ifdef OP_IN_REGISTER
325#define opsave (thr->Topsave)
326#else
327#undef op
328#define op (thr->Top)
329#endif
330#define curcop (thr->Tcurcop)
331#define stack (thr->Tstack)
332#define curstack (thr->Tcurstack)
333#define mainstack (thr->Tmainstack)
334#define markstack (thr->Tmarkstack)
335#define markstack_ptr (thr->Tmarkstack_ptr)
336#define markstack_max (thr->Tmarkstack_max)
337#define scopestack (thr->Tscopestack)
338#define scopestack_ix (thr->Tscopestack_ix)
339#define scopestack_max (thr->Tscopestack_max)
340
341#define savestack (thr->Tsavestack)
342#define savestack_ix (thr->Tsavestack_ix)
343#define savestack_max (thr->Tsavestack_max)
344
345#define retstack (thr->Tretstack)
346#define retstack_ix (thr->Tretstack_ix)
347#define retstack_max (thr->Tretstack_max)
348
349#define cxstack (thr->Tcxstack)
350#define cxstack_ix (thr->Tcxstack_ix)
351#define cxstack_max (thr->Tcxstack_max)
352
353#define curpad (thr->Tcurpad)
354#define Sv (thr->TSv)
355#define Xpv (thr->TXpv)
356#define statbuf (thr->Tstatbuf)
357#define timesbuf (thr->Ttimesbuf)
358#define tainted (thr->Ttainted)
359#define tainted (thr->Ttainted)
360#define curpm (thr->Tcurpm)
361#define nrs (thr->Tnrs)
362#define rs (thr->Trs)
363#define last_in_gv (thr->Tlast_in_gv)
364#define ofs (thr->Tofs)
365#define ofslen (thr->Tofslen)
366#define defoutgv (thr->Tdefoutgv)
367#define chopset (thr->Tchopset)
368#define formtarget (thr->Tformtarget)
369#define bodytarget (thr->Tbodytarget)
370#define toptarget (thr->Ttoptarget)
371#define defstash (thr->Tdefstash)
372#define curstash (thr->Tcurstash)
373
374#define tmps_stack (thr->Ttmps_stack)
375#define tmps_ix (thr->Ttmps_ix)
376#define tmps_floor (thr->Ttmps_floor)
377#define tmps_max (thr->Ttmps_max)
378
379#define in_eval (thr->Tin_eval)
380#define restartop (thr->Trestartop)
381#define delaymagic (thr->Tdelaymagic)
382#define dirty (thr->Tdirty)
383#define localizing (thr->Tlocalizing)
384
385#define top_env (thr->Ttop_env)
386#define runlevel (thr->Trunlevel)
387#define start_env (thr->Tstart_env)
388
389#else
390/* USE_THREADS is not defined */
391#define MUTEX_LOCK(m)
392#define MUTEX_UNLOCK(m)
393#define MUTEX_INIT(m)
394#define MUTEX_DESTROY(m)
395#define COND_INIT(c)
396#define COND_SIGNAL(c)
397#define COND_BROADCAST(c)
398#define COND_WAIT(c, m)
399#define COND_DESTROY(c)
400
401#define THR
402/* Rats: if dTHR is just blank then the subsequent ";" throws an error */
403#define dTHR extern int errno
404#endif /* USE_THREADS */