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.215 by root, Sun Oct 14 19:34:09 2007 UTC vs.
Revision 1.219 by root, Tue Dec 4 19:33:45 2007 UTC

145static size_t coro_stacksize = CORO_STACKSIZE; 145static size_t coro_stacksize = CORO_STACKSIZE;
146static struct CoroAPI coroapi; 146static struct CoroAPI coroapi;
147static AV *main_mainstack; /* used to differentiate between $main and others */ 147static AV *main_mainstack; /* used to differentiate between $main and others */
148static JMPENV *main_top_env; 148static JMPENV *main_top_env;
149static HV *coro_state_stash, *coro_stash; 149static HV *coro_state_stash, *coro_stash;
150static SV *coro_mortal; /* will be freed after next transfer */ 150static volatile SV *coro_mortal; /* will be freed after next transfer */
151 151
152static GV *irsgv; /* $/ */ 152static GV *irsgv; /* $/ */
153static GV *stdoutgv; /* *STDOUT */ 153static GV *stdoutgv; /* *STDOUT */
154static SV *rv_diehook; 154static SV *rv_diehook;
155static SV *rv_warnhook; 155static SV *rv_warnhook;
1120/* always use the TRANSFER macro */ 1120/* always use the TRANSFER macro */
1121static void NOINLINE 1121static void NOINLINE
1122transfer (pTHX_ struct coro *prev, struct coro *next) 1122transfer (pTHX_ struct coro *prev, struct coro *next)
1123{ 1123{
1124 dSTACKLEVEL; 1124 dSTACKLEVEL;
1125 static volatile int has_throw;
1125 1126
1126 /* sometimes transfer is only called to set idle_sp */ 1127 /* sometimes transfer is only called to set idle_sp */
1127 if (expect_false (!next)) 1128 if (expect_false (!next))
1128 { 1129 {
1129 ((coro_cctx *)prev)->idle_sp = STACKLEVEL; 1130 ((coro_cctx *)prev)->idle_sp = STACKLEVEL;
1181 ++next->usecount; 1182 ++next->usecount;
1182 1183
1183 if (expect_true (!next->cctx)) 1184 if (expect_true (!next->cctx))
1184 next->cctx = cctx_get (aTHX); 1185 next->cctx = cctx_get (aTHX);
1185 1186
1187 has_throw = !!next->throw;
1188
1186 if (expect_false (prev__cctx != next->cctx)) 1189 if (expect_false (prev__cctx != next->cctx))
1187 { 1190 {
1188 prev__cctx->top_env = PL_top_env; 1191 prev__cctx->top_env = PL_top_env;
1189 PL_top_env = next->cctx->top_env; 1192 PL_top_env = next->cctx->top_env;
1190 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx); 1193 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx);
1191 } 1194 }
1192 1195
1193 free_coro_mortal (aTHX); 1196 free_coro_mortal (aTHX);
1194 UNLOCK; 1197 UNLOCK;
1195 1198
1196 if (expect_false (prev->throw || next->throw)) 1199 if (expect_false (has_throw))
1197 { 1200 {
1198 struct coro *coro = SvSTATE (coro_current); 1201 struct coro *coro = SvSTATE (coro_current);
1199 1202
1200 if (coro->throw) 1203 if (coro->throw)
1201 { 1204 {
1327{ 1330{
1328 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);
1329} 1332}
1330 1333
1331static SV * 1334static SV *
1332coro_deq (pTHX_ int min_prio) 1335coro_deq (pTHX)
1333{ 1336{
1334 int prio = PRIO_MAX - PRIO_MIN; 1337 int prio;
1335 1338
1336 min_prio -= PRIO_MIN;
1337 if (min_prio < 0)
1338 min_prio = 0;
1339
1340 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; ) 1339 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; )
1341 if (AvFILLp (coro_ready [prio]) >= 0) 1340 if (AvFILLp (coro_ready [prio]) >= 0)
1342 return av_shift (coro_ready [prio]); 1341 return av_shift (coro_ready [prio]);
1343 1342
1344 return 0; 1343 return 0;
1345} 1344}
1381 SV *prev_sv, *next_sv; 1380 SV *prev_sv, *next_sv;
1382 1381
1383 for (;;) 1382 for (;;)
1384 { 1383 {
1385 LOCK; 1384 LOCK;
1386 next_sv = coro_deq (aTHX_ PRIO_MIN); 1385 next_sv = coro_deq (aTHX);
1387 1386
1388 /* nothing to schedule: call the idle handler */ 1387 /* nothing to schedule: call the idle handler */
1389 if (expect_false (!next_sv)) 1388 if (expect_false (!next_sv))
1390 { 1389 {
1391 dSP; 1390 dSP;
1395 SAVETMPS; 1394 SAVETMPS;
1396 1395
1397 PUSHMARK (SP); 1396 PUSHMARK (SP);
1398 PUTBACK; 1397 PUTBACK;
1399 call_sv (get_sv ("Coro::idle", FALSE), G_DISCARD); 1398 call_sv (get_sv ("Coro::idle", FALSE), G_DISCARD);
1399 SPAGAIN;
1400 1400
1401 FREETMPS; 1401 FREETMPS;
1402 LEAVE; 1402 LEAVE;
1403 continue; 1403 continue;
1404 } 1404 }
1604 Coro::cede_notself = 4 1604 Coro::cede_notself = 4
1605 CODE: 1605 CODE:
1606{ 1606{
1607 struct transfer_args ta; 1607 struct transfer_args ta;
1608 1608
1609 PUTBACK;
1609 switch (ix) 1610 switch (ix)
1610 { 1611 {
1611 case 0: 1612 case 0:
1612 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0))); 1613 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0)));
1613 ta.next = 0; 1614 ta.next = 0;
1632 if (!prepare_cede_notself (aTHX_ &ta)) 1633 if (!prepare_cede_notself (aTHX_ &ta))
1633 XSRETURN_EMPTY; 1634 XSRETURN_EMPTY;
1634 1635
1635 break; 1636 break;
1636 } 1637 }
1638 SPAGAIN;
1637 1639
1638 BARRIER; 1640 BARRIER;
1639 PUTBACK; 1641 PUTBACK;
1640 TRANSFER (ta); 1642 TRANSFER (ta);
1641 SPAGAIN; /* might be the sp of a different coroutine now */ 1643 SPAGAIN; /* might be the sp of a different coroutine now */
1699 { 1701 {
1700 struct coro temp; 1702 struct coro temp;
1701 1703
1702 if (!(coro->flags & CF_RUNNING)) 1704 if (!(coro->flags & CF_RUNNING))
1703 { 1705 {
1706 PUTBACK;
1704 save_perl (aTHX_ &temp); 1707 save_perl (aTHX_ &temp);
1705 load_perl (aTHX_ coro); 1708 load_perl (aTHX_ coro);
1706 } 1709 }
1707 1710
1708 { 1711 {
1727 1730
1728 if (!(coro->flags & CF_RUNNING)) 1731 if (!(coro->flags & CF_RUNNING))
1729 { 1732 {
1730 save_perl (aTHX_ coro); 1733 save_perl (aTHX_ coro);
1731 load_perl (aTHX_ &temp); 1734 load_perl (aTHX_ &temp);
1735 SPAGAIN;
1732 } 1736 }
1733 } 1737 }
1734} 1738}
1735 1739
1736SV * 1740SV *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines