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) |
41 | |
42 | #else |
43 | /* POSIXish threads */ |
44 | typedef pthread_t perl_thread; |
11343788 |
45 | #ifdef OLD_PTHREADS_API |
46 | #define pthread_mutexattr_init(a) pthread_mutexattr_create(a) |
47 | #define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t) |
48 | #define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d)) |
49 | #else |
50 | #define pthread_mutexattr_default NULL |
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) \ |
64 | if (pthread_cond_init((c), NULL)) croak("panic: COND_INIT"); else 1 |
65 | #define COND_SIGNAL(c) \ |
66 | if (pthread_cond_signal((c))) croak("panic: COND_SIGNAL"); else 1 |
67 | #define COND_BROADCAST(c) \ |
68 | if (pthread_cond_broadcast((c))) croak("panic: COND_BROADCAST"); else 1 |
69 | #define COND_WAIT(c, m) \ |
70 | if (pthread_cond_wait((c), (m))) croak("panic: COND_WAIT"); else 1 |
71 | #define COND_DESTROY(c) \ |
72 | if (pthread_cond_destroy((c))) croak("panic: COND_DESTROY"); else 1 |
73 | /* XXX Add "old" (?) POSIX draft interface too */ |
74 | #ifdef OLD_PTHREADS_API |
75 | struct thread *getTHR _((void)); |
76 | #define THR getTHR() |
77 | #else |
78 | #define THR ((struct thread *) pthread_getspecific(thr_key)) |
79 | #endif /* OLD_PTHREADS_API */ |
80 | #define dTHR struct thread *thr = THR |
12ca11f6 |
81 | #endif /* FAKE_THREADS */ |
11343788 |
82 | |
83 | struct thread { |
12ca11f6 |
84 | perl_thread Tself; |
11343788 |
85 | |
86 | /* The fields that used to be global */ |
87 | SV ** Tstack_base; |
88 | SV ** Tstack_sp; |
89 | SV ** Tstack_max; |
90 | |
462e5cf6 |
91 | #ifdef OP_IN_REGISTER |
92 | OP * Topsave; |
93 | #else |
11343788 |
94 | OP * Top; |
462e5cf6 |
95 | #endif |
11343788 |
96 | |
97 | I32 * Tscopestack; |
98 | I32 Tscopestack_ix; |
99 | I32 Tscopestack_max; |
100 | |
101 | ANY * Tsavestack; |
102 | I32 Tsavestack_ix; |
103 | I32 Tsavestack_max; |
104 | |
105 | OP ** Tretstack; |
106 | I32 Tretstack_ix; |
107 | I32 Tretstack_max; |
108 | |
109 | I32 * Tmarkstack; |
110 | I32 * Tmarkstack_ptr; |
111 | I32 * Tmarkstack_max; |
112 | |
113 | SV ** Tcurpad; |
114 | |
115 | SV * TSv; |
116 | XPV * TXpv; |
117 | char Tbuf[2048]; /* should be a global locked by a mutex */ |
118 | char Ttokenbuf[256]; /* should be a global locked by a mutex */ |
119 | struct stat Tstatbuf; |
120 | struct tms Ttimesbuf; |
121 | |
122 | /* XXX What about regexp stuff? */ |
123 | |
124 | /* Now the fields that used to be "per interpreter" (even when global) */ |
125 | |
126 | /* XXX What about magic variables such as $/, $? and so on? */ |
127 | HV * Tdefstash; |
128 | HV * Tcurstash; |
129 | AV * Tpad; |
130 | AV * Tpadname; |
131 | |
132 | SV ** Ttmps_stack; |
133 | I32 Ttmps_ix; |
134 | I32 Ttmps_floor; |
135 | I32 Ttmps_max; |
136 | |
137 | int Tin_eval; |
138 | OP * Trestartop; |
139 | int Tdelaymagic; |
140 | bool Tdirty; |
141 | U8 Tlocalizing; |
0f15f207 |
142 | COP * Tcurcop; |
11343788 |
143 | |
144 | CONTEXT * Tcxstack; |
145 | I32 Tcxstack_ix; |
146 | I32 Tcxstack_max; |
147 | |
0f15f207 |
148 | AV * Tcurstack; |
11343788 |
149 | AV * Tmainstack; |
e858de61 |
150 | JMPENV * Ttop_env; |
11343788 |
151 | I32 Trunlevel; |
152 | |
153 | /* XXX Sort stuff, firstgv, secongv and so on? */ |
154 | |
12ca11f6 |
155 | perl_mutex *Tthreadstart_mutexp; |
11343788 |
156 | HV * Tcvcache; |
f93b4edd |
157 | U32 Tthrflags; |
12ca11f6 |
158 | |
159 | #ifdef FAKE_THREADS |
160 | perl_thread next, prev; /* Linked list of all threads */ |
161 | perl_thread next_run, prev_run; /* Linked list of runnable threads */ |
162 | perl_cond wait_queue; /* Wait queue that we are waiting on */ |
163 | IV private; /* Holds data across time slices */ |
0f15f207 |
164 | I32 savemark; /* Holds MARK for thread join values */ |
12ca11f6 |
165 | #endif /* FAKE_THREADS */ |
11343788 |
166 | }; |
167 | |
168 | typedef struct thread *Thread; |
169 | |
f93b4edd |
170 | /* Values and macros for thrflags */ |
171 | #define THR_STATE_MASK 3 |
172 | #define THR_NORMAL 0 |
173 | #define THR_DETACHED 1 |
174 | #define THR_JOINED 2 |
175 | #define THR_DEAD 3 |
176 | |
177 | #define ThrSTATE(t) (t->Tthrflags & THR_STATE_MASK) |
178 | #define ThrSETSTATE(t, s) STMT_START { \ |
179 | (t)->Tthrflags &= ~THR_STATE_MASK; \ |
180 | (t)->Tthrflags |= (s); \ |
181 | DEBUG_L(fprintf(stderr, "thread 0x%lx set to state %d\n", \ |
182 | (unsigned long)(t), (s))); \ |
183 | } STMT_END |
184 | |
185 | typedef struct condpair { |
12ca11f6 |
186 | perl_mutex mutex; |
187 | perl_cond owner_cond; |
188 | perl_cond cond; |
189 | Thread owner; |
f93b4edd |
190 | } condpair_t; |
191 | |
192 | #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex) |
193 | #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond) |
194 | #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond) |
195 | #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner |
196 | |
11343788 |
197 | #undef stack_base |
198 | #undef stack_sp |
199 | #undef stack_max |
0f15f207 |
200 | #undef curstack |
11343788 |
201 | #undef mainstack |
202 | #undef markstack |
203 | #undef markstack_ptr |
204 | #undef markstack_max |
205 | #undef scopestack |
206 | #undef scopestack_ix |
207 | #undef scopestack_max |
208 | #undef savestack |
209 | #undef savestack_ix |
210 | #undef savestack_max |
211 | #undef retstack |
212 | #undef retstack_ix |
213 | #undef retstack_max |
0f15f207 |
214 | #undef curcop |
11343788 |
215 | #undef cxstack |
216 | #undef cxstack_ix |
217 | #undef cxstack_max |
6d4ff0d2 |
218 | #undef tmps_stack |
219 | #undef tmps_floor |
220 | #undef tmps_ix |
221 | #undef tmps_max |
11343788 |
222 | #undef curpad |
223 | #undef Sv |
224 | #undef Xpv |
11343788 |
225 | #undef top_env |
226 | #undef runlevel |
227 | #undef in_eval |
228 | |
229 | #define self (thr->Tself) |
230 | #define stack_base (thr->Tstack_base) |
231 | #define stack_sp (thr->Tstack_sp) |
232 | #define stack_max (thr->Tstack_max) |
462e5cf6 |
233 | #ifdef OP_IN_REGISTER |
234 | #define opsave (thr->Topsave) |
235 | #else |
236 | #undef op |
11343788 |
237 | #define op (thr->Top) |
462e5cf6 |
238 | #endif |
0f15f207 |
239 | #define curcop (thr->Tcurcop) |
11343788 |
240 | #define stack (thr->Tstack) |
241 | #define mainstack (thr->Tmainstack) |
242 | #define markstack (thr->Tmarkstack) |
243 | #define markstack_ptr (thr->Tmarkstack_ptr) |
244 | #define markstack_max (thr->Tmarkstack_max) |
245 | #define scopestack (thr->Tscopestack) |
246 | #define scopestack_ix (thr->Tscopestack_ix) |
247 | #define scopestack_max (thr->Tscopestack_max) |
248 | |
249 | #define savestack (thr->Tsavestack) |
250 | #define savestack_ix (thr->Tsavestack_ix) |
251 | #define savestack_max (thr->Tsavestack_max) |
252 | |
253 | #define retstack (thr->Tretstack) |
254 | #define retstack_ix (thr->Tretstack_ix) |
255 | #define retstack_max (thr->Tretstack_max) |
256 | |
257 | #define cxstack (thr->Tcxstack) |
258 | #define cxstack_ix (thr->Tcxstack_ix) |
259 | #define cxstack_max (thr->Tcxstack_max) |
260 | |
261 | #define curpad (thr->Tcurpad) |
262 | #define Sv (thr->TSv) |
263 | #define Xpv (thr->TXpv) |
264 | #define defstash (thr->Tdefstash) |
265 | #define curstash (thr->Tcurstash) |
266 | #define pad (thr->Tpad) |
267 | #define padname (thr->Tpadname) |
268 | |
269 | #define tmps_stack (thr->Ttmps_stack) |
270 | #define tmps_ix (thr->Ttmps_ix) |
271 | #define tmps_floor (thr->Ttmps_floor) |
272 | #define tmps_max (thr->Ttmps_max) |
273 | |
274 | #define in_eval (thr->Tin_eval) |
275 | #define restartop (thr->Trestartop) |
276 | #define delaymagic (thr->Tdelaymagic) |
277 | #define dirty (thr->Tdirty) |
278 | #define localizing (thr->Tlocalizing) |
279 | |
280 | #define top_env (thr->Ttop_env) |
281 | #define runlevel (thr->Trunlevel) |
282 | |
283 | #define threadstart_mutexp (thr->Tthreadstart_mutexp) |
f93b4edd |
284 | #define cvcache (thr->Tcvcache) |
285 | #define thrflags (thr->Tthrflags) |
11343788 |
286 | #endif /* USE_THREADS */ |