… | |
… | |
713 | prev->flags &= ~CF_RUNNING; |
713 | prev->flags &= ~CF_RUNNING; |
714 | next->flags |= CF_RUNNING; |
714 | next->flags |= CF_RUNNING; |
715 | |
715 | |
716 | LOCK; |
716 | LOCK; |
717 | |
717 | |
718 | if (next->mainstack) |
718 | if (next->flags & CF_NEW) |
719 | { |
|
|
720 | /* coroutine already started */ |
|
|
721 | SAVE (prev, flags); |
|
|
722 | LOAD (next); |
|
|
723 | } |
|
|
724 | else |
|
|
725 | { |
719 | { |
726 | /* need to start coroutine */ |
720 | /* need to start coroutine */ |
727 | assert (next->flags & CF_NEW); |
|
|
728 | next->flags &= ~CF_NEW; |
721 | next->flags &= ~CF_NEW; |
729 | /* first get rid of the old state */ |
722 | /* first get rid of the old state */ |
730 | SAVE (prev, -1); |
723 | SAVE (prev, -1); |
731 | /* setup coroutine call */ |
724 | /* setup coroutine call */ |
732 | setup_coro (next); |
725 | setup_coro (next); |
733 | /* need a new stack */ |
726 | /* need a new stack */ |
734 | assert (!next->stack); |
727 | assert (!next->stack); |
735 | } |
728 | } |
|
|
729 | else |
|
|
730 | { |
|
|
731 | /* coroutine already started */ |
|
|
732 | SAVE (prev, flags); |
|
|
733 | LOAD (next); |
|
|
734 | } |
736 | |
735 | |
737 | prev__cctx = prev->cctx; |
736 | prev__cctx = prev->cctx; |
738 | |
737 | |
739 | /* possibly "free" the cctx */ |
738 | /* possibly "free" the cctx */ |
740 | if (prev__cctx->idle_sp == STACKLEVEL && 0) |
739 | if (prev__cctx->idle_sp == STACKLEVEL && 0) |
… | |
… | |
1074 | _set_stacklevel (...) |
1073 | _set_stacklevel (...) |
1075 | ALIAS: |
1074 | ALIAS: |
1076 | Coro::State::transfer = 1 |
1075 | Coro::State::transfer = 1 |
1077 | Coro::schedule = 2 |
1076 | Coro::schedule = 2 |
1078 | Coro::cede = 3 |
1077 | Coro::cede = 3 |
1079 | Coro::Cont::yield = 4 |
|
|
1080 | CODE: |
1078 | CODE: |
1081 | { |
1079 | { |
1082 | struct transfer_args ta; |
1080 | struct transfer_args ta; |
1083 | |
1081 | |
1084 | switch (ix) |
1082 | switch (ix) |
… | |
… | |
1101 | break; |
1099 | break; |
1102 | |
1100 | |
1103 | case 3: |
1101 | case 3: |
1104 | prepare_cede (&ta); |
1102 | prepare_cede (&ta); |
1105 | break; |
1103 | break; |
1106 | |
|
|
1107 | case 4: |
|
|
1108 | { |
|
|
1109 | SV *yieldstack; |
|
|
1110 | SV *sv; |
|
|
1111 | AV *defav = GvAV (PL_defgv); |
|
|
1112 | |
|
|
1113 | yieldstack = *hv_fetch ( |
|
|
1114 | (HV *)SvRV (coro_current), |
|
|
1115 | "yieldstack", sizeof ("yieldstack") - 1, |
|
|
1116 | 0 |
|
|
1117 | ); |
|
|
1118 | |
|
|
1119 | /* set up @_ -- ugly */ |
|
|
1120 | av_clear (defav); |
|
|
1121 | av_fill (defav, items - 1); |
|
|
1122 | while (items--) |
|
|
1123 | av_store (defav, items, SvREFCNT_inc (ST(items))); |
|
|
1124 | |
|
|
1125 | sv = av_pop ((AV *)SvRV (yieldstack)); |
|
|
1126 | ta.prev = SvSTATE (*av_fetch ((AV *)SvRV (sv), 0, 0)); |
|
|
1127 | ta.next = SvSTATE (*av_fetch ((AV *)SvRV (sv), 1, 0)); |
|
|
1128 | ta.flags = 0; |
|
|
1129 | SvREFCNT_dec (sv); |
|
|
1130 | } |
|
|
1131 | break; |
|
|
1132 | |
|
|
1133 | } |
1104 | } |
1134 | |
1105 | |
1135 | TRANSFER (ta); |
1106 | TRANSFER (ta); |
1136 | } |
1107 | } |
1137 | |
1108 | |