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.280 by root, Sun Nov 16 09:43:18 2008 UTC vs.
Revision 1.284 by root, Mon Nov 17 01:05:47 2008 UTC

166static struct CoroAPI coroapi; 166static struct CoroAPI coroapi;
167static AV *main_mainstack; /* used to differentiate between $main and others */ 167static AV *main_mainstack; /* used to differentiate between $main and others */
168static JMPENV *main_top_env; 168static JMPENV *main_top_env;
169static HV *coro_state_stash, *coro_stash; 169static HV *coro_state_stash, *coro_stash;
170static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */ 170static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
171static volatile struct coro *transfer_next;
172 171
173static GV *irsgv; /* $/ */ 172static GV *irsgv; /* $/ */
174static GV *stdoutgv; /* *STDOUT */ 173static GV *stdoutgv; /* *STDOUT */
175static SV *rv_diehook; 174static SV *rv_diehook;
176static SV *rv_warnhook; 175static SV *rv_warnhook;
389static MGVTBL coro_cv_vtbl = { 388static MGVTBL coro_cv_vtbl = {
390 0, 0, 0, 0, 389 0, 0, 0, 0,
391 coro_cv_free 390 coro_cv_free
392}; 391};
393 392
394#define CORO_MAGIC(sv, type) \ 393#define CORO_MAGIC(sv, type) \
395 SvMAGIC (sv) \ 394 expect_true (SvMAGIC (sv)) \
396 ? SvMAGIC (sv)->mg_type == type \ 395 ? expect_true (SvMAGIC (sv)->mg_type == type) \
397 ? SvMAGIC (sv) \ 396 ? SvMAGIC (sv) \
398 : mg_find (sv, type) \ 397 : mg_find (sv, type) \
399 : 0 398 : 0
400 399
401#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv) 400#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv)
402#define CORO_MAGIC_state(sv) CORO_MAGIC (((SV *)(sv)), CORO_MAGIC_type_state) 401#define CORO_MAGIC_state(sv) CORO_MAGIC (((SV *)(sv)), CORO_MAGIC_type_state)
403 402
424 mg = CORO_MAGIC_state (coro); 423 mg = CORO_MAGIC_state (coro);
425 return (struct coro *)mg->mg_ptr; 424 return (struct coro *)mg->mg_ptr;
426} 425}
427 426
428#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv)) 427#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv))
428
429/* fastert than SvSTATE, but expects a coroutine hv */
430INLINE struct coro *
431SvSTATE_hv (SV *sv)
432{
433 MAGIC *mg = expect_true (SvMAGIC (sv)->mg_type == CORO_MAGIC_type_state)
434 ? SvMAGIC (sv)
435 : mg_find (sv, CORO_MAGIC_type_state);
436
437 return (struct coro *)mg->mg_ptr;
438}
439
440#define SvSTATE_current SvSTATE_hv (SvRV (coro_current))
429 441
430/* the next two functions merely cache the padlists */ 442/* the next two functions merely cache the padlists */
431static void 443static void
432get_padlist (pTHX_ CV *cv) 444get_padlist (pTHX_ CV *cv)
433{ 445{
915static int 927static int
916runops_trace (pTHX) 928runops_trace (pTHX)
917{ 929{
918 COP *oldcop = 0; 930 COP *oldcop = 0;
919 int oldcxix = -2; 931 int oldcxix = -2;
920 struct coro *coro = SvSTATE (coro_current); /* trace cctx is tied to specific coro */ 932 struct coro *coro = SvSTATE_current; /* trace cctx is tied to specific coro */
921 coro_cctx *cctx = coro->cctx; 933 coro_cctx *cctx = coro->cctx;
922 934
923 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX))) 935 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX)))
924 { 936 {
925 PERL_ASYNC_CHECK (); 937 PERL_ASYNC_CHECK ();
1074 1086
1075/* the tail of transfer: execute stuff we can only do after a transfer */ 1087/* the tail of transfer: execute stuff we can only do after a transfer */
1076INLINE void 1088INLINE void
1077transfer_tail (pTHX) 1089transfer_tail (pTHX)
1078{ 1090{
1079 struct coro *next = (struct coro *)transfer_next;
1080 assert (!(transfer_next = 0)); /* just used for the side effect when asserts are enabled */
1081 assert (("FATAL: next coroutine was zero in transfer_tail (please report)", next));
1082
1083 free_coro_mortal (aTHX); 1091 free_coro_mortal (aTHX);
1084
1085 if (expect_false (next->throw))
1086 {
1087 SV *exception = sv_2mortal (next->throw);
1088
1089 next->throw = 0;
1090 sv_setsv (ERRSV, exception);
1091 croak (0);
1092 }
1093} 1092}
1094 1093
1095/* 1094/*
1096 * this is a _very_ stripped down perl interpreter ;) 1095 * this is a _very_ stripped down perl interpreter ;)
1097 */ 1096 */
1112 1111
1113 /* inject a fake subroutine call to cctx_init */ 1112 /* inject a fake subroutine call to cctx_init */
1114 cctx_prepare (aTHX_ (coro_cctx *)arg); 1113 cctx_prepare (aTHX_ (coro_cctx *)arg);
1115 1114
1116 /* cctx_run is the alternative tail of transfer() */ 1115 /* cctx_run is the alternative tail of transfer() */
1117 /* TODO: throwing an exception here might be deadly, VERIFY */
1118 transfer_tail (aTHX); 1116 transfer_tail (aTHX);
1119 1117
1120 /* somebody or something will hit me for both perl_run and PL_restartop */ 1118 /* somebody or something will hit me for both perl_run and PL_restartop */
1121 PL_restartop = PL_op; 1119 PL_restartop = PL_op;
1122 perl_run (PL_curinterp); 1120 perl_run (PL_curinterp);
1364 ++next->usecount; 1362 ++next->usecount;
1365 1363
1366 if (expect_true (!next->cctx)) 1364 if (expect_true (!next->cctx))
1367 next->cctx = cctx_get (aTHX); 1365 next->cctx = cctx_get (aTHX);
1368 1366
1369 assert (("FATAL: transfer_next already nonzero in Coro (please report)", !transfer_next));
1370 transfer_next = next;
1371
1372 if (expect_false (prev__cctx != next->cctx)) 1367 if (expect_false (prev__cctx != next->cctx))
1373 { 1368 {
1374 prev__cctx->top_env = PL_top_env; 1369 prev__cctx->top_env = PL_top_env;
1375 PL_top_env = next->cctx->top_env; 1370 PL_top_env = next->cctx->top_env;
1376 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx); 1371 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx);
1486 TRANSFER (ta, 1); 1481 TRANSFER (ta, 1);
1487} 1482}
1488 1483
1489/** Coro ********************************************************************/ 1484/** Coro ********************************************************************/
1490 1485
1491static void 1486INLINE void
1492coro_enq (pTHX_ SV *coro_sv) 1487coro_enq (pTHX_ struct coro *coro)
1493{ 1488{
1494 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv); 1489 av_push (coro_ready [coro->prio - PRIO_MIN], SvREFCNT_inc_NN (coro->hv));
1495} 1490}
1496 1491
1497static SV * 1492INLINE SV *
1498coro_deq (pTHX) 1493coro_deq (pTHX)
1499{ 1494{
1500 int prio; 1495 int prio;
1501 1496
1502 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; ) 1497 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; )
1524 coro->flags |= CF_READY; 1519 coro->flags |= CF_READY;
1525 1520
1526 sv_hook = coro_nready ? 0 : coro_readyhook; 1521 sv_hook = coro_nready ? 0 : coro_readyhook;
1527 xs_hook = coro_nready ? 0 : coroapi.readyhook; 1522 xs_hook = coro_nready ? 0 : coroapi.readyhook;
1528 1523
1529 coro_enq (aTHX_ SvREFCNT_inc_NN (coro_sv)); 1524 coro_enq (aTHX_ coro);
1530 ++coro_nready; 1525 ++coro_nready;
1531 1526
1532 if (sv_hook) 1527 if (sv_hook)
1533 { 1528 {
1534 dSP; 1529 dSP;
1582 FREETMPS; 1577 FREETMPS;
1583 LEAVE; 1578 LEAVE;
1584 continue; 1579 continue;
1585 } 1580 }
1586 1581
1587 ta->next = SvSTATE (next_sv); 1582 ta->next = SvSTATE_hv (next_sv);
1588 1583
1589 /* cannot transfer to destroyed coros, skip and look for next */ 1584 /* cannot transfer to destroyed coros, skip and look for next */
1590 if (expect_false (ta->next->flags & CF_DESTROYED)) 1585 if (expect_false (ta->next->flags & CF_DESTROYED))
1591 { 1586 {
1592 SvREFCNT_dec (next_sv); 1587 SvREFCNT_dec (next_sv);
1598 break; 1593 break;
1599 } 1594 }
1600 1595
1601 /* free this only after the transfer */ 1596 /* free this only after the transfer */
1602 prev_sv = SvRV (coro_current); 1597 prev_sv = SvRV (coro_current);
1603 ta->prev = SvSTATE (prev_sv); 1598 ta->prev = SvSTATE_hv (prev_sv);
1604 TRANSFER_CHECK (*ta); 1599 TRANSFER_CHECK (*ta);
1605 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY)); 1600 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY));
1606 ta->next->flags &= ~CF_READY; 1601 ta->next->flags &= ~CF_READY;
1607 SvRV_set (coro_current, next_sv); 1602 SvRV_set (coro_current, next_sv);
1608 1603
1771 PerlIOBuf_set_ptrcnt, 1766 PerlIOBuf_set_ptrcnt,
1772}; 1767};
1773 1768
1774/*****************************************************************************/ 1769/*****************************************************************************/
1775 1770
1776static const CV *slf_cv; /* for quick consistency check */
1777
1778static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */ 1771static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */
1772static const CV *slf_cv;
1779static SV *slf_arg0; 1773static SV *slf_arg0;
1780static SV *slf_arg1; 1774static SV *slf_arg1;
1781static SV *slf_arg2; 1775static SV *slf_arg2;
1776static I32 slf_ax; /* top of stack, for restore */
1782 1777
1783/* this restores the stack in the case we patched the entersub, to */ 1778/* this restores the stack in the case we patched the entersub, to */
1784/* recreate the stack frame as perl will on following calls */ 1779/* recreate the stack frame as perl will on following calls */
1785/* since entersub cleared the stack */ 1780/* since entersub cleared the stack */
1786static OP * 1781static OP *
1787pp_restore (pTHX) 1782pp_restore (pTHX)
1788{ 1783{
1789 dSP; 1784 SV **SP = PL_stack_base + slf_ax;
1790 1785
1791 PUSHMARK (SP); 1786 PUSHMARK (SP);
1792 1787
1793 EXTEND (SP, 3); 1788 EXTEND (SP, 3);
1794 if (slf_arg0) PUSHs (sv_2mortal (slf_arg0)); 1789 if (slf_arg0) PUSHs (sv_2mortal (slf_arg0));
1819slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta) 1814slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta)
1820{ 1815{
1821 SV **arg = (SV **)slf_frame.data; 1816 SV **arg = (SV **)slf_frame.data;
1822 1817
1823 prepare_transfer (aTHX_ ta, arg [0], arg [1]); 1818 prepare_transfer (aTHX_ ta, arg [0], arg [1]);
1819
1820 /* if the destination has ->throw set, then copy it */
1821 /* into the current coro's throw slot, so it will be raised */
1822 /* after the schedule */
1823 if (expect_false (ta->next->throw))
1824 {
1825 struct coro *coro = SvSTATE_current;
1826 SvREFCNT_dec (coro->throw);
1827 coro->throw = ta->next->throw;
1828 ta->next->throw = 0;
1829 }
1824} 1830}
1825 1831
1826static void 1832static void
1827slf_init_transfer (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items) 1833slf_init_transfer (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1828{ 1834{
1883 /* do a quick consistency check on the "function" object, and if it isn't */ 1889 /* do a quick consistency check on the "function" object, and if it isn't */
1884 /* for us, divert to the real entersub */ 1890 /* for us, divert to the real entersub */
1885 if (SvTYPE (gv) != SVt_PVGV || !(CvFLAGS (GvCV (gv)) & CVf_SLF)) 1891 if (SvTYPE (gv) != SVt_PVGV || !(CvFLAGS (GvCV (gv)) & CVf_SLF))
1886 return PL_ppaddr[OP_ENTERSUB](aTHX); 1892 return PL_ppaddr[OP_ENTERSUB](aTHX);
1887 1893
1888 /* pop args */
1889 SP = PL_stack_base + POPMARK;
1890
1891 if (!(PL_op->op_flags & OPf_STACKED)) 1894 if (!(PL_op->op_flags & OPf_STACKED))
1892 { 1895 {
1893 /* ampersand-form of call, use @_ instead of stack */ 1896 /* ampersand-form of call, use @_ instead of stack */
1894 AV *av = GvAV (PL_defgv); 1897 AV *av = GvAV (PL_defgv);
1895 arg = AvARRAY (av); 1898 arg = AvARRAY (av);
1896 items = AvFILLp (av) + 1; 1899 items = AvFILLp (av) + 1;
1897 } 1900 }
1898 1901
1899 PUTBACK;
1900
1901 /* now call the init function, which needs to set up slf_frame */ 1902 /* now call the init function, which needs to set up slf_frame */
1902 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr) 1903 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr)
1903 (aTHX_ &slf_frame, GvCV (gv), arg, items); 1904 (aTHX_ &slf_frame, GvCV (gv), arg, items);
1905
1906 /* pop args */
1907 SP = PL_stack_base + POPMARK;
1908
1909 PUTBACK;
1904 } 1910 }
1905 1911
1906 /* now that we have a slf_frame, interpret it! */ 1912 /* now that we have a slf_frame, interpret it! */
1907 /* we use a callback system not to make the code needlessly */ 1913 /* we use a callback system not to make the code needlessly */
1908 /* complicated, but so we can run multiple perl coros from one cctx */ 1914 /* complicated, but so we can run multiple perl coros from one cctx */
1935 } 1941 }
1936 1942
1937 PUTBACK; 1943 PUTBACK;
1938 } 1944 }
1939 1945
1946 {
1947 struct coro *coro = SvSTATE_current;
1948
1949 if (expect_false (coro->throw))
1950 {
1951 SV *exception = sv_2mortal (coro->throw);
1952
1953 coro->throw = 0;
1954 sv_setsv (ERRSV, exception);
1955 croak (0);
1956 }
1957 }
1958
1940 return NORMAL; 1959 return NORMAL;
1941} 1960}
1942 1961
1943static void 1962static void
1944api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, SV **arg, int items) 1963api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, I32 ax)
1945{ 1964{
1965 SV **arg = PL_stack_base + ax;
1966 int items = PL_stack_sp - arg + 1;
1967
1946 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv))); 1968 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv)));
1947 1969
1948 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB] 1970 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
1949 && PL_op->op_ppaddr != pp_slf) 1971 && PL_op->op_ppaddr != pp_slf)
1950 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught"); 1972 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
1951 1973
1974#if 0
1952 if (items > 3) 1975 if (items > 3)
1953 croak ("Coro only supports up to three arguments to SLF functions currently (not %d), caught", items); 1976 croak ("Coro only supports up to three arguments to SLF functions currently (not %d), caught", items);
1977#endif
1954 1978
1955 CvFLAGS (cv) |= CVf_SLF; 1979 CvFLAGS (cv) |= CVf_SLF;
1956 CvXSUBANY (cv).any_ptr = (void *)init_cb; 1980 CvXSUBANY (cv).any_ptr = (void *)init_cb;
1957 slf_cv = cv; 1981 slf_cv = cv;
1958 1982
1959 /* we patch the op, and then re-run the whole call */ 1983 /* we patch the op, and then re-run the whole call */
1960 /* we have to put the same argument on the stack for this to work */ 1984 /* we have to put the same argument on the stack for this to work */
1961 /* and this will be done by pp_restore */ 1985 /* and this will be done by pp_restore */
1962 slf_restore.op_next = (OP *)&slf_restore; 1986 slf_restore.op_next = (OP *)&slf_restore;
1963 slf_restore.op_type = OP_CUSTOM; 1987 slf_restore.op_type = OP_CUSTOM;
1964 slf_restore.op_ppaddr = pp_restore; 1988 slf_restore.op_ppaddr = pp_restore;
1965 slf_restore.op_first = PL_op; 1989 slf_restore.op_first = PL_op;
1966 1990
1991 slf_ax = ax - 1; /* undo the ax++ inside dAXMARK */
1967 slf_arg0 = items > 0 ? SvREFCNT_inc (arg [0]) : 0; 1992 slf_arg0 = items > 0 ? SvREFCNT_inc (arg [0]) : 0;
1968 slf_arg1 = items > 1 ? SvREFCNT_inc (arg [1]) : 0; 1993 slf_arg1 = items > 1 ? SvREFCNT_inc (arg [1]) : 0;
1969 slf_arg2 = items > 2 ? SvREFCNT_inc (arg [2]) : 0; 1994 slf_arg2 = items > 2 ? SvREFCNT_inc (arg [2]) : 0;
1970 1995
1971 PL_op->op_ppaddr = pp_slf; 1996 PL_op->op_ppaddr = pp_slf;
1997 PL_op->op_type = OP_CUSTOM; /* maybe we should leave it at entersub? */
1972 1998
1973 PL_op = (OP *)&slf_restore; 1999 PL_op = (OP *)&slf_restore;
1974} 2000}
1975 2001
1976/*****************************************************************************/ 2002/*****************************************************************************/
1977 2003
1978static void 2004static void
1979coro_semaphore_adjust (AV *av, int adjust) 2005coro_semaphore_adjust (pTHX_ AV *av, IV adjust)
1980{ 2006{
1981 SV *count_sv = AvARRAY (av)[0]; 2007 SV *count_sv = AvARRAY (av)[0];
1982 IV count = SvIVX (count_sv); 2008 IV count = SvIVX (count_sv);
1983 2009
1984 count += adjust; 2010 count += adjust;
1985 SvIVX (count_sv) = count; 2011 SvIVX (count_sv) = count;
1986 2012
1987 /* now wake up as many waiters as possible */ 2013 /* now wake up as many waiters as are expected to lock */
1988 while (count > 0 && AvFILLp (av) >= count) 2014 while (count > 0 && AvFILLp (av) > 0)
1989 { 2015 {
1990 SV *cb; 2016 SV *cb;
1991 2017
1992 /* swap first two elements so we can shift a waiter */ 2018 /* swap first two elements so we can shift a waiter */
1993 AvARRAY (av)[0] = AvARRAY (av)[1]; 2019 AvARRAY (av)[0] = AvARRAY (av)[1];
2006} 2032}
2007 2033
2008static void 2034static void
2009coro_semaphore_on_destroy (pTHX_ struct coro *coro) 2035coro_semaphore_on_destroy (pTHX_ struct coro *coro)
2010{ 2036{
2011 /* call $sem->adjust (0) to possibly wake up some waiters */ 2037 /* call $sem->adjust (0) to possibly wake up some other waiters */
2012 coro_semaphore_adjust ((AV *)coro->slf_frame.data, 0); 2038 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0);
2013} 2039}
2014 2040
2015static int 2041static int
2016slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) 2042slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2017{ 2043{
2018 AV *av = (AV *)frame->data; 2044 AV *av = (AV *)frame->data;
2019 SV *count_sv = AvARRAY (av)[0]; 2045 SV *count_sv = AvARRAY (av)[0];
2020 2046
2021 if (SvIVX (count_sv) > 0) 2047 if (SvIVX (count_sv) > 0)
2022 { 2048 {
2023 SvSTATE (coro_current)->on_destroy = 0; 2049 SvSTATE_current->on_destroy = 0;
2024 SvIVX (count_sv) = SvIVX (count_sv) - 1; 2050 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2025 return 0; 2051 return 0;
2026 } 2052 }
2027 else 2053 else
2028 { 2054 {
2047 2073
2048 if (SvIVX (AvARRAY (av)[0]) > 0) 2074 if (SvIVX (AvARRAY (av)[0]) > 0)
2049 { 2075 {
2050 frame->data = (void *)av; 2076 frame->data = (void *)av;
2051 frame->prepare = prepare_nop; 2077 frame->prepare = prepare_nop;
2078 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2052 } 2079 }
2053 else 2080 else
2054 { 2081 {
2055 av_push (av, SvREFCNT_inc (SvRV (coro_current))); 2082 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2056 2083
2057 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av)); 2084 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2058 frame->prepare = prepare_schedule; 2085 frame->prepare = prepare_schedule;
2059 2086
2060 /* to avoid race conditions when a woken-up coro gets terminated */ 2087 /* to avoid race conditions when a woken-up coro gets terminated */
2061 /* we arrange for a temporary on_destroy that calls adjust (0) */ 2088 /* we arrange for a temporary on_destroy that calls adjust (0) */
2089 assert (!SvSTATE_current->on_destroy);//D
2062 SvSTATE (coro_current)->on_destroy = coro_semaphore_on_destroy; 2090 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2063 } 2091 }
2064 2092
2065 frame->check = slf_check_semaphore_down; 2093 frame->check = slf_check_semaphore_down;
2066 2094
2067} 2095}
2095PROTOTYPES: DISABLE 2123PROTOTYPES: DISABLE
2096 2124
2097BOOT: 2125BOOT:
2098{ 2126{
2099#ifdef USE_ITHREADS 2127#ifdef USE_ITHREADS
2100 MUTEX_INIT (&coro_lock);
2101# if CORO_PTHREAD 2128# if CORO_PTHREAD
2102 coro_thx = PERL_GET_CONTEXT; 2129 coro_thx = PERL_GET_CONTEXT;
2103# endif 2130# endif
2104#endif 2131#endif
2105 BOOT_PAGESIZE; 2132 BOOT_PAGESIZE;
2194 RETVAL 2221 RETVAL
2195 2222
2196void 2223void
2197_set_stacklevel (...) 2224_set_stacklevel (...)
2198 CODE: 2225 CODE:
2199 api_execute_slf (aTHX_ cv, slf_init_set_stacklevel, &ST (0), items); 2226 CORO_EXECUTE_SLF_XS (slf_init_set_stacklevel);
2200 2227
2201void 2228void
2202transfer (...) 2229transfer (...)
2203 PROTOTYPE: $$ 2230 PROTOTYPE: $$
2204 CODE: 2231 CODE:
2205 api_execute_slf (aTHX_ cv, slf_init_transfer, &ST (0), items); 2232 CORO_EXECUTE_SLF_XS (slf_init_transfer);
2206 2233
2207bool 2234bool
2208_destroy (SV *coro_sv) 2235_destroy (SV *coro_sv)
2209 CODE: 2236 CODE:
2210 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); 2237 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
2370 2397
2371void 2398void
2372force_cctx () 2399force_cctx ()
2373 PROTOTYPE: 2400 PROTOTYPE:
2374 CODE: 2401 CODE:
2375 struct coro *coro = SvSTATE (coro_current);
2376 coro->cctx->idle_sp = 0; 2402 SvSTATE_current->cctx->idle_sp = 0;
2377 2403
2378void 2404void
2379swap_defsv (Coro::State self) 2405swap_defsv (Coro::State self)
2380 PROTOTYPE: $ 2406 PROTOTYPE: $
2381 ALIAS: 2407 ALIAS:
2434} 2460}
2435 2461
2436void 2462void
2437schedule (...) 2463schedule (...)
2438 CODE: 2464 CODE:
2439 api_execute_slf (aTHX_ cv, slf_init_schedule, &ST (0), 0); 2465 CORO_EXECUTE_SLF_XS (slf_init_schedule);
2440 2466
2441void 2467void
2442cede (...) 2468cede (...)
2443 CODE: 2469 CODE:
2444 api_execute_slf (aTHX_ cv, slf_init_cede, &ST (0), 0); 2470 CORO_EXECUTE_SLF_XS (slf_init_cede);
2445 2471
2446void 2472void
2447cede_notself (...) 2473cede_notself (...)
2448 CODE: 2474 CODE:
2449 api_execute_slf (aTHX_ cv, slf_init_cede_notself, &ST (0), 0); 2475 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
2450 2476
2451void 2477void
2452_set_current (SV *current) 2478_set_current (SV *current)
2453 PROTOTYPE: $ 2479 PROTOTYPE: $
2454 CODE: 2480 CODE:
2504# for async_pool speedup 2530# for async_pool speedup
2505void 2531void
2506_pool_1 (SV *cb) 2532_pool_1 (SV *cb)
2507 CODE: 2533 CODE:
2508{ 2534{
2509 struct coro *coro = SvSTATE (coro_current);
2510 HV *hv = (HV *)SvRV (coro_current); 2535 HV *hv = (HV *)SvRV (coro_current);
2536 struct coro *coro = SvSTATE_hv ((SV *)hv);
2511 AV *defav = GvAV (PL_defgv); 2537 AV *defav = GvAV (PL_defgv);
2512 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0); 2538 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
2513 AV *invoke_av; 2539 AV *invoke_av;
2514 int i, len; 2540 int i, len;
2515 2541
2542 2568
2543void 2569void
2544_pool_2 (SV *cb) 2570_pool_2 (SV *cb)
2545 CODE: 2571 CODE:
2546{ 2572{
2547 struct coro *coro = SvSTATE (coro_current); 2573 struct coro *coro = SvSTATE_current;
2548 2574
2549 sv_setsv (cb, &PL_sv_undef); 2575 sv_setsv (cb, &PL_sv_undef);
2550 2576
2551 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh; 2577 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
2552 coro->saved_deffh = 0; 2578 coro->saved_deffh = 0;
2684void 2710void
2685up (SV *self, int adjust = 1) 2711up (SV *self, int adjust = 1)
2686 ALIAS: 2712 ALIAS:
2687 adjust = 1 2713 adjust = 1
2688 CODE: 2714 CODE:
2689 coro_semaphore_adjust ((AV *)SvRV (self), ix ? adjust : 1); 2715 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1);
2690 2716
2691void 2717void
2692down (SV *self) 2718down (SV *self)
2693 CODE: 2719 CODE:
2694 api_execute_slf (aTHX_ cv, slf_init_semaphore_down, &ST (0), 1); 2720 CORO_EXECUTE_SLF_XS (slf_init_semaphore_down);
2695 2721
2696void 2722void
2697try (SV *self) 2723try (SV *self)
2698 PPCODE: 2724 PPCODE:
2699{ 2725{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines