… | |
… | |
97 | /* cpu state */ |
97 | /* cpu state */ |
98 | void *idle_sp; /* original stacklevel when coroutine was created */ |
98 | void *idle_sp; /* original stacklevel when coroutine was created */ |
99 | JMPENV *top_env; |
99 | JMPENV *top_env; |
100 | coro_context cctx; |
100 | coro_context cctx; |
101 | } coro_stack; |
101 | } coro_stack; |
102 | |
|
|
103 | /* the (fake) coro_stack representing the main program */ |
|
|
104 | static coro_stack *main_stack; |
|
|
105 | |
102 | |
106 | /* this is a structure representing a perl-level coroutine */ |
103 | /* this is a structure representing a perl-level coroutine */ |
107 | struct coro { |
104 | struct coro { |
108 | /* the c coroutine allocated to this perl coroutine, if any */ |
105 | /* the c coroutine allocated to this perl coroutine, if any */ |
109 | coro_stack *stack; |
106 | coro_stack *stack; |
… | |
… | |
647 | } |
644 | } |
648 | |
645 | |
649 | static void |
646 | static void |
650 | stack_free (coro_stack *stack) |
647 | stack_free (coro_stack *stack) |
651 | { |
648 | { |
652 | if (!stack || stack == main_stack) |
649 | if (!stack) |
653 | return; |
650 | return; |
654 | |
651 | |
655 | #if HAVE_MMAP |
652 | #if HAVE_MMAP |
656 | munmap (stack->sptr, stack->ssize); |
653 | munmap (stack->sptr, stack->ssize); |
657 | #else |
654 | #else |
… | |
… | |
719 | setup_coro (next); |
716 | setup_coro (next); |
720 | /* need a stack */ |
717 | /* need a stack */ |
721 | next->stack = 0; |
718 | next->stack = 0; |
722 | } |
719 | } |
723 | |
720 | |
|
|
721 | if (!prev->stack) |
|
|
722 | /* create a new empty context */ |
|
|
723 | Newz (0, prev->stack, 1, coro_stack); |
|
|
724 | |
724 | prev__stack = prev->stack; |
725 | prev__stack = prev->stack; |
725 | |
726 | |
726 | /* possibly "free" the stack */ |
727 | /* possibly "free" the stack */ |
727 | if (prev__stack->idle_sp == STACKLEVEL) |
728 | if (prev__stack->idle_sp == STACKLEVEL) |
728 | { |
729 | { |
… | |
… | |
735 | |
736 | |
736 | if (prev__stack != next->stack) |
737 | if (prev__stack != next->stack) |
737 | { |
738 | { |
738 | prev__stack->top_env = PL_top_env; |
739 | prev__stack->top_env = PL_top_env; |
739 | PL_top_env = next->stack->top_env; |
740 | PL_top_env = next->stack->top_env; |
740 | printf ("stacksw %p %p\n", prev__stack->idle_sp, next->stack->idle_sp);//D |
|
|
741 | coro_transfer (&prev__stack->cctx, &next->stack->cctx); |
741 | coro_transfer (&prev__stack->cctx, &next->stack->cctx); |
742 | } |
742 | } |
743 | |
743 | |
744 | free_coro_mortal (); |
744 | free_coro_mortal (); |
745 | |
745 | |
… | |
… | |
1007 | main_mainstack = PL_mainstack; |
1007 | main_mainstack = PL_mainstack; |
1008 | |
1008 | |
1009 | coroapi.ver = CORO_API_VERSION; |
1009 | coroapi.ver = CORO_API_VERSION; |
1010 | coroapi.transfer = api_transfer; |
1010 | coroapi.transfer = api_transfer; |
1011 | |
1011 | |
1012 | Newz (0, main_stack, 1, coro_stack); |
|
|
1013 | main_stack->idle_sp = (void *)-1; |
|
|
1014 | |
|
|
1015 | assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); |
1012 | assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); |
1016 | } |
1013 | } |
1017 | |
1014 | |
1018 | SV * |
1015 | SV * |
1019 | new (char *klass, ...) |
1016 | new (char *klass, ...) |
… | |
… | |
1031 | RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); |
1028 | RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); |
1032 | |
1029 | |
1033 | for (i = 1; i < items; i++) |
1030 | for (i = 1; i < items; i++) |
1034 | av_push (coro->args, newSVsv (ST (i))); |
1031 | av_push (coro->args, newSVsv (ST (i))); |
1035 | |
1032 | |
1036 | coro->stack = main_stack; |
|
|
1037 | /*coro->mainstack = 0; *//*actual work is done inside transfer */ |
1033 | /*coro->mainstack = 0; *//*actual work is done inside transfer */ |
1038 | /*coro->stack = 0;*/ |
1034 | /*coro->stack = 0;*/ |
1039 | } |
1035 | } |
1040 | OUTPUT: |
1036 | OUTPUT: |
1041 | RETVAL |
1037 | RETVAL |