… | |
… | |
3 | #include "EXTERN.h" |
3 | #include "EXTERN.h" |
4 | #include "perl.h" |
4 | #include "perl.h" |
5 | #include "XSUB.h" |
5 | #include "XSUB.h" |
6 | |
6 | |
7 | #include "patchlevel.h" |
7 | #include "patchlevel.h" |
|
|
8 | |
|
|
9 | #if USE_VALGRIND |
|
|
10 | # include <valgrind/valgrind.h> |
|
|
11 | #endif |
8 | |
12 | |
9 | #define PERL_VERSION_ATLEAST(a,b,c) \ |
13 | #define PERL_VERSION_ATLEAST(a,b,c) \ |
10 | (PERL_REVISION > (a) \ |
14 | (PERL_REVISION > (a) \ |
11 | || (PERL_REVISION == (a) \ |
15 | || (PERL_REVISION == (a) \ |
12 | && (PERL_VERSION > (b) \ |
16 | && (PERL_VERSION > (b) \ |
… | |
… | |
108 | |
112 | |
109 | /* cpu state */ |
113 | /* cpu state */ |
110 | void *idle_sp; /* sp of top-level transfer/schedule/cede call */ |
114 | void *idle_sp; /* sp of top-level transfer/schedule/cede call */ |
111 | JMPENV *top_env; |
115 | JMPENV *top_env; |
112 | coro_context cctx; |
116 | coro_context cctx; |
|
|
117 | |
|
|
118 | #if USE_VALGRIND |
|
|
119 | int valgrind_id; |
|
|
120 | #endif |
113 | } coro_stack; |
121 | } coro_stack; |
114 | |
122 | |
115 | /* this is a structure representing a perl-level coroutine */ |
123 | /* this is a structure representing a perl-level coroutine */ |
116 | struct coro { |
124 | struct coro { |
117 | /* the c coroutine allocated to this perl coroutine, if any */ |
125 | /* the c coroutine allocated to this perl coroutine, if any */ |
… | |
… | |
546 | * emulate part of the perl startup here. |
554 | * emulate part of the perl startup here. |
547 | */ |
555 | */ |
548 | |
556 | |
549 | coro_init_stacks (); |
557 | coro_init_stacks (); |
550 | |
558 | |
|
|
559 | PL_curcop = 0; |
|
|
560 | PL_in_eval = 0; |
|
|
561 | PL_curpm = 0; |
|
|
562 | |
551 | { |
563 | { |
552 | dSP; |
564 | dSP; |
553 | LOGOP myop; |
565 | LOGOP myop; |
554 | |
566 | |
555 | /*PL_curcop = 0;*/ |
567 | /* I have no idea why this is needed, but it is */ |
556 | PL_in_eval = 0; |
568 | PUSHMARK (SP); |
|
|
569 | |
557 | SvREFCNT_dec (GvAV (PL_defgv)); |
570 | SvREFCNT_dec (GvAV (PL_defgv)); |
558 | GvAV (PL_defgv) = coro->args; coro->args = 0; |
571 | GvAV (PL_defgv) = coro->args; coro->args = 0; |
559 | |
|
|
560 | SPAGAIN; |
|
|
561 | |
572 | |
562 | Zero (&myop, 1, LOGOP); |
573 | Zero (&myop, 1, LOGOP); |
563 | myop.op_next = Nullop; |
574 | myop.op_next = Nullop; |
564 | myop.op_flags = OPf_WANT_VOID; |
575 | myop.op_flags = OPf_WANT_VOID; |
565 | |
576 | |
566 | PL_op = (OP *)&myop; |
577 | PL_op = (OP *)&myop; |
567 | |
578 | |
568 | PUSHMARK (SP); |
|
|
569 | PUSHMARK (SP); |
579 | PUSHMARK (SP); |
570 | XPUSHs ((SV *)get_cv ("Coro::State::coro_init", FALSE)); |
580 | XPUSHs ((SV *)get_cv ("Coro::State::coro_init", FALSE)); |
571 | PUTBACK; |
581 | PUTBACK; |
572 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
582 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
573 | SPAGAIN; |
583 | SPAGAIN; |
… | |
… | |
659 | _exit (EXIT_FAILURE); |
669 | _exit (EXIT_FAILURE); |
660 | } |
670 | } |
661 | |
671 | |
662 | #endif |
672 | #endif |
663 | |
673 | |
|
|
674 | #if USE_VALGRIND |
|
|
675 | stack->valgrind_id = VALGRIND_STACK_REGISTER ( |
|
|
676 | STACKGUARD * PAGESIZE + (char *)stack->sptr, |
|
|
677 | stack->ssize + (char *)stack->sptr |
|
|
678 | ); |
|
|
679 | #endif |
|
|
680 | |
664 | coro_create (&stack->cctx, coro_run, (void *)stack, stack->sptr, stack->ssize); |
681 | coro_create (&stack->cctx, coro_run, (void *)stack, stack->sptr, stack->ssize); |
665 | |
682 | |
666 | return stack; |
683 | return stack; |
667 | } |
684 | } |
668 | |
685 | |
669 | static void |
686 | static void |
670 | stack_free (coro_stack *stack) |
687 | stack_free (coro_stack *stack) |
671 | { |
688 | { |
672 | if (!stack) |
689 | if (!stack) |
673 | return; |
690 | return; |
|
|
691 | |
|
|
692 | #if USE_VALGRIND |
|
|
693 | VALGRIND_STACK_DEREGISTER (stack->valgrind_id); |
|
|
694 | #endif |
674 | |
695 | |
675 | #if HAVE_MMAP |
696 | #if HAVE_MMAP |
676 | munmap (stack->sptr, stack->ssize); |
697 | munmap (stack->sptr, stack->ssize); |
677 | #else |
698 | #else |
678 | Safefree (stack->sptr); |
699 | Safefree (stack->sptr); |