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 |
16 | #include <pthread.h> |
17 | |
18 | #ifdef OLD_PTHREADS_API |
19 | #define pthread_mutexattr_init(a) pthread_mutexattr_create(a) |
20 | #define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t) |
21 | #define pthread_key_create(k,d) pthread_keycreate(k,(pthread_destructor_t)(d)) |
22 | #else |
23 | #define pthread_mutexattr_default NULL |
24 | #endif /* OLD_PTHREADS_API */ |
25 | |
26 | #define MUTEX_INIT(m) \ |
27 | if (pthread_mutex_init((m), pthread_mutexattr_default)) \ |
28 | croak("panic: MUTEX_INIT"); \ |
29 | else 1 |
30 | #define MUTEX_LOCK(m) \ |
31 | if (pthread_mutex_lock((m))) croak("panic: MUTEX_LOCK"); else 1 |
32 | #define MUTEX_UNLOCK(m) \ |
33 | if (pthread_mutex_unlock((m))) croak("panic: MUTEX_UNLOCK"); else 1 |
34 | #define MUTEX_DESTROY(m) \ |
35 | if (pthread_mutex_destroy((m))) croak("panic: MUTEX_DESTROY"); else 1 |
36 | #define COND_INIT(c) \ |
37 | if (pthread_cond_init((c), NULL)) croak("panic: COND_INIT"); else 1 |
38 | #define COND_SIGNAL(c) \ |
39 | if (pthread_cond_signal((c))) croak("panic: COND_SIGNAL"); else 1 |
40 | #define COND_BROADCAST(c) \ |
41 | if (pthread_cond_broadcast((c))) croak("panic: COND_BROADCAST"); else 1 |
42 | #define COND_WAIT(c, m) \ |
43 | if (pthread_cond_wait((c), (m))) croak("panic: COND_WAIT"); else 1 |
44 | #define COND_DESTROY(c) \ |
45 | if (pthread_cond_destroy((c))) croak("panic: COND_DESTROY"); else 1 |
46 | /* XXX Add "old" (?) POSIX draft interface too */ |
47 | #ifdef OLD_PTHREADS_API |
48 | struct thread *getTHR _((void)); |
49 | #define THR getTHR() |
50 | #else |
51 | #define THR ((struct thread *) pthread_getspecific(thr_key)) |
52 | #endif /* OLD_PTHREADS_API */ |
53 | #define dTHR struct thread *thr = THR |
54 | |
55 | struct thread { |
56 | pthread_t Tself; |
57 | |
58 | /* The fields that used to be global */ |
59 | SV ** Tstack_base; |
60 | SV ** Tstack_sp; |
61 | SV ** Tstack_max; |
62 | |
462e5cf6 |
63 | #ifdef OP_IN_REGISTER |
64 | OP * Topsave; |
65 | #else |
11343788 |
66 | OP * Top; |
462e5cf6 |
67 | #endif |
11343788 |
68 | |
69 | I32 * Tscopestack; |
70 | I32 Tscopestack_ix; |
71 | I32 Tscopestack_max; |
72 | |
73 | ANY * Tsavestack; |
74 | I32 Tsavestack_ix; |
75 | I32 Tsavestack_max; |
76 | |
77 | OP ** Tretstack; |
78 | I32 Tretstack_ix; |
79 | I32 Tretstack_max; |
80 | |
81 | I32 * Tmarkstack; |
82 | I32 * Tmarkstack_ptr; |
83 | I32 * Tmarkstack_max; |
84 | |
85 | SV ** Tcurpad; |
86 | |
87 | SV * TSv; |
88 | XPV * TXpv; |
89 | char Tbuf[2048]; /* should be a global locked by a mutex */ |
90 | char Ttokenbuf[256]; /* should be a global locked by a mutex */ |
91 | struct stat Tstatbuf; |
92 | struct tms Ttimesbuf; |
93 | |
94 | /* XXX What about regexp stuff? */ |
95 | |
96 | /* Now the fields that used to be "per interpreter" (even when global) */ |
97 | |
98 | /* XXX What about magic variables such as $/, $? and so on? */ |
99 | HV * Tdefstash; |
100 | HV * Tcurstash; |
101 | AV * Tpad; |
102 | AV * Tpadname; |
103 | |
104 | SV ** Ttmps_stack; |
105 | I32 Ttmps_ix; |
106 | I32 Ttmps_floor; |
107 | I32 Ttmps_max; |
108 | |
109 | int Tin_eval; |
110 | OP * Trestartop; |
111 | int Tdelaymagic; |
112 | bool Tdirty; |
113 | U8 Tlocalizing; |
114 | |
115 | CONTEXT * Tcxstack; |
116 | I32 Tcxstack_ix; |
117 | I32 Tcxstack_max; |
118 | |
119 | AV * Tstack; |
120 | AV * Tmainstack; |
e858de61 |
121 | JMPENV * Ttop_env; |
11343788 |
122 | I32 Trunlevel; |
123 | |
124 | /* XXX Sort stuff, firstgv, secongv and so on? */ |
125 | |
126 | pthread_mutex_t * Tthreadstart_mutexp; |
127 | HV * Tcvcache; |
f93b4edd |
128 | U32 Tthrflags; |
11343788 |
129 | }; |
130 | |
131 | typedef struct thread *Thread; |
132 | |
f93b4edd |
133 | /* Values and macros for thrflags */ |
134 | #define THR_STATE_MASK 3 |
135 | #define THR_NORMAL 0 |
136 | #define THR_DETACHED 1 |
137 | #define THR_JOINED 2 |
138 | #define THR_DEAD 3 |
139 | |
140 | #define ThrSTATE(t) (t->Tthrflags & THR_STATE_MASK) |
141 | #define ThrSETSTATE(t, s) STMT_START { \ |
142 | (t)->Tthrflags &= ~THR_STATE_MASK; \ |
143 | (t)->Tthrflags |= (s); \ |
144 | DEBUG_L(fprintf(stderr, "thread 0x%lx set to state %d\n", \ |
145 | (unsigned long)(t), (s))); \ |
146 | } STMT_END |
147 | |
148 | typedef struct condpair { |
149 | pthread_mutex_t mutex; |
150 | pthread_cond_t owner_cond; |
151 | pthread_cond_t cond; |
152 | Thread owner; |
153 | } condpair_t; |
154 | |
155 | #define MgMUTEXP(mg) (&((condpair_t *)(mg->mg_ptr))->mutex) |
156 | #define MgOWNERCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->owner_cond) |
157 | #define MgCONDP(mg) (&((condpair_t *)(mg->mg_ptr))->cond) |
158 | #define MgOWNER(mg) ((condpair_t *)(mg->mg_ptr))->owner |
159 | |
11343788 |
160 | #undef stack_base |
161 | #undef stack_sp |
162 | #undef stack_max |
163 | #undef stack |
164 | #undef mainstack |
165 | #undef markstack |
166 | #undef markstack_ptr |
167 | #undef markstack_max |
168 | #undef scopestack |
169 | #undef scopestack_ix |
170 | #undef scopestack_max |
171 | #undef savestack |
172 | #undef savestack_ix |
173 | #undef savestack_max |
174 | #undef retstack |
175 | #undef retstack_ix |
176 | #undef retstack_max |
177 | #undef cxstack |
178 | #undef cxstack_ix |
179 | #undef cxstack_max |
180 | #undef curpad |
181 | #undef Sv |
182 | #undef Xpv |
11343788 |
183 | #undef top_env |
184 | #undef runlevel |
185 | #undef in_eval |
186 | |
187 | #define self (thr->Tself) |
188 | #define stack_base (thr->Tstack_base) |
189 | #define stack_sp (thr->Tstack_sp) |
190 | #define stack_max (thr->Tstack_max) |
462e5cf6 |
191 | #ifdef OP_IN_REGISTER |
192 | #define opsave (thr->Topsave) |
193 | #else |
194 | #undef op |
11343788 |
195 | #define op (thr->Top) |
462e5cf6 |
196 | #endif |
11343788 |
197 | #define stack (thr->Tstack) |
198 | #define mainstack (thr->Tmainstack) |
199 | #define markstack (thr->Tmarkstack) |
200 | #define markstack_ptr (thr->Tmarkstack_ptr) |
201 | #define markstack_max (thr->Tmarkstack_max) |
202 | #define scopestack (thr->Tscopestack) |
203 | #define scopestack_ix (thr->Tscopestack_ix) |
204 | #define scopestack_max (thr->Tscopestack_max) |
205 | |
206 | #define savestack (thr->Tsavestack) |
207 | #define savestack_ix (thr->Tsavestack_ix) |
208 | #define savestack_max (thr->Tsavestack_max) |
209 | |
210 | #define retstack (thr->Tretstack) |
211 | #define retstack_ix (thr->Tretstack_ix) |
212 | #define retstack_max (thr->Tretstack_max) |
213 | |
214 | #define cxstack (thr->Tcxstack) |
215 | #define cxstack_ix (thr->Tcxstack_ix) |
216 | #define cxstack_max (thr->Tcxstack_max) |
217 | |
218 | #define curpad (thr->Tcurpad) |
219 | #define Sv (thr->TSv) |
220 | #define Xpv (thr->TXpv) |
221 | #define defstash (thr->Tdefstash) |
222 | #define curstash (thr->Tcurstash) |
223 | #define pad (thr->Tpad) |
224 | #define padname (thr->Tpadname) |
225 | |
226 | #define tmps_stack (thr->Ttmps_stack) |
227 | #define tmps_ix (thr->Ttmps_ix) |
228 | #define tmps_floor (thr->Ttmps_floor) |
229 | #define tmps_max (thr->Ttmps_max) |
230 | |
231 | #define in_eval (thr->Tin_eval) |
232 | #define restartop (thr->Trestartop) |
233 | #define delaymagic (thr->Tdelaymagic) |
234 | #define dirty (thr->Tdirty) |
235 | #define localizing (thr->Tlocalizing) |
236 | |
237 | #define top_env (thr->Ttop_env) |
238 | #define runlevel (thr->Trunlevel) |
239 | |
240 | #define threadstart_mutexp (thr->Tthreadstart_mutexp) |
f93b4edd |
241 | #define cvcache (thr->Tcvcache) |
242 | #define thrflags (thr->Tthrflags) |
11343788 |
243 | #endif /* USE_THREADS */ |