ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.466 by root, Sat Jun 25 19:22:33 2016 UTC vs.
Revision 1.478 by root, Mon Mar 16 11:12:52 2020 UTC

2#define USE_NO_MINGW_SETJMP_TWO_ARGS 2#define USE_NO_MINGW_SETJMP_TWO_ARGS
3 3
4#define NDEBUG 1 /* perl usually disables NDEBUG later */ 4#define NDEBUG 1 /* perl usually disables NDEBUG later */
5 5
6#include "libcoro/coro.c" 6#include "libcoro/coro.c"
7
8#if CORO_UCONTEXT
9 #define CORO_BACKEND "ucontext"
10#elif CORO_SJLJ
11 #define CORO_BACKEND "sjlj"
12#elif CORO_LINUX
13 #define CORO_BACKEND "linux"
14#elif CORO_LOSER
15 #define CORO_BACKEND "loser"
16#elif CORO_FIBER
17 #define CORO_BACKEND "fiber"
18#elif CORO_IRIX
19 #define CORO_BACKEND "irix"
20#elif CORO_ASM
21 #define CORO_BACKEND "asm"
22#elif CORO_PTHREAD
23 #define CORO_BACKEND "pthread"
24#else
25 #define CORO_BACKEND "unknown"
26#endif
7 27
8#define PERL_NO_GET_CONTEXT 28#define PERL_NO_GET_CONTEXT
9#define PERL_EXT 29#define PERL_EXT
10 30
11#include "EXTERN.h" 31#include "EXTERN.h"
116# define CORO_CLOCK_MONOTONIC 1 136# define CORO_CLOCK_MONOTONIC 1
117# define CORO_CLOCK_THREAD_CPUTIME_ID 3 137# define CORO_CLOCK_THREAD_CPUTIME_ID 3
118# endif 138# endif
119#endif 139#endif
120 140
141/* one off bugfix for perl 5.22 */
142#if PERL_VERSION_ATLEAST(5,22,0) && !PERL_VERSION_ATLEAST(5,24,0)
143# undef PadlistNAMES
144# define PadlistNAMES(pl) *((PADNAMELIST **)PadlistARRAY (pl))
145#endif
146
147#if PERL_VERSION_ATLEAST(5,24,0)
148# define SUB_ARGARRAY PL_curpad[0]
149#else
150# define SUB_ARGARRAY (SV *)cx->blk_sub.argarray
151#endif
152
121/* perl usually suppressed asserts. for debugging, we sometimes force it to be on */ 153/* perl usually suppresses asserts. for debugging, we sometimes force it to be on */
122#if 0 154#if 0
123# undef NDEBUG 155# undef NDEBUG
124# include <assert.h> 156# include <assert.h>
125#endif 157#endif
126 158
251 int usecount; /* number of transfers to this coro */ 283 int usecount; /* number of transfers to this coro */
252 284
253 /* coro process data */ 285 /* coro process data */
254 int prio; 286 int prio;
255 SV *except; /* exception to be thrown */ 287 SV *except; /* exception to be thrown */
256 SV *rouse_cb; /* last rouse callback */ 288 SV *rouse_cb; /* most recently created rouse callback */
257 AV *on_destroy; /* callbacks or coros to notify on destroy */ 289 AV *on_destroy; /* callbacks or coros to notify on destroy */
258 AV *status; /* the exit status list */ 290 AV *status; /* the exit status list */
259 291
260 /* async_pool */ 292 /* async_pool */
261 SV *saved_deffh; 293 SV *saved_deffh;
1210 myop.op_next = Nullop; 1242 myop.op_next = Nullop;
1211 myop.op_type = OP_ENTERSUB; 1243 myop.op_type = OP_ENTERSUB;
1212 myop.op_flags = OPf_WANT_VOID; 1244 myop.op_flags = OPf_WANT_VOID;
1213 1245
1214 PUSHMARK (SP); 1246 PUSHMARK (SP);
1215 PUSHs ((SV *)coro->startcv); 1247 XPUSHs ((SV *)coro->startcv);
1216 PUTBACK; 1248 PUTBACK;
1217 PL_op = (OP *)&myop; 1249 PL_op = (OP *)&myop;
1218 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); 1250 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
1219 } 1251 }
1220 1252
1368 av_push (av, SvREFCNT_inc_NN (*bot++)); 1400 av_push (av, SvREFCNT_inc_NN (*bot++));
1369 1401
1370 PL_runops = RUNOPS_DEFAULT; 1402 PL_runops = RUNOPS_DEFAULT;
1371 ENTER; 1403 ENTER;
1372 SAVETMPS; 1404 SAVETMPS;
1405 PUSHMARK (SP);
1373 EXTEND (SP, 3); 1406 EXTEND (SP, 3);
1374 PUSHMARK (SP);
1375 PUSHs (&PL_sv_no); 1407 PUSHs (&PL_sv_no);
1376 PUSHs (fullname); 1408 PUSHs (fullname);
1377 PUSHs (sv_2mortal (newRV_noinc ((SV *)av))); 1409 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
1378 PUTBACK; 1410 PUTBACK;
1379 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0); 1411 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
1406 gv_efullname3 (fullname, gv, 0); 1438 gv_efullname3 (fullname, gv, 0);
1407 1439
1408 PL_runops = RUNOPS_DEFAULT; 1440 PL_runops = RUNOPS_DEFAULT;
1409 ENTER; 1441 ENTER;
1410 SAVETMPS; 1442 SAVETMPS;
1443 PUSHMARK (SP);
1411 EXTEND (SP, 3); 1444 EXTEND (SP, 3);
1412 PUSHMARK (SP);
1413 PUSHs (&PL_sv_yes); 1445 PUSHs (&PL_sv_yes);
1414 PUSHs (fullname); 1446 PUSHs (fullname);
1415 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef); 1447 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc (SUB_ARGARRAY)) : &PL_sv_undef);
1416 PUTBACK; 1448 PUTBACK;
1417 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0); 1449 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
1418 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 1450 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1419 SPAGAIN; 1451 SPAGAIN;
1420 FREETMPS; 1452 FREETMPS;
1430 dSP; 1462 dSP;
1431 1463
1432 PL_runops = RUNOPS_DEFAULT; 1464 PL_runops = RUNOPS_DEFAULT;
1433 ENTER; 1465 ENTER;
1434 SAVETMPS; 1466 SAVETMPS;
1435 EXTEND (SP, 3);
1436 PL_runops = RUNOPS_DEFAULT;
1437 PUSHMARK (SP); 1467 PUSHMARK (SP);
1468 EXTEND (SP, 2);
1438 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0))); 1469 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
1439 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop)))); 1470 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
1440 PUTBACK; 1471 PUTBACK;
1441 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0); 1472 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0);
1442 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 1473 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1828 1859
1829static int ecb_cold 1860static int ecb_cold
1830coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params) 1861coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
1831{ 1862{
1832 /* called when perl clones the current process the slow way (windows process emulation) */ 1863 /* called when perl clones the current process the slow way (windows process emulation) */
1833 /* WE SIMply nuke the pointers in the copy, causing perl to croak */ 1864 /* we simply nuke the pointers in the copy, causing perl to croak */
1834 mg->mg_ptr = 0; 1865 mg->mg_ptr = 0;
1835 mg->mg_virtual = 0; 1866 mg->mg_virtual = 0;
1836 1867
1837 return 0; 1868 return 0;
1838} 1869}
2360safe_cancel (pTHX_ struct coro *coro, SV **arg, int items) 2391safe_cancel (pTHX_ struct coro *coro, SV **arg, int items)
2361{ 2392{
2362 if (coro->cctx) 2393 if (coro->cctx)
2363 croak ("coro inside C callback, unable to cancel at this time, caught"); 2394 croak ("coro inside C callback, unable to cancel at this time, caught");
2364 2395
2365 if (coro->flags & CF_NEW) 2396 if (coro->flags & (CF_NEW | CF_ZOMBIE))
2366 { 2397 {
2367 coro_set_status (aTHX_ coro, arg, items); 2398 coro_set_status (aTHX_ coro, arg, items);
2368 coro_state_destroy (aTHX_ coro); 2399 coro_state_destroy (aTHX_ coro);
2369 } 2400 }
2370 else 2401 else
2439 av_clear (GvAV (PL_defgv)); 2470 av_clear (GvAV (PL_defgv));
2440 hv_store (hv, "desc", sizeof ("desc") - 1, SvREFCNT_inc_NN (sv_async_pool_idle), 0); 2471 hv_store (hv, "desc", sizeof ("desc") - 1, SvREFCNT_inc_NN (sv_async_pool_idle), 0);
2441 2472
2442 if (ecb_expect_false (coro->swap_sv)) 2473 if (ecb_expect_false (coro->swap_sv))
2443 { 2474 {
2444 swap_svs_leave (coro); 2475 SWAP_SVS_LEAVE (coro);
2445 SvREFCNT_dec_NN (coro->swap_sv); 2476 SvREFCNT_dec_NN (coro->swap_sv);
2446 coro->swap_sv = 0; 2477 coro->swap_sv = 0;
2447 } 2478 }
2448 2479
2449 coro->prio = 0; 2480 coro->prio = 0;
2450 2481
2451 if (ecb_expect_false (coro->cctx) && ecb_expect_false (coro->cctx->flags & CC_TRACE)) 2482 if (ecb_expect_false (coro->cctx) && ecb_expect_false (coro->cctx->flags & CC_TRACE))
2452 api_trace (aTHX_ coro_current, 0); 2483 api_trace (aTHX_ coro_current, 0);
2453 2484
2454 frame->prepare = prepare_schedule; 2485 frame->prepare = prepare_schedule;
2455 av_push (av_async_pool, SvREFCNT_inc (hv)); 2486 av_push (av_async_pool, SvREFCNT_inc_NN (hv));
2456 } 2487 }
2457 } 2488 }
2458 else 2489 else
2459 { 2490 {
2460 /* first iteration, simply fall through */ 2491 /* first iteration, simply fall through */
2473static void 2504static void
2474coro_rouse_callback (pTHX_ CV *cv) 2505coro_rouse_callback (pTHX_ CV *cv)
2475{ 2506{
2476 dXSARGS; 2507 dXSARGS;
2477 SV *data = (SV *)S_GENSUB_ARG; 2508 SV *data = (SV *)S_GENSUB_ARG;
2509 SV *coro = SvRV (data);
2478 2510
2511 /* data starts being either undef or a coro, and is replaced by the results when done */
2479 if (SvTYPE (SvRV (data)) != SVt_PVAV) 2512 if (SvTYPE (coro) != SVt_PVAV)
2480 { 2513 {
2481 /* first call, set args */ 2514 /* first call, set args */
2482 SV *coro = SvRV (data);
2483 AV *av = newAV ();
2484 2515
2485 SvRV_set (data, (SV *)av); 2516 assert (&ST (0) < &ST (1)); /* ensure the stack is in the order we expect it to be */
2517 SvRV_set (data, (SV *)av_make (items, &ST (0))); /* av_make copies the SVs */
2486 2518
2487 /* better take a full copy of the arguments */ 2519 if (coro != &PL_sv_undef)
2488 while (items--) 2520 {
2489 av_store (av, items, newSVsv (ST (items)));
2490
2491 api_ready (aTHX_ coro); 2521 api_ready (aTHX_ coro);
2492 SvREFCNT_dec (coro); 2522 SvREFCNT_dec_NN (coro);
2523 }
2493 } 2524 }
2494 2525
2495 XSRETURN_EMPTY; 2526 XSRETURN_EMPTY;
2496} 2527}
2497 2528
2514 2545
2515 EXTEND (SP, AvFILLp (av) + 1); 2546 EXTEND (SP, AvFILLp (av) + 1);
2516 for (i = 0; i <= AvFILLp (av); ++i) 2547 for (i = 0; i <= AvFILLp (av); ++i)
2517 PUSHs (sv_2mortal (AvARRAY (av)[i])); 2548 PUSHs (sv_2mortal (AvARRAY (av)[i]));
2518 2549
2519 /* we have stolen the elements, so set length to zero and free */ 2550 /* we have stolen the elements, make it unreal and free */
2520 AvFILLp (av) = -1; 2551 AvREAL_off (av);
2521 av_undef (av); 2552 av_undef (av);
2522 2553
2523 PUTBACK; 2554 PUTBACK;
2524 } 2555 }
2525 2556
2550 croak ("Coro::rouse_wait called with illegal callback argument,"); 2581 croak ("Coro::rouse_wait called with illegal callback argument,");
2551 2582
2552 { 2583 {
2553 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */ 2584 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */
2554 SV *data = (SV *)S_GENSUB_ARG; 2585 SV *data = (SV *)S_GENSUB_ARG;
2586 int data_ready = SvTYPE (SvRV (data)) == SVt_PVAV;
2587
2588 /* if there is no data, we need to store the current coro in the reference so we can be woken up */
2589 if (!data_ready)
2590 if (SvRV (data) != &PL_sv_undef)
2591 croak ("Coro::rouse_wait was called on a calback that is already being waited for - only one thread can wait for a rouse callback, caught");
2592 else
2593 SvRV_set (data, SvREFCNT_inc_NN (SvRV (coro_current)));
2555 2594
2556 frame->data = (void *)data; 2595 frame->data = (void *)data;
2557 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule; 2596 frame->prepare = data_ready ? prepare_nop : prepare_schedule;
2558 frame->check = slf_check_rouse_wait; 2597 frame->check = slf_check_rouse_wait;
2559 } 2598 }
2560} 2599}
2561 2600
2562static SV * 2601static SV *
2563coro_new_rouse_cb (pTHX) 2602coro_new_rouse_cb (pTHX)
2564{ 2603{
2565 HV *hv = (HV *)SvRV (coro_current); 2604 HV *hv = (HV *)SvRV (coro_current);
2566 struct coro *coro = SvSTATE_hv (hv); 2605 struct coro *coro = SvSTATE_hv (hv);
2567 SV *data = newRV_inc ((SV *)hv); 2606 SV *data = newRV_noinc (&PL_sv_undef);
2568 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data); 2607 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data);
2569 2608
2570 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0); 2609 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
2571 SvREFCNT_dec (data); /* magicext increases the refcount */ 2610 SvREFCNT_dec_NN (data); /* magicext increases the refcount */
2572 2611
2573 SvREFCNT_dec (coro->rouse_cb); 2612 SvREFCNT_dec (coro->rouse_cb);
2574 coro->rouse_cb = SvREFCNT_inc_NN (cb); 2613 coro->rouse_cb = SvREFCNT_inc_NN (cb);
2575 2614
2576 return cb; 2615 return cb;
3585 3624
3586 map_len = load_len + save_len + 16; 3625 map_len = load_len + save_len + 16;
3587 3626
3588 map_base = mmap (0, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 3627 map_base = mmap (0, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
3589 3628
3629 if (map_base == (char *)MAP_FAILED)
3630 map_base = mmap (0, map_len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
3631
3590 assert (("Coro: unable to mmap jit code page, cannot continue.", map_base != (char *)MAP_FAILED)); 3632 assert (("Coro: unable to mmap jit code page, cannot continue.", map_base != (char *)MAP_FAILED));
3591 3633
3592 load_perl_slots = (load_save_perl_slots_type)map_base; 3634 load_perl_slots = (load_save_perl_slots_type)map_base;
3593 memcpy (map_base, load_ptr, load_len); 3635 memcpy (map_base, load_ptr, load_len);
3594 3636
3660 rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV)); 3702 rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV));
3661 rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV)); 3703 rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV));
3662 3704
3663 coro_state_stash = gv_stashpv ("Coro::State", TRUE); 3705 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
3664 3706
3707 newCONSTSUB (coro_state_stash, "BACKEND", newSVpv (CORO_BACKEND, 0)); /* undocumented */
3708
3665 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE)); 3709 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
3666 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB)); 3710 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
3667 newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE)); 3711 newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE));
3668 newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL)); 3712 newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL));
3669 3713
3793call (Coro::State coro, SV *coderef) 3837call (Coro::State coro, SV *coderef)
3794 ALIAS: 3838 ALIAS:
3795 eval = 1 3839 eval = 1
3796 CODE: 3840 CODE:
3797{ 3841{
3842 struct coro *current = SvSTATE_current;
3843
3798 if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot)) 3844 if ((coro == current) || (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot)))
3799 { 3845 {
3800 struct coro *current = SvSTATE_current;
3801 struct CoroSLF slf_save; 3846 struct CoroSLF slf_save;
3802 3847
3803 if (current != coro) 3848 if (current != coro)
3804 { 3849 {
3805 PUTBACK; 3850 PUTBACK;
4064 coroapi.enterleave_hook = api_enterleave_hook; 4109 coroapi.enterleave_hook = api_enterleave_hook;
4065 coroapi.enterleave_unhook = api_enterleave_unhook; 4110 coroapi.enterleave_unhook = api_enterleave_unhook;
4066 coroapi.enterleave_scope_hook = api_enterleave_scope_hook; 4111 coroapi.enterleave_scope_hook = api_enterleave_scope_hook;
4067 4112
4068 /*GCoroAPI = &coroapi;*/ 4113 /*GCoroAPI = &coroapi;*/
4069 sv_setiv (sv, (IV)&coroapi); 4114 sv_setiv (sv, PTR2IV (&coroapi));
4070 SvREADONLY_on (sv); 4115 SvREADONLY_on (sv);
4071 } 4116 }
4072} 4117}
4073 4118
4074SV * 4119SV *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines