… | |
… | |
27 | |
27 | |
28 | #ifndef SvREFCNT_dec_NN |
28 | #ifndef SvREFCNT_dec_NN |
29 | #define SvREFCNT_dec_NN(sv) SvREFCNT_dec (sv) |
29 | #define SvREFCNT_dec_NN(sv) SvREFCNT_dec (sv) |
30 | #endif |
30 | #endif |
31 | |
31 | |
|
|
32 | #ifndef SvREFCNT_dec_simple_void_NN |
|
|
33 | #define SvREFCNT_dec_simple_void_NN(sv) SvREFCNT_dec (sv) |
|
|
34 | #endif |
|
|
35 | |
32 | #ifndef SvREFCNT_inc_NN |
36 | #ifndef SvREFCNT_inc_NN |
33 | #define SvREFCNT_inc_NN(sv) SvREFCNT_inc (sv) |
37 | #define SvREFCNT_inc_NN(sv) SvREFCNT_inc (sv) |
34 | #endif |
38 | #endif |
35 | |
39 | |
|
|
40 | #ifndef RECURSION_CHECK |
36 | #define RECURSION_CHECK 0 |
41 | #define RECURSION_CHECK 0 |
|
|
42 | #endif |
37 | |
43 | |
38 | static X_TLS_DECLARE(current_key); |
44 | static X_TLS_DECLARE(current_key); |
39 | #if RECURSION_CHECK |
45 | #if RECURSION_CHECK |
40 | static X_TLS_DECLARE(check_key); |
46 | static X_TLS_DECLARE(check_key); |
41 | #endif |
47 | #endif |
42 | |
48 | |
|
|
49 | static void |
|
|
50 | fatal (const char *msg) |
|
|
51 | { |
|
|
52 | write (2, msg, strlen (msg)); |
|
|
53 | abort (); |
|
|
54 | } |
43 | |
55 | |
44 | static s_epipe ep; |
56 | static s_epipe ep; |
45 | static void *perl_thx; |
57 | static void *perl_thx; |
46 | static sigset_t cursigset, fullsigset; |
58 | static sigset_t cursigset, fullsigset; |
47 | |
59 | |
… | |
… | |
177 | static void |
189 | static void |
178 | start_thread (void) |
190 | start_thread (void) |
179 | { |
191 | { |
180 | xthread_t tid; |
192 | xthread_t tid; |
181 | |
193 | |
|
|
194 | if (!curthreads) |
|
|
195 | { |
|
|
196 | X_UNLOCK (release_m); |
|
|
197 | { |
|
|
198 | dTHX; |
|
|
199 | dSP; |
|
|
200 | |
|
|
201 | PUSHSTACKi (PERLSI_REQUIRE); |
|
|
202 | |
|
|
203 | eval_pv ("Coro::Multicore::init", 1); |
|
|
204 | |
|
|
205 | POPSTACK; |
|
|
206 | } |
|
|
207 | X_LOCK (release_m); |
|
|
208 | } |
|
|
209 | |
182 | if (curthreads >= max_threads && 0) |
210 | if (curthreads >= max_threads && 0) |
183 | return; |
211 | return; |
184 | |
212 | |
185 | ++curthreads; |
213 | ++curthreads; |
186 | ++idle; |
214 | ++idle; |
… | |
… | |
188 | } |
216 | } |
189 | |
217 | |
190 | static void |
218 | static void |
191 | pmapi_release (void) |
219 | pmapi_release (void) |
192 | { |
220 | { |
|
|
221 | if (! ((thread_enable ? thread_enable : global_enable) & 1)) |
|
|
222 | { |
|
|
223 | X_TLS_SET (current_key, 0); |
|
|
224 | return; |
|
|
225 | } |
|
|
226 | |
193 | #if RECURSION_CHECK |
227 | #if RECURSION_CHECK |
194 | if (X_TLS_GET (check_key)) |
228 | if (X_TLS_GET (check_key)) |
195 | croak ("perlinterp_release () called without valid perl context"); |
229 | fatal ("FATAL: perlinterp_release () called without valid perl context"); |
196 | |
230 | |
197 | X_TLS_SET (check_key, &check_key); |
231 | X_TLS_SET (check_key, &check_key); |
198 | #endif |
232 | #endif |
199 | |
|
|
200 | if (! ((thread_enable ? thread_enable : global_enable) & 1)) |
|
|
201 | { |
|
|
202 | X_TLS_SET (current_key, 0); |
|
|
203 | return; |
|
|
204 | } |
|
|
205 | |
233 | |
206 | struct tctx *ctx = tctx_get (); |
234 | struct tctx *ctx = tctx_get (); |
207 | ctx->coro = SvREFCNT_inc_simple_NN (CORO_CURRENT); |
235 | ctx->coro = SvREFCNT_inc_simple_NN (CORO_CURRENT); |
208 | ctx->wait_f = 0; |
236 | ctx->wait_f = 0; |
209 | |
237 | |
… | |
… | |
231 | pmapi_acquire (void) |
259 | pmapi_acquire (void) |
232 | { |
260 | { |
233 | int jeret; |
261 | int jeret; |
234 | struct tctx *ctx = X_TLS_GET (current_key); |
262 | struct tctx *ctx = X_TLS_GET (current_key); |
235 | |
263 | |
|
|
264 | if (!ctx) |
|
|
265 | return; |
|
|
266 | |
236 | #if RECURSION_CHECK |
267 | #if RECURSION_CHECK |
237 | if (X_TLS_GET (check_key) != &check_key) |
268 | if (X_TLS_GET (check_key) != &check_key) |
238 | croak ("perlinterp_acquire () called with valid perl context"); |
269 | fatal ("FATAL: perlinterp_acquire () called with valid perl context"); |
239 | |
270 | |
240 | X_TLS_SET (check_key, 0); |
271 | X_TLS_SET (check_key, 0); |
241 | #endif |
272 | #endif |
242 | |
|
|
243 | if (!ctx) |
|
|
244 | return; |
|
|
245 | |
273 | |
246 | X_LOCK (acquire_m); |
274 | X_LOCK (acquire_m); |
247 | |
275 | |
248 | tctxs_put (&acquirers, ctx); |
276 | tctxs_put (&acquirers, ctx); |
249 | |
277 | |
… | |
… | |
289 | |
317 | |
290 | perl_thx = PERL_GET_CONTEXT; |
318 | perl_thx = PERL_GET_CONTEXT; |
291 | |
319 | |
292 | I_CORO_API ("Coro::Multicore"); |
320 | I_CORO_API ("Coro::Multicore"); |
293 | |
321 | |
|
|
322 | if (0) { /*D*/ |
294 | X_LOCK (release_m); |
323 | X_LOCK (release_m); |
295 | while (idle < min_idle) |
324 | while (idle < min_idle) |
296 | start_thread (); |
325 | start_thread (); |
297 | X_UNLOCK (release_m); |
326 | X_UNLOCK (release_m); |
|
|
327 | } |
298 | |
328 | |
299 | /* not perfectly efficient to do it this way, but it is simple */ |
329 | /* not perfectly efficient to do it this way, but it is simple */ |
300 | perl_multicore_init (); /* calls release */ |
330 | perl_multicore_init (); /* calls release */ |
301 | perl_multicore_api->pmapi_release = pmapi_release; |
331 | perl_multicore_api->pmapi_release = pmapi_release; |
302 | perl_multicore_api->pmapi_acquire = pmapi_acquire; |
332 | perl_multicore_api->pmapi_acquire = pmapi_acquire; |
… | |
… | |
322 | scoped_disable () |
352 | scoped_disable () |
323 | CODE: |
353 | CODE: |
324 | LEAVE; /* see Guard.xs */ |
354 | LEAVE; /* see Guard.xs */ |
325 | CORO_ENTERLEAVE_SCOPE_HOOK (set_thread_enable, (void *)2, set_thread_enable, (void *)0); |
355 | CORO_ENTERLEAVE_SCOPE_HOOK (set_thread_enable, (void *)2, set_thread_enable, (void *)0); |
326 | ENTER; /* see Guard.xs */ |
356 | ENTER; /* see Guard.xs */ |
|
|
357 | |
|
|
358 | #if 0 |
327 | |
359 | |
328 | U32 |
360 | U32 |
329 | min_idle_threads (U32 min = NO_INIT) |
361 | min_idle_threads (U32 min = NO_INIT) |
330 | CODE: |
362 | CODE: |
331 | X_LOCK (acquire_m); |
363 | X_LOCK (acquire_m); |
… | |
… | |
333 | if (items) |
365 | if (items) |
334 | min_idle = min; |
366 | min_idle = min; |
335 | X_UNLOCK (acquire_m); |
367 | X_UNLOCK (acquire_m); |
336 | OUTPUT: |
368 | OUTPUT: |
337 | RETVAL |
369 | RETVAL |
338 | |
370 | |
|
|
371 | #endif |
339 | |
372 | |
340 | int |
373 | int |
341 | fd () |
374 | fd () |
342 | CODE: |
375 | CODE: |
343 | RETVAL = s_epipe_fd (&ep); |
376 | RETVAL = s_epipe_fd (&ep); |
… | |
… | |
351 | X_LOCK (acquire_m); |
384 | X_LOCK (acquire_m); |
352 | while (acquirers.cur) |
385 | while (acquirers.cur) |
353 | { |
386 | { |
354 | struct tctx *ctx = tctxs_get (&acquirers); |
387 | struct tctx *ctx = tctxs_get (&acquirers); |
355 | CORO_READY ((SV *)ctx->coro); |
388 | CORO_READY ((SV *)ctx->coro); |
356 | SvREFCNT_dec_NN ((SV *)ctx->coro); |
389 | SvREFCNT_dec_simple_void_NN ((SV *)ctx->coro); |
357 | ctx->coro = 0; |
390 | ctx->coro = 0; |
358 | } |
391 | } |
359 | X_UNLOCK (acquire_m); |
392 | X_UNLOCK (acquire_m); |
360 | |
393 | |
361 | void |
394 | void |