… | |
… | |
100 | void *sptr; |
100 | void *sptr; |
101 | long ssize; /* positive == mmap, otherwise malloc */ |
101 | long ssize; /* positive == mmap, otherwise malloc */ |
102 | } coro_stack; |
102 | } coro_stack; |
103 | |
103 | |
104 | struct coro { |
104 | struct coro { |
105 | /* the top-level JMPENV for each coroutine, needed to catch dies. */ |
|
|
106 | JMPENV start_env; |
|
|
107 | |
|
|
108 | /* the optional C context */ |
105 | /* the optional C context */ |
109 | coro_stack *stack; |
106 | coro_stack *stack; |
110 | void *cursp; |
107 | void *cursp; |
111 | int gencnt; |
108 | int gencnt; |
112 | |
109 | |
… | |
… | |
661 | * this is a _very_ stripped down perl interpreter ;) |
658 | * this is a _very_ stripped down perl interpreter ;) |
662 | */ |
659 | */ |
663 | dTHX; |
660 | dTHX; |
664 | Coro__State ctx = (Coro__State)arg; |
661 | Coro__State ctx = (Coro__State)arg; |
665 | |
662 | |
666 | PL_top_env = &ctx->start_env; |
663 | PL_top_env = &PL_start_env; |
667 | |
664 | |
668 | ctx->cursp = 0; |
665 | ctx->cursp = 0; |
669 | PL_op = PL_op->op_next; |
666 | PL_op = PL_op->op_next; |
670 | CALLRUNOPS(aTHX); |
667 | CALLRUNOPS(aTHX); |
671 | |
668 | |
… | |
… | |
677 | { |
674 | { |
678 | dSTACKLEVEL; |
675 | dSTACKLEVEL; |
679 | |
676 | |
680 | if (prev != next) |
677 | if (prev != next) |
681 | { |
678 | { |
|
|
679 | /* has this coro been created yet? */ |
682 | if (next->mainstack) |
680 | if (next->mainstack) |
683 | { |
681 | { |
684 | LOCK; |
682 | LOCK; |
685 | SAVE (prev, flags); |
683 | SAVE (prev, flags); |
686 | LOAD (next); |
684 | LOAD (next); |
… | |
… | |
725 | { |
723 | { |
726 | LOCK; |
724 | LOCK; |
727 | SAVE (prev, -1); /* first get rid of the old state */ |
725 | SAVE (prev, -1); /* first get rid of the old state */ |
728 | UNLOCK; |
726 | UNLOCK; |
729 | |
727 | |
|
|
728 | /* create the coroutine for the first time */ |
730 | if (flags & TRANSFER_SAVE_CCTXT) |
729 | if (flags & TRANSFER_SAVE_CCTXT) |
731 | { |
730 | { |
732 | if (!prev->stack) |
731 | if (!prev->stack) |
733 | allocate_stack (prev, 0); |
732 | allocate_stack (prev, 0); |
734 | |
733 | |
|
|
734 | /* the new coroutine starts with start_env again */ |
|
|
735 | PL_top_env = &PL_start_env; |
|
|
736 | |
735 | if (prev->stack->sptr && flags & TRANSFER_LAZY_STACK) |
737 | if (prev->stack->sptr && flags & TRANSFER_LAZY_STACK) |
736 | { |
738 | { |
737 | PL_top_env = &next->start_env; |
|
|
738 | |
|
|
739 | setup_coro (next); |
739 | setup_coro (next); |
740 | next->cursp = stacklevel; |
740 | next->cursp = stacklevel; |
741 | |
741 | |
742 | prev->stack->refcnt++; |
742 | prev->stack->refcnt++; |
743 | prev->stack->usecnt++; |
743 | prev->stack->usecnt++; |
… | |
… | |
952 | |
952 | |
953 | coro->args = (AV *)SvREFCNT_inc (SvRV (args)); |
953 | coro->args = (AV *)SvREFCNT_inc (SvRV (args)); |
954 | /*coro->mainstack = 0; *//*actual work is done inside transfer */ |
954 | /*coro->mainstack = 0; *//*actual work is done inside transfer */ |
955 | /*coro->stack = 0;*/ |
955 | /*coro->stack = 0;*/ |
956 | |
956 | |
957 | /* same as JMPENV_BOOTSTRAP */ |
|
|
958 | /* we might be able to recycle start_env, but safe is safe */ |
|
|
959 | /*Zero (&coro->start_env, 1, JMPENV);*/ |
|
|
960 | coro->start_env.je_ret = -1; |
|
|
961 | coro->start_env.je_mustcatch = TRUE; |
|
|
962 | |
|
|
963 | RETVAL = coro; |
957 | RETVAL = coro; |
964 | OUTPUT: |
958 | OUTPUT: |
965 | RETVAL |
959 | RETVAL |
966 | |
960 | |
967 | void |
961 | void |
… | |
… | |
1010 | CODE: |
1004 | CODE: |
1011 | _exit (code); |
1005 | _exit (code); |
1012 | |
1006 | |
1013 | MODULE = Coro::State PACKAGE = Coro::Cont |
1007 | MODULE = Coro::State PACKAGE = Coro::Cont |
1014 | |
1008 | |
1015 | # this is slightly dirty (should expose a c-level api) |
|
|
1016 | |
|
|
1017 | void |
1009 | void |
1018 | yield(...) |
1010 | yield(...) |
1019 | PROTOTYPE: @ |
1011 | PROTOTYPE: @ |
1020 | CODE: |
1012 | CODE: |
1021 | SV *yieldstack; |
1013 | SV *yieldstack; |
… | |
… | |
1042 | |
1034 | |
1043 | transfer (aTHX_ prev, next, 0); |
1035 | transfer (aTHX_ prev, next, 0); |
1044 | |
1036 | |
1045 | MODULE = Coro::State PACKAGE = Coro |
1037 | MODULE = Coro::State PACKAGE = Coro |
1046 | |
1038 | |
1047 | # this is slightly dirty (should expose a c-level api) |
|
|
1048 | |
|
|
1049 | BOOT: |
1039 | BOOT: |
1050 | { |
1040 | { |
1051 | int i; |
1041 | int i; |
1052 | HV *stash = gv_stashpv ("Coro", TRUE); |
1042 | HV *stash = gv_stashpv ("Coro", TRUE); |
1053 | |
1043 | |
… | |
… | |
1072 | coroapi.ready = api_ready; |
1062 | coroapi.ready = api_ready; |
1073 | coroapi.nready = &coro_nready; |
1063 | coroapi.nready = &coro_nready; |
1074 | coroapi.current = coro_current; |
1064 | coroapi.current = coro_current; |
1075 | |
1065 | |
1076 | GCoroAPI = &coroapi; |
1066 | GCoroAPI = &coroapi; |
1077 | sv_setiv(sv, (IV)&coroapi); |
1067 | sv_setiv (sv, (IV)&coroapi); |
1078 | SvREADONLY_on(sv); |
1068 | SvREADONLY_on (sv); |
1079 | } |
1069 | } |
1080 | } |
1070 | } |
1081 | |
1071 | |
1082 | #if !PERL_MICRO |
1072 | #if !PERL_MICRO |
1083 | |
1073 | |