Commit | Line | Data |
11343788 |
1 | #ifndef USE_THREADS |
2 | #define MUTEX_LOCK(m) |
3 | #define MUTEX_UNLOCK(m) |
4 | #define MUTEX_INIT(m) |
5 | #define MUTEX_DESTROY(m) |
6 | #define COND_INIT(c) |
7 | #define COND_SIGNAL(c) |
8 | #define COND_BROADCAST(c) |
9 | #define COND_WAIT(c, m) |
10 | #define COND_DESTROY(c) |
11 | |
12 | #define THR |
13 | /* Rats: if dTHR is just blank then the subsequent ";" throws an error */ |
14 | #define dTHR extern int errno |
15 | #else |
11343788 |
16 | |
12ca11f6 |
17 | #ifdef FAKE_THREADS |
18 | typedef struct thread *perl_thread; |
19 | /* With fake threads, thr is global(ish) so we don't need dTHR */ |
20 | #define dTHR extern int errno |
21 | |
22 | /* |
23 | * Note that SCHEDULE() is only callable from pp code (which |
24 | * must be expecting to be restarted). We'll have to do |
25 | * something a bit different for XS code. |
26 | */ |
27 | #define SCHEDULE() return schedule(), op |
28 | |
29 | #define MUTEX_LOCK(m) |
30 | #define MUTEX_UNLOCK(m) |
31 | #define MUTEX_INIT(m) |
32 | #define MUTEX_DESTROY(m) |
33 | #define COND_INIT(c) perl_cond_init(c) |
34 | #define COND_SIGNAL(c) perl_cond_signal(c) |
35 | #define COND_BROADCAST(c) perl_cond_broadcast(c) |
36 | #define COND_WAIT(c, m) STMT_START { \ |
37 | perl_cond_wait(c); \ |
38 | SCHEDULE(); \ |
39 | } STMT_END |
40 | #define COND_DESTROY(c) |
12ca11f6 |
41 | #else |
42 | /* POSIXish threads */ |
43 | typedef pthread_t perl_thread; |
11343788 |
44 | #ifdef OLD_PTHREADS_API |
45 | #define pthread_mutexattr_init(a) pthread_mutexattr_create(a) |
46 | #define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t) |
47 | #define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d)) |
48 | #else |
49 | #define pthread_mutexattr_default NULL |
b851de6c |
50 | #define pthread_condattr_default NULL |
11343788 |
51 | #endif /* OLD_PTHREADS_API */ |
52 | |
53 | #define MUTEX_INIT(m) \ |
54 | if (pthread_mutex_init((m), pthread_mutexattr_default)) \ |
55 | croak("panic: MUTEX_INIT"); \ |
56 | else 1 |
57 | #define MUTEX_LOCK(m) \ |
58 | if (pthread_mutex_lock((m))) croak("panic: MUTEX_LOCK"); else 1 |
59 | #define MUTEX_UNLOCK(m) \ |
60 | if (pthread_mutex_unlock((m))) croak("panic: MUTEX_UNLOCK"); else 1 |
61 | #define MUTEX_DESTROY(m) \ |
62 | if (pthread_mutex_destroy((m))) croak("panic: MUTEX_DESTROY"); else 1 |
63 | #define COND_INIT(c) \ |
b851de6c |
64 | if (pthread_cond_init((c), pthread_condattr_default)) \ |
65 | croak("panic: COND_INIT"); \ |
66 | else 1 |
11343788 |
67 | #define COND_SIGNAL(c) \ |
68 | if (pthread_cond_signal((c))) croak("panic: COND_SIGNAL"); else 1 |
69 | #define COND_BROADCAST(c) \ |
70 | if (pthread_cond_broadcast((c))) croak("panic: COND_BROADCAST"); else 1 |
71 | #define COND_WAIT(c, m) \ |
72 | if (pthread_cond_wait((c), (m))) croak("panic: COND_WAIT"); else 1 |
73 | #define COND_DESTROY(c) \ |
74 | if (pthread_cond_destroy((c))) croak("panic: COND_DESTROY"); else 1 |
33f46ff6 |
75 | |
76 | #define DETACH(t) \ |
77 | if (pthread_detach((t)->Tself)) croak("panic: DETACH"); else 1 |
78 | |
11343788 |
79 | /* XXX Add "old" (?) POSIX draft interface too */ |
80 | #ifdef OLD_PTHREADS_API |
81 | struct thread *getTHR _((void)); |
82 | #define THR getTHR() |
83 | #else |
84 | #define THR ((struct thread *) pthread_getspecific(thr_key)) |
85 | #endif /* OLD_PTHREADS_API */ |
86 | #define dTHR struct thread *thr = THR |
12ca11f6 |
87 | #endif /* FAKE_THREADS */ |
11343788 |
88 | |
33f46ff6 |
89 | #ifndef INIT_THREADS |
90 | # ifdef NEED_PTHREAD_INIT |
91 | # define INIT_THREADS pthread_init() |
92 | # else |
93 | # define INIT_THREADS NOOP |
94 | # endif |
95 | #endif |
11343788 |
96 | |
33f46ff6 |
97 | struct thread { |
11343788 |
98 | /* The fields that used to be global */ |
33f46ff6 |
99 | /* Important ones in the first cache line (if alignment is done right) */ |
11343788 |
100 | SV ** Tstack_sp; |
462e5cf6 |
101 | #ifdef OP_IN_REGISTER |
102 | OP * Topsave; |
103 | #else |
11343788 |
104 | OP * Top; |
462e5cf6 |
105 | #endif |
33f46ff6 |
106 | SV ** Tcurpad; |
107 | SV ** Tstack_base; |
108 | |
109 | SV ** Tstack_max; |
11343788 |
110 | |
111 | I32 * Tscopestack; |
112 | I32 Tscopestack_ix; |
113 | I32 Tscopestack_max; |
114 | |
115 | ANY * Tsavestack; |
116 | I32 Tsavestack_ix; |
117 | I32 Tsavestack_max; |
118 | |
119 | OP ** Tretstack; |
120 | I32 Tretstack_ix; |
121 | I32 Tretstack_max; |
122 | |
123 | I32 * Tmarkstack; |
124 | I32 * Tmarkstack_ptr; |
125 | I32 * Tmarkstack_max; |
126 | |
11343788 |
127 | SV * TSv; |
128 | XPV * TXpv; |
11343788 |
129 | struct stat Tstatbuf; |
130 | struct tms Ttimesbuf; |
131 | |
132 | /* XXX What about regexp stuff? */ |
133 | |
134 | /* Now the fields that used to be "per interpreter" (even when global) */ |
135 | |
136 | /* XXX What about magic variables such as $/, $? and so on? */ |
137 | HV * Tdefstash; |
138 | HV * Tcurstash; |
11343788 |
139 | |
140 | SV ** Ttmps_stack; |
141 | I32 Ttmps_ix; |
142 | I32 Ttmps_floor; |
143 | I32 Ttmps_max; |
144 | |
145 | int Tin_eval; |
146 | OP * Trestartop; |
147 | int Tdelaymagic; |
148 | bool Tdirty; |
149 | U8 Tlocalizing; |
0f15f207 |
150 | COP * Tcurcop; |
11343788 |
151 | |
152 | CONTEXT * Tcxstack; |
153 | I32 Tcxstack_ix; |
154 | I32 Tcxstack_max; |
155 | |
0f15f207 |
156 | AV * Tcurstack; |
11343788 |
157 | AV * Tmainstack; |
e858de61 |
158 | JMPENV * Ttop_env; |
11343788 |
159 | I32 Trunlevel; |
160 | |
161 | /* XXX Sort stuff, firstgv, secongv and so on? */ |
162 | |
33f46ff6 |
163 | perl_thread Tself; |
164 | SV * Toursv; |
11343788 |
165 | HV * Tcvcache; |
33f46ff6 |
166 | U32 flags; |
605e5515 |
167 | perl_mutex mutex; |
33f46ff6 |
168 | U32 tid; |
169 | struct thread *next, *prev; /* Circular linked list of threads */ |
12ca11f6 |
170 | |
171 | #ifdef FAKE_THREADS |
12ca11f6 |
172 | perl_thread next_run, prev_run; /* Linked list of runnable threads */ |
173 | perl_cond wait_queue; /* Wait queue that we are waiting on */ |
174 | IV private; /* Holds data across time slices */ |
0f15f207 |
175 | I32 savemark; /* Holds MARK for thread join values */ |
12ca11f6 |
176 | #endif /* FAKE_THREADS */ |
11343788 |
177 | }; |
178 | |
179 | typedef struct thread *Thread; |
180 | |
33f46ff6 |
181 | /* Values and macros for thr->flags */ |
605e5515 |
182 | #define THRf_STATE_MASK 7 |
183 | #define THRf_R_JOINABLE 0 |
184 | #define THRf_R_JOINED 1 |
185 | #define THRf_R_DETACHED 2 |
186 | #define THRf_ZOMBIE 3 |
187 | #define THRf_DEAD 4 |
f93b4edd |
188 | |
605e5515 |
189 | #define THRf_DIE_FATAL 8 |
07b73707 |
190 | |
605e5515 |
191 | #define ThrSTATE(t) ((t)->flags) |
f93b4edd |
192 | #define ThrSETSTATE(t, s) STMT_START { \ |
605e5515 |
193 | MUTEX_LOCK(&(t)->mutex); \ |
194 | (t)->flags &= ~THRf_STATE_MASK; \ |
33f46ff6 |
195 | (t)->flags |= (s); \ |
605e5515 |
196 | MUTEX_UNLOCK(&(t)->mutex); \ |
197 | DEBUG_L(PerlIO_printf(PerlIO_stderr(), \ |
198 | "thread %p set to state %d\n", (t), (s))); \ |
f93b4edd |
199 | } STMT_END |
200 | |
201 | typedef struct condpair { |
12ca11f6 |
202 | perl_mutex mutex; |
203 | perl_cond owner_cond; |
204 | perl_cond cond; |
205 | Thread owner; |
f93b4edd |
206 | } condpair_t; |
207 | |
208 | #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex) |
209 | #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond) |
210 | #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond) |
211 | #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner |
212 | |
11343788 |
213 | #undef stack_base |
214 | #undef stack_sp |
215 | #undef stack_max |
0f15f207 |
216 | #undef curstack |
11343788 |
217 | #undef mainstack |
218 | #undef markstack |
219 | #undef markstack_ptr |
220 | #undef markstack_max |
221 | #undef scopestack |
222 | #undef scopestack_ix |
223 | #undef scopestack_max |
224 | #undef savestack |
225 | #undef savestack_ix |
226 | #undef savestack_max |
227 | #undef retstack |
228 | #undef retstack_ix |
229 | #undef retstack_max |
0f15f207 |
230 | #undef curcop |
11343788 |
231 | #undef cxstack |
232 | #undef cxstack_ix |
233 | #undef cxstack_max |
809a5acc |
234 | #undef defstash |
235 | #undef curstash |
6d4ff0d2 |
236 | #undef tmps_stack |
237 | #undef tmps_floor |
238 | #undef tmps_ix |
239 | #undef tmps_max |
11343788 |
240 | #undef curpad |
241 | #undef Sv |
242 | #undef Xpv |
96827780 |
243 | #undef statbuf |
244 | #undef timesbuf |
11343788 |
245 | #undef top_env |
246 | #undef runlevel |
247 | #undef in_eval |
809a5acc |
248 | #undef restartop |
249 | #undef delaymagic |
250 | #undef dirty |
251 | #undef localizing |
11343788 |
252 | |
253 | #define self (thr->Tself) |
07b73707 |
254 | #define oursv (thr->Toursv) |
11343788 |
255 | #define stack_base (thr->Tstack_base) |
256 | #define stack_sp (thr->Tstack_sp) |
257 | #define stack_max (thr->Tstack_max) |
462e5cf6 |
258 | #ifdef OP_IN_REGISTER |
259 | #define opsave (thr->Topsave) |
260 | #else |
261 | #undef op |
11343788 |
262 | #define op (thr->Top) |
462e5cf6 |
263 | #endif |
0f15f207 |
264 | #define curcop (thr->Tcurcop) |
11343788 |
265 | #define stack (thr->Tstack) |
809a5acc |
266 | #define curstack (thr->Tcurstack) |
11343788 |
267 | #define mainstack (thr->Tmainstack) |
268 | #define markstack (thr->Tmarkstack) |
269 | #define markstack_ptr (thr->Tmarkstack_ptr) |
270 | #define markstack_max (thr->Tmarkstack_max) |
271 | #define scopestack (thr->Tscopestack) |
272 | #define scopestack_ix (thr->Tscopestack_ix) |
273 | #define scopestack_max (thr->Tscopestack_max) |
274 | |
275 | #define savestack (thr->Tsavestack) |
276 | #define savestack_ix (thr->Tsavestack_ix) |
277 | #define savestack_max (thr->Tsavestack_max) |
278 | |
279 | #define retstack (thr->Tretstack) |
280 | #define retstack_ix (thr->Tretstack_ix) |
281 | #define retstack_max (thr->Tretstack_max) |
282 | |
283 | #define cxstack (thr->Tcxstack) |
284 | #define cxstack_ix (thr->Tcxstack_ix) |
285 | #define cxstack_max (thr->Tcxstack_max) |
286 | |
287 | #define curpad (thr->Tcurpad) |
288 | #define Sv (thr->TSv) |
289 | #define Xpv (thr->TXpv) |
96827780 |
290 | #define statbuf (thr->Tstatbuf) |
291 | #define timesbuf (thr->Ttimesbuf) |
11343788 |
292 | #define defstash (thr->Tdefstash) |
293 | #define curstash (thr->Tcurstash) |
11343788 |
294 | |
295 | #define tmps_stack (thr->Ttmps_stack) |
296 | #define tmps_ix (thr->Ttmps_ix) |
297 | #define tmps_floor (thr->Ttmps_floor) |
298 | #define tmps_max (thr->Ttmps_max) |
299 | |
300 | #define in_eval (thr->Tin_eval) |
301 | #define restartop (thr->Trestartop) |
302 | #define delaymagic (thr->Tdelaymagic) |
303 | #define dirty (thr->Tdirty) |
304 | #define localizing (thr->Tlocalizing) |
305 | |
306 | #define top_env (thr->Ttop_env) |
307 | #define runlevel (thr->Trunlevel) |
308 | |
f93b4edd |
309 | #define cvcache (thr->Tcvcache) |
11343788 |
310 | #endif /* USE_THREADS */ |