Reverse integrate Malcolm's chanes into local
[p5sagit/p5-mst-13.2.git] / thread.h
CommitLineData
ea0efc06 1#ifdef USE_THREADS
12ca11f6 2
ea0efc06 3#ifdef WIN32
f0f333f4 4# include <win32thread.h>
5#else
12ca11f6 6
12ca11f6 7/* POSIXish threads */
8typedef pthread_t perl_thread;
11343788 9#ifdef OLD_PTHREADS_API
ea0efc06 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 17 MUTEX_UNLOCK(&(t)->mutex); \
18 croak("panic: DETACH"); \
19 } \
20 } STMT_END
11343788 21#else
ea0efc06 22# define pthread_mutexattr_default NULL
23# define pthread_condattr_default NULL
24# define pthread_attr_default NULL
11343788 25#endif /* OLD_PTHREADS_API */
f0f333f4 26#endif
11343788 27
ea0efc06 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 */
33f46ff6 82
f826a10b 83/* DETACH(t) must only be called while holding t->mutex */
ea0efc06 84#ifndef DETACH
85#define DETACH(t) \
86 STMT_START { \
46930d8f 87 if (pthread_detach((t)->self)) { \
ea0efc06 88 MUTEX_UNLOCK(&(t)->mutex); \
89 croak("panic: DETACH"); \
90 } \
91 } STMT_END
92#endif /* DETACH */
33f46ff6 93
ea0efc06 94#ifndef JOIN
95#define JOIN(t, avp) \
96 STMT_START { \
46930d8f 97 if (pthread_join((t)->self, (void**)(avp))) \
ea0efc06 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
11343788 112struct thread *getTHR _((void));
ea0efc06 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 */
11343788 122
33f46ff6 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
11343788 130
ea0efc06 131#ifndef THREAD_RET_TYPE
132# define THREAD_RET_TYPE void *
133# define THREAD_RET_CAST(p) ((void *)(p))
134#endif /* THREAD_RET */
135
33f46ff6 136struct thread {
11343788 137 /* The fields that used to be global */
33f46ff6 138 /* Important ones in the first cache line (if alignment is done right) */
11343788 139 SV ** Tstack_sp;
462e5cf6 140#ifdef OP_IN_REGISTER
141 OP * Topsave;
142#else
11343788 143 OP * Top;
462e5cf6 144#endif
33f46ff6 145 SV ** Tcurpad;
146 SV ** Tstack_base;
147
148 SV ** Tstack_max;
11343788 149
150 I32 * Tscopestack;
151 I32 Tscopestack_ix;
152 I32 Tscopestack_max;
153
154 ANY * Tsavestack;
155 I32 Tsavestack_ix;
156 I32 Tsavestack_max;
157
158 OP ** Tretstack;
159 I32 Tretstack_ix;
160 I32 Tretstack_max;
161
162 I32 * Tmarkstack;
163 I32 * Tmarkstack_ptr;
164 I32 * Tmarkstack_max;
165
11343788 166 SV * TSv;
167 XPV * TXpv;
11343788 168 struct stat Tstatbuf;
169 struct tms Ttimesbuf;
170
171 /* XXX What about regexp stuff? */
172
173 /* Now the fields that used to be "per interpreter" (even when global) */
174
aeea060c 175 /* Fields used by magic variables such as $@, $/ and so on */
176 bool Ttainted;
177 PMOP * Tcurpm;
178 SV * Tnrs;
179 SV * Trs;
180 GV * Tlast_in_gv;
181 char * Tofs;
182 STRLEN Tofslen;
183 GV * Tdefoutgv;
184 char * Tchopset;
185 SV * Tformtarget;
186 SV * Tbodytarget;
187 SV * Ttoptarget;
188
189 /* Stashes */
11343788 190 HV * Tdefstash;
191 HV * Tcurstash;
11343788 192
aeea060c 193 /* Stacks */
11343788 194 SV ** Ttmps_stack;
195 I32 Ttmps_ix;
196 I32 Ttmps_floor;
197 I32 Ttmps_max;
198
199 int Tin_eval;
200 OP * Trestartop;
201 int Tdelaymagic;
202 bool Tdirty;
203 U8 Tlocalizing;
0f15f207 204 COP * Tcurcop;
11343788 205
206 CONTEXT * Tcxstack;
207 I32 Tcxstack_ix;
208 I32 Tcxstack_max;
209
0f15f207 210 AV * Tcurstack;
11343788 211 AV * Tmainstack;
e858de61 212 JMPENV * Ttop_env;
11343788 213 I32 Trunlevel;
214
215 /* XXX Sort stuff, firstgv, secongv and so on? */
216
199100c8 217 SV * oursv;
218 HV * cvcache;
46930d8f 219 perl_thread self; /* Underlying thread object */
33f46ff6 220 U32 flags;
554b3eca 221 AV * magicals; /* Per-thread magicals */
222 AV * specific; /* Thread-specific user data */
f826a10b 223 perl_mutex mutex; /* For the fields others can change */
33f46ff6 224 U32 tid;
225 struct thread *next, *prev; /* Circular linked list of threads */
12ca11f6 226
f826a10b 227#ifdef ADD_THREAD_INTERN
228 struct thread_intern i; /* Platform-dependent internals */
229#endif
199100c8 230 char trailing_nul; /* For the sake of thrsv and oursv */
11343788 231};
232
233typedef struct thread *Thread;
234
33f46ff6 235/* Values and macros for thr->flags */
605e5515 236#define THRf_STATE_MASK 7
237#define THRf_R_JOINABLE 0
238#define THRf_R_JOINED 1
239#define THRf_R_DETACHED 2
240#define THRf_ZOMBIE 3
241#define THRf_DEAD 4
f93b4edd 242
605e5515 243#define THRf_DIE_FATAL 8
07b73707 244
f826a10b 245/* ThrSTATE(t) and ThrSETSTATE(t) must only be called while holding t->mutex */
605e5515 246#define ThrSTATE(t) ((t)->flags)
f93b4edd 247#define ThrSETSTATE(t, s) STMT_START { \
605e5515 248 (t)->flags &= ~THRf_STATE_MASK; \
33f46ff6 249 (t)->flags |= (s); \
605e5515 250 DEBUG_L(PerlIO_printf(PerlIO_stderr(), \
251 "thread %p set to state %d\n", (t), (s))); \
f93b4edd 252 } STMT_END
253
254typedef struct condpair {
f826a10b 255 perl_mutex mutex; /* Protects all other fields */
256 perl_cond owner_cond; /* For when owner changes at all */
257 perl_cond cond; /* For cond_signal and cond_broadcast */
258 Thread owner; /* Currently owning thread */
f93b4edd 259} condpair_t;
260
261#define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex)
262#define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond)
263#define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond)
264#define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner
265
11343788 266#undef stack_base
267#undef stack_sp
268#undef stack_max
0f15f207 269#undef curstack
11343788 270#undef mainstack
271#undef markstack
272#undef markstack_ptr
273#undef markstack_max
274#undef scopestack
275#undef scopestack_ix
276#undef scopestack_max
277#undef savestack
278#undef savestack_ix
279#undef savestack_max
280#undef retstack
281#undef retstack_ix
282#undef retstack_max
0f15f207 283#undef curcop
11343788 284#undef cxstack
285#undef cxstack_ix
286#undef cxstack_max
809a5acc 287#undef defstash
288#undef curstash
6d4ff0d2 289#undef tmps_stack
290#undef tmps_floor
291#undef tmps_ix
292#undef tmps_max
11343788 293#undef curpad
294#undef Sv
295#undef Xpv
96827780 296#undef statbuf
297#undef timesbuf
aeea060c 298#undef tainted
299#undef curpm
300#undef nrs
301#undef rs
302#undef last_in_gv
303#undef ofs
304#undef ofslen
305#undef defoutgv
306#undef chopset
307#undef formtarget
308#undef bodytarget
309#undef toptarget
11343788 310#undef top_env
311#undef runlevel
312#undef in_eval
809a5acc 313#undef restartop
314#undef delaymagic
315#undef dirty
316#undef localizing
11343788 317
11343788 318#define stack_base (thr->Tstack_base)
319#define stack_sp (thr->Tstack_sp)
320#define stack_max (thr->Tstack_max)
462e5cf6 321#ifdef OP_IN_REGISTER
322#define opsave (thr->Topsave)
323#else
324#undef op
11343788 325#define op (thr->Top)
462e5cf6 326#endif
0f15f207 327#define curcop (thr->Tcurcop)
11343788 328#define stack (thr->Tstack)
809a5acc 329#define curstack (thr->Tcurstack)
11343788 330#define mainstack (thr->Tmainstack)
331#define markstack (thr->Tmarkstack)
332#define markstack_ptr (thr->Tmarkstack_ptr)
333#define markstack_max (thr->Tmarkstack_max)
334#define scopestack (thr->Tscopestack)
335#define scopestack_ix (thr->Tscopestack_ix)
336#define scopestack_max (thr->Tscopestack_max)
337
338#define savestack (thr->Tsavestack)
339#define savestack_ix (thr->Tsavestack_ix)
340#define savestack_max (thr->Tsavestack_max)
341
342#define retstack (thr->Tretstack)
343#define retstack_ix (thr->Tretstack_ix)
344#define retstack_max (thr->Tretstack_max)
345
346#define cxstack (thr->Tcxstack)
347#define cxstack_ix (thr->Tcxstack_ix)
348#define cxstack_max (thr->Tcxstack_max)
349
350#define curpad (thr->Tcurpad)
351#define Sv (thr->TSv)
352#define Xpv (thr->TXpv)
96827780 353#define statbuf (thr->Tstatbuf)
354#define timesbuf (thr->Ttimesbuf)
aeea060c 355#define tainted (thr->Ttainted)
356#define tainted (thr->Ttainted)
357#define curpm (thr->Tcurpm)
358#define nrs (thr->Tnrs)
359#define rs (thr->Trs)
360#define last_in_gv (thr->Tlast_in_gv)
361#define ofs (thr->Tofs)
362#define ofslen (thr->Tofslen)
363#define defoutgv (thr->Tdefoutgv)
364#define chopset (thr->Tchopset)
365#define formtarget (thr->Tformtarget)
366#define bodytarget (thr->Tbodytarget)
367#define toptarget (thr->Ttoptarget)
11343788 368#define defstash (thr->Tdefstash)
369#define curstash (thr->Tcurstash)
11343788 370
371#define tmps_stack (thr->Ttmps_stack)
372#define tmps_ix (thr->Ttmps_ix)
373#define tmps_floor (thr->Ttmps_floor)
374#define tmps_max (thr->Ttmps_max)
375
376#define in_eval (thr->Tin_eval)
377#define restartop (thr->Trestartop)
378#define delaymagic (thr->Tdelaymagic)
379#define dirty (thr->Tdirty)
380#define localizing (thr->Tlocalizing)
381
382#define top_env (thr->Ttop_env)
383#define runlevel (thr->Trunlevel)
384
ea0efc06 385#else
386/* USE_THREADS is not defined */
387#define MUTEX_LOCK(m)
388#define MUTEX_UNLOCK(m)
389#define MUTEX_INIT(m)
390#define MUTEX_DESTROY(m)
391#define COND_INIT(c)
392#define COND_SIGNAL(c)
393#define COND_BROADCAST(c)
394#define COND_WAIT(c, m)
395#define COND_DESTROY(c)
396
397#define THR
398/* Rats: if dTHR is just blank then the subsequent ";" throws an error */
399#define dTHR extern int errno
11343788 400#endif /* USE_THREADS */