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