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