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.269 by root, Fri Nov 14 06:50:11 2008 UTC vs.
Revision 1.270 by root, Fri Nov 14 07:22:11 2008 UTC

299 299
300/* for Coro.pm */ 300/* for Coro.pm */
301static SV *coro_current; 301static SV *coro_current;
302static SV *coro_readyhook; 302static SV *coro_readyhook;
303static AV *coro_ready [PRIO_MAX - PRIO_MIN + 1]; 303static AV *coro_ready [PRIO_MAX - PRIO_MIN + 1];
304static int coro_nready;
305static struct coro *coro_first; 304static struct coro *coro_first;
305#define coro_nready coroapi.nready
306 306
307/** lowlevel stuff **********************************************************/ 307/** lowlevel stuff **********************************************************/
308 308
309static SV * 309static SV *
310coro_get_sv (pTHX_ const char *name, int create) 310coro_get_sv (pTHX_ const char *name, int create)
1505 ta->next = SvSTATE (next_sv); 1505 ta->next = SvSTATE (next_sv);
1506 TRANSFER_CHECK (*ta); 1506 TRANSFER_CHECK (*ta);
1507} 1507}
1508 1508
1509static void 1509static void
1510api_transfer (SV *prev_sv, SV *next_sv) 1510api_transfer (pTHX_ SV *prev_sv, SV *next_sv)
1511{ 1511{
1512 dTHX;
1513 struct transfer_args ta; 1512 struct transfer_args ta;
1514 1513
1515 prepare_transfer (aTHX_ &ta, prev_sv, next_sv); 1514 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1516 TRANSFER (ta, 1); 1515 TRANSFER (ta, 1);
1517} 1516}
1535 1534
1536 return 0; 1535 return 0;
1537} 1536}
1538 1537
1539static int 1538static int
1540api_ready (SV *coro_sv) 1539api_ready (pTHX_ SV *coro_sv)
1541{ 1540{
1542 dTHX;
1543 struct coro *coro; 1541 struct coro *coro;
1544 SV *sv_hook; 1542 SV *sv_hook;
1545 void (*xs_hook)(void); 1543 void (*xs_hook)(void);
1546 1544
1547 if (SvROK (coro_sv)) 1545 if (SvROK (coro_sv))
1585 1583
1586 return 1; 1584 return 1;
1587} 1585}
1588 1586
1589static int 1587static int
1590api_is_ready (SV *coro_sv) 1588api_is_ready (pTHX_ SV *coro_sv)
1591{ 1589{
1592 dTHX;
1593
1594 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1590 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1595} 1591}
1596 1592
1597INLINE void 1593INLINE void
1598prepare_schedule (pTHX_ struct transfer_args *ta) 1594prepare_schedule (pTHX_ struct transfer_args *ta)
1654} 1650}
1655 1651
1656INLINE void 1652INLINE void
1657prepare_cede (pTHX_ struct transfer_args *ta) 1653prepare_cede (pTHX_ struct transfer_args *ta)
1658{ 1654{
1659 api_ready (coro_current); 1655 api_ready (aTHX_ coro_current);
1660 prepare_schedule (aTHX_ ta); 1656 prepare_schedule (aTHX_ ta);
1661} 1657}
1662 1658
1663static void 1659static void
1664prepare_cede_notself (pTHX_ struct transfer_args *ta) 1660prepare_cede_notself (pTHX_ struct transfer_args *ta)
1666 SV *prev = SvRV (coro_current); 1662 SV *prev = SvRV (coro_current);
1667 1663
1668 if (coro_nready) 1664 if (coro_nready)
1669 { 1665 {
1670 prepare_schedule (aTHX_ ta); 1666 prepare_schedule (aTHX_ ta);
1671 api_ready (prev); 1667 api_ready (aTHX_ prev);
1672 } 1668 }
1673 else 1669 else
1674 ta->prev = ta->next = SvSTATE (prev); 1670 ta->prev = ta->next = SvSTATE (prev);
1675} 1671}
1676 1672
1677static void 1673static void
1678api_schedule (void) 1674api_schedule (pTHX)
1679{ 1675{
1680 dTHX;
1681 struct transfer_args ta; 1676 struct transfer_args ta;
1682 1677
1683 prepare_schedule (aTHX_ &ta); 1678 prepare_schedule (aTHX_ &ta);
1684 TRANSFER (ta, 1); 1679 TRANSFER (ta, 1);
1685} 1680}
1686 1681
1687static int 1682static int
1688api_cede (void) 1683api_cede (pTHX)
1689{ 1684{
1690 dTHX;
1691 struct transfer_args ta; 1685 struct transfer_args ta;
1692 1686
1693 prepare_cede (aTHX_ &ta); 1687 prepare_cede (aTHX_ &ta);
1694 1688
1695 if (expect_true (ta.prev != ta.next)) 1689 if (expect_true (ta.prev != ta.next))
1700 else 1694 else
1701 return 0; 1695 return 0;
1702} 1696}
1703 1697
1704static int 1698static int
1705api_cede_notself (void) 1699api_cede_notself (pTHX)
1706{ 1700{
1707 if (coro_nready) 1701 if (coro_nready)
1708 { 1702 {
1709 dTHX;
1710 struct transfer_args ta; 1703 struct transfer_args ta;
1711 1704
1712 prepare_cede_notself (aTHX_ &ta); 1705 prepare_cede_notself (aTHX_ &ta);
1713 TRANSFER (ta, 1); 1706 TRANSFER (ta, 1);
1714 return 1; 1707 return 1;
1716 else 1709 else
1717 return 0; 1710 return 0;
1718} 1711}
1719 1712
1720static void 1713static void
1721api_trace (SV *coro_sv, int flags) 1714api_trace (pTHX_ SV *coro_sv, int flags)
1722{ 1715{
1723 dTHX;
1724 struct coro *coro = SvSTATE (coro_sv); 1716 struct coro *coro = SvSTATE (coro_sv);
1725 1717
1726 if (flags & CC_TRACE) 1718 if (flags & CC_TRACE)
1727 { 1719 {
1728 if (!coro->cctx) 1720 if (!coro->cctx)
1795 PerlIOCede *self = PerlIOSelf (f, PerlIOCede); 1787 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
1796 double now = nvtime (); 1788 double now = nvtime ();
1797 1789
1798 if (now >= self->next) 1790 if (now >= self->next)
1799 { 1791 {
1800 api_cede (); 1792 api_cede (aTHX);
1801 self->next = now + self->every; 1793 self->next = now + self->every;
1802 } 1794 }
1803 1795
1804 return PerlIOBuf_flush (aTHX_ f); 1796 return PerlIOBuf_flush (aTHX_ f);
1805} 1797}
1862 RETURNOP (slf_restore.op_first); 1854 RETURNOP (slf_restore.op_first);
1863} 1855}
1864 1856
1865#define OPpENTERSUB_SLF 15 /* the part of op_private entersub hopefully doesn't use */ 1857#define OPpENTERSUB_SLF 15 /* the part of op_private entersub hopefully doesn't use */
1866 1858
1859enum {
1860 CORO_SLF_CUSTOM = 0,
1861 CORO_SLF_SET_STACKLEVEL = 1,
1862 CORO_SLF_TRANSFER = 2
1863};
1864
1867/* declare prototype */ 1865/* declare prototype */
1868XS(XS_Coro__State__set_stacklevel); 1866XS(XS_Coro__State__set_stacklevel);
1869 1867
1870/* 1868/*
1871 * these not obviously related functions are all rolled into one 1869 * these not obviously related functions are all rolled into one
1878{ 1876{
1879 dSP; 1877 dSP;
1880 struct transfer_args ta; 1878 struct transfer_args ta;
1881 SV **arg = PL_stack_base + TOPMARK + 1; 1879 SV **arg = PL_stack_base + TOPMARK + 1;
1882 int items = SP - arg; /* args without function object */ 1880 int items = SP - arg; /* args without function object */
1881 int ix = PL_op->op_private & OPpENTERSUB_SLF;
1882 struct CoroSLF *slf = 0;
1883 1883
1884 /* do a quick consistency check on the "function" object, and if it isn't */ 1884 /* do a quick consistency check on the "function" object, and if it isn't */
1885 /* for us, divert to the real entersub */ 1885 /* for us, divert to the real entersub */
1886 if (SvTYPE (*sp) != SVt_PVGV || CvXSUB (GvCV (*sp)) != XS_Coro__State__set_stacklevel) 1886 if (SvTYPE (*sp) != SVt_PVGV || CvXSUB (GvCV (*sp)) != XS_Coro__State__set_stacklevel)
1887 return PL_ppaddr[OP_ENTERSUB](aTHX); 1887 return PL_ppaddr[OP_ENTERSUB](aTHX);
1896 arg = AvARRAY (av); 1896 arg = AvARRAY (av);
1897 items = AvFILLp (av) + 1; 1897 items = AvFILLp (av) + 1;
1898 } 1898 }
1899 1899
1900 PUTBACK; 1900 PUTBACK;
1901 switch (PL_op->op_private & OPpENTERSUB_SLF) 1901
1902 if (!ix)
1903 {
1904 slf = (struct CoroSLF *)CvSTART (GvCV (*sp));
1905 ix = slf->prepare (aTHX_ arg, items);
1902 { 1906 }
1903 case 0: 1907
1908 switch (ix)
1909 {
1910 case CORO_SLF_SET_STACKLEVEL:
1904 prepare_set_stacklevel (&ta, (struct coro_cctx *)SvIV (arg [0])); 1911 prepare_set_stacklevel (&ta, (struct coro_cctx *)SvIV (arg [0]));
1905 break; 1912 break;
1906 1913
1907 case 1: 1914 case CORO_SLF_TRANSFER:
1908 if (items != 2) 1915 if (items != 2)
1909 croak ("Coro::State::transfer (prev, next) expects two arguments, not %d.", items); 1916 croak ("Coro::State::transfer (prev, next) expects two arguments, not %d.", items);
1910 1917
1911 prepare_transfer (aTHX_ &ta, arg [0], arg [1]); 1918 prepare_transfer (aTHX_ &ta, arg [0], arg [1]);
1912 break; 1919 break;
1913 1920
1914 case 2: 1921 case CORO_SLF_SCHEDULE:
1915 prepare_schedule (aTHX_ &ta); 1922 prepare_schedule (aTHX_ &ta);
1916 break; 1923 break;
1917 1924
1918 case 3: 1925 case CORO_SLF_CEDE:
1919 prepare_cede (aTHX_ &ta); 1926 prepare_cede (aTHX_ &ta);
1920 break; 1927 break;
1921 1928
1922 case 4: 1929 case CORO_SLF_CEDE_NOTSELF:
1923 prepare_cede_notself (aTHX_ &ta); 1930 prepare_cede_notself (aTHX_ &ta);
1924 break; 1931 break;
1925 1932
1926 case 5:
1927 abort ();
1928
1929 default: 1933 default:
1930 abort (); 1934 abort ();
1931 } 1935 }
1932 1936
1937 do
1933 TRANSFER (ta, 0); 1938 TRANSFER (ta, 0);
1939 while (slf && slf->check (aTHX));
1940
1934 SPAGAIN; 1941 SPAGAIN;
1935 1942
1936 PUTBACK; 1943 PUTBACK;
1937 SLF_TAIL; 1944 SLF_TAIL;
1938 SPAGAIN; 1945 SPAGAIN;
2048 RETVAL 2055 RETVAL
2049 2056
2050void 2057void
2051_set_stacklevel (...) 2058_set_stacklevel (...)
2052 ALIAS: 2059 ALIAS:
2060 _set_stacklevel = CORO_SLF_SET_STACKLEVEL
2053 Coro::State::transfer = 1 2061 Coro::State::transfer = CORO_SLF_TRANSFER
2054 Coro::schedule = 2 2062 Coro::schedule = CORO_SLF_SCHEDULE
2055 Coro::cede = 3 2063 Coro::cede = CORO_SLF_CEDE
2056 Coro::cede_notself = 4 2064 Coro::cede_notself = CORO_SLF_CEDE_NOTSELF
2057 CODE: 2065 CODE:
2058 coro_slf_patch (aTHX_ cv, ix, &ST (0), items); 2066 coro_slf_patch (aTHX_ cv, ix, &ST (0), items);
2059 2067
2060bool 2068bool
2061_destroy (SV *coro_sv) 2069_destroy (SV *coro_sv)
2181 SvREFCNT_dec (self->throw); 2189 SvREFCNT_dec (self->throw);
2182 self->throw = SvOK (throw) ? newSVsv (throw) : 0; 2190 self->throw = SvOK (throw) ? newSVsv (throw) : 0;
2183 2191
2184void 2192void
2185api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB) 2193api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
2194 C_ARGS: aTHX_ coro, flags
2186 2195
2187SV * 2196SV *
2188has_cctx (Coro::State coro) 2197has_cctx (Coro::State coro)
2189 PROTOTYPE: $ 2198 PROTOTYPE: $
2190 CODE: 2199 CODE:
2267 coroapi.schedule = api_schedule; 2276 coroapi.schedule = api_schedule;
2268 coroapi.cede = api_cede; 2277 coroapi.cede = api_cede;
2269 coroapi.cede_notself = api_cede_notself; 2278 coroapi.cede_notself = api_cede_notself;
2270 coroapi.ready = api_ready; 2279 coroapi.ready = api_ready;
2271 coroapi.is_ready = api_is_ready; 2280 coroapi.is_ready = api_is_ready;
2272 coroapi.nready = &coro_nready; 2281 coroapi.nready = coro_nready;
2273 coroapi.current = coro_current; 2282 coroapi.current = coro_current;
2274 2283
2275 GCoroAPI = &coroapi; 2284 GCoroAPI = &coroapi;
2276 sv_setiv (sv, (IV)&coroapi); 2285 sv_setiv (sv, (IV)&coroapi);
2277 SvREADONLY_on (sv); 2286 SvREADONLY_on (sv);
2318 2327
2319SV * 2328SV *
2320ready (SV *self) 2329ready (SV *self)
2321 PROTOTYPE: $ 2330 PROTOTYPE: $
2322 CODE: 2331 CODE:
2323 RETVAL = boolSV (api_ready (self)); 2332 RETVAL = boolSV (api_ready (aTHX_ self));
2324 OUTPUT: 2333 OUTPUT:
2325 RETVAL 2334 RETVAL
2326 2335
2327int 2336int
2328nready (...) 2337nready (...)
2398 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0); 2407 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
2399 2408
2400 coro->prio = 0; 2409 coro->prio = 0;
2401 2410
2402 if (coro->cctx && (coro->cctx->flags & CC_TRACE)) 2411 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
2403 api_trace (coro_current, 0); 2412 api_trace (aTHX_ coro_current, 0);
2404 2413
2405 av_push (av_async_pool, newSVsv (coro_current)); 2414 av_push (av_async_pool, newSVsv (coro_current));
2406} 2415}
2407 2416
2408#if 0 2417#if 0
2480 2489
2481 av_push (av, data_sv); 2490 av_push (av, data_sv);
2482 2491
2483 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av))); 2492 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
2484 2493
2485 api_ready (self); 2494 api_ready (aTHX_ self);
2486} 2495}
2487 2496
2488void 2497void
2489_set_state (SV *state) 2498_set_state (SV *state)
2490 PROTOTYPE: $ 2499 PROTOTYPE: $
2515 PROTOTYPE: @ 2524 PROTOTYPE: @
2516 CODE: 2525 CODE:
2517{ 2526{
2518 static int incede; 2527 static int incede;
2519 2528
2520 api_cede_notself (); 2529 api_cede_notself (aTHX);
2521 2530
2522 ++incede; 2531 ++incede;
2523 while (coro_nready >= incede && api_cede ()) 2532 while (coro_nready >= incede && api_cede (aTHX))
2524 ; 2533 ;
2525 2534
2526 sv_setsv (sv_activity, &PL_sv_undef); 2535 sv_setsv (sv_activity, &PL_sv_undef);
2527 if (coro_nready >= incede) 2536 if (coro_nready >= incede)
2528 { 2537 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines