… | |
… | |
145 | static size_t coro_stacksize = CORO_STACKSIZE; |
145 | static size_t coro_stacksize = CORO_STACKSIZE; |
146 | static struct CoroAPI coroapi; |
146 | static struct CoroAPI coroapi; |
147 | static AV *main_mainstack; /* used to differentiate between $main and others */ |
147 | static AV *main_mainstack; /* used to differentiate between $main and others */ |
148 | static JMPENV *main_top_env; |
148 | static JMPENV *main_top_env; |
149 | static HV *coro_state_stash, *coro_stash; |
149 | static HV *coro_state_stash, *coro_stash; |
150 | static SV *coro_mortal; /* will be freed after next transfer */ |
150 | static volatile SV *coro_mortal; /* will be freed after next transfer */ |
151 | |
151 | |
152 | static GV *irsgv; /* $/ */ |
152 | static GV *irsgv; /* $/ */ |
153 | static GV *stdoutgv; /* *STDOUT */ |
153 | static GV *stdoutgv; /* *STDOUT */ |
154 | static SV *rv_diehook; |
154 | static SV *rv_diehook; |
155 | static SV *rv_warnhook; |
155 | static SV *rv_warnhook; |
… | |
… | |
1330 | { |
1330 | { |
1331 | av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv); |
1331 | av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv); |
1332 | } |
1332 | } |
1333 | |
1333 | |
1334 | static SV * |
1334 | static SV * |
1335 | coro_deq (pTHX_ int min_prio) |
1335 | coro_deq (pTHX) |
1336 | { |
1336 | { |
1337 | int prio = PRIO_MAX - PRIO_MIN; |
1337 | int prio; |
1338 | |
1338 | |
1339 | min_prio -= PRIO_MIN; |
|
|
1340 | if (min_prio < 0) |
|
|
1341 | min_prio = 0; |
|
|
1342 | |
|
|
1343 | for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; ) |
1339 | for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; ) |
1344 | if (AvFILLp (coro_ready [prio]) >= 0) |
1340 | if (AvFILLp (coro_ready [prio]) >= 0) |
1345 | return av_shift (coro_ready [prio]); |
1341 | return av_shift (coro_ready [prio]); |
1346 | |
1342 | |
1347 | return 0; |
1343 | return 0; |
1348 | } |
1344 | } |
… | |
… | |
1384 | SV *prev_sv, *next_sv; |
1380 | SV *prev_sv, *next_sv; |
1385 | |
1381 | |
1386 | for (;;) |
1382 | for (;;) |
1387 | { |
1383 | { |
1388 | LOCK; |
1384 | LOCK; |
1389 | next_sv = coro_deq (aTHX_ PRIO_MIN); |
1385 | next_sv = coro_deq (aTHX); |
1390 | |
1386 | |
1391 | /* nothing to schedule: call the idle handler */ |
1387 | /* nothing to schedule: call the idle handler */ |
1392 | if (expect_false (!next_sv)) |
1388 | if (expect_false (!next_sv)) |
1393 | { |
1389 | { |
1394 | dSP; |
1390 | dSP; |
… | |
… | |
1398 | SAVETMPS; |
1394 | SAVETMPS; |
1399 | |
1395 | |
1400 | PUSHMARK (SP); |
1396 | PUSHMARK (SP); |
1401 | PUTBACK; |
1397 | PUTBACK; |
1402 | call_sv (get_sv ("Coro::idle", FALSE), G_DISCARD); |
1398 | call_sv (get_sv ("Coro::idle", FALSE), G_DISCARD); |
|
|
1399 | SPAGAIN; |
1403 | |
1400 | |
1404 | FREETMPS; |
1401 | FREETMPS; |
1405 | LEAVE; |
1402 | LEAVE; |
1406 | continue; |
1403 | continue; |
1407 | } |
1404 | } |
… | |
… | |
1607 | Coro::cede_notself = 4 |
1604 | Coro::cede_notself = 4 |
1608 | CODE: |
1605 | CODE: |
1609 | { |
1606 | { |
1610 | struct transfer_args ta; |
1607 | struct transfer_args ta; |
1611 | |
1608 | |
|
|
1609 | PUTBACK; |
1612 | switch (ix) |
1610 | switch (ix) |
1613 | { |
1611 | { |
1614 | case 0: |
1612 | case 0: |
1615 | ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0))); |
1613 | ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0))); |
1616 | ta.next = 0; |
1614 | ta.next = 0; |
… | |
… | |
1635 | if (!prepare_cede_notself (aTHX_ &ta)) |
1633 | if (!prepare_cede_notself (aTHX_ &ta)) |
1636 | XSRETURN_EMPTY; |
1634 | XSRETURN_EMPTY; |
1637 | |
1635 | |
1638 | break; |
1636 | break; |
1639 | } |
1637 | } |
|
|
1638 | SPAGAIN; |
1640 | |
1639 | |
1641 | BARRIER; |
1640 | BARRIER; |
1642 | PUTBACK; |
1641 | PUTBACK; |
1643 | TRANSFER (ta); |
1642 | TRANSFER (ta); |
1644 | SPAGAIN; /* might be the sp of a different coroutine now */ |
1643 | SPAGAIN; /* might be the sp of a different coroutine now */ |
… | |
… | |
1702 | { |
1701 | { |
1703 | struct coro temp; |
1702 | struct coro temp; |
1704 | |
1703 | |
1705 | if (!(coro->flags & CF_RUNNING)) |
1704 | if (!(coro->flags & CF_RUNNING)) |
1706 | { |
1705 | { |
|
|
1706 | PUTBACK; |
1707 | save_perl (aTHX_ &temp); |
1707 | save_perl (aTHX_ &temp); |
1708 | load_perl (aTHX_ coro); |
1708 | load_perl (aTHX_ coro); |
1709 | } |
1709 | } |
1710 | |
1710 | |
1711 | { |
1711 | { |
… | |
… | |
1730 | |
1730 | |
1731 | if (!(coro->flags & CF_RUNNING)) |
1731 | if (!(coro->flags & CF_RUNNING)) |
1732 | { |
1732 | { |
1733 | save_perl (aTHX_ coro); |
1733 | save_perl (aTHX_ coro); |
1734 | load_perl (aTHX_ &temp); |
1734 | load_perl (aTHX_ &temp); |
|
|
1735 | SPAGAIN; |
1735 | } |
1736 | } |
1736 | } |
1737 | } |
1737 | } |
1738 | } |
1738 | |
1739 | |
1739 | SV * |
1740 | SV * |