… | |
… | |
102 | |
102 | |
103 | static struct CoroAPI coroapi; |
103 | static struct CoroAPI coroapi; |
104 | static AV *main_mainstack; /* used to differentiate between $main and others */ |
104 | static AV *main_mainstack; /* used to differentiate between $main and others */ |
105 | static HV *coro_state_stash, *coro_stash; |
105 | static HV *coro_state_stash, *coro_stash; |
106 | static SV *coro_mortal; /* will be freed after next transfer */ |
106 | static SV *coro_mortal; /* will be freed after next transfer */ |
|
|
107 | |
|
|
108 | static struct coro_cctx *cctx_first; |
|
|
109 | static int cctx_count, cctx_idle; |
107 | |
110 | |
108 | /* this is a structure representing a c-level coroutine */ |
111 | /* this is a structure representing a c-level coroutine */ |
109 | typedef struct coro_cctx { |
112 | typedef struct coro_cctx { |
110 | struct coro_cctx *next; |
113 | struct coro_cctx *next; |
111 | |
114 | |
… | |
… | |
578 | myop.op_flags = OPf_WANT_VOID; |
581 | myop.op_flags = OPf_WANT_VOID; |
579 | |
582 | |
580 | PL_op = (OP *)&myop; |
583 | PL_op = (OP *)&myop; |
581 | |
584 | |
582 | PUSHMARK (SP); |
585 | PUSHMARK (SP); |
583 | XPUSHs ((SV *)get_cv ("Coro::State::coro_init", FALSE)); |
586 | XPUSHs ((SV *)get_cv ("Coro::State::_coro_init", FALSE)); |
584 | PUTBACK; |
587 | PUTBACK; |
585 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
588 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
586 | SPAGAIN; |
589 | SPAGAIN; |
587 | |
590 | |
588 | ENTER; /* necessary e.g. for dounwind */ |
591 | ENTER; /* necessary e.g. for dounwind */ |
… | |
… | |
607 | |
610 | |
608 | Zero (&myop, 1, LOGOP); |
611 | Zero (&myop, 1, LOGOP); |
609 | myop.op_next = PL_op; |
612 | myop.op_next = PL_op; |
610 | myop.op_flags = OPf_WANT_VOID; |
613 | myop.op_flags = OPf_WANT_VOID; |
611 | |
614 | |
612 | sv_setiv (get_sv ("Coro::State::cctx", FALSE), PTR2IV (cctx)); |
615 | sv_setiv (get_sv ("Coro::State::_cctx", FALSE), PTR2IV (cctx)); |
613 | |
616 | |
614 | PUSHMARK (SP); |
617 | PUSHMARK (SP); |
615 | XPUSHs ((SV *)get_cv ("Coro::State::cctx_init", FALSE)); |
618 | XPUSHs ((SV *)get_cv ("Coro::State::_cctx_init", FALSE)); |
616 | PUTBACK; |
619 | PUTBACK; |
617 | PL_restartop = PL_ppaddr[OP_ENTERSUB](aTHX); |
620 | PL_restartop = PL_ppaddr[OP_ENTERSUB](aTHX); |
618 | SPAGAIN; |
621 | SPAGAIN; |
619 | } |
622 | } |
620 | |
623 | |
… | |
… | |
626 | |
629 | |
627 | /* |
630 | /* |
628 | * this is a _very_ stripped down perl interpreter ;) |
631 | * this is a _very_ stripped down perl interpreter ;) |
629 | */ |
632 | */ |
630 | PL_top_env = &PL_start_env; |
633 | PL_top_env = &PL_start_env; |
|
|
634 | |
631 | /* inject call to cctx_init */ |
635 | /* inject call to cctx_init */ |
632 | prepare_cctx ((coro_cctx *)arg); |
636 | prepare_cctx ((coro_cctx *)arg); |
633 | |
637 | |
634 | /* somebody will hit me for both perl_run and PL_restartop */ |
638 | /* somebody will hit me for both perl_run and PL_restartop */ |
635 | perl_run (PL_curinterp); |
639 | perl_run (PL_curinterp); |
… | |
… | |
640 | |
644 | |
641 | static coro_cctx * |
645 | static coro_cctx * |
642 | cctx_new () |
646 | cctx_new () |
643 | { |
647 | { |
644 | coro_cctx *cctx; |
648 | coro_cctx *cctx; |
|
|
649 | |
|
|
650 | ++cctx_count; |
645 | |
651 | |
646 | New (0, cctx, 1, coro_cctx); |
652 | New (0, cctx, 1, coro_cctx); |
647 | |
653 | |
648 | #if HAVE_MMAP |
654 | #if HAVE_MMAP |
649 | |
655 | |
… | |
… | |
690 | cctx_free (coro_cctx *cctx) |
696 | cctx_free (coro_cctx *cctx) |
691 | { |
697 | { |
692 | if (!cctx) |
698 | if (!cctx) |
693 | return; |
699 | return; |
694 | |
700 | |
|
|
701 | --cctx_count; |
|
|
702 | |
695 | #if USE_VALGRIND |
703 | #if USE_VALGRIND |
696 | VALGRIND_STACK_DEREGISTER (cctx->valgrind_id); |
704 | VALGRIND_STACK_DEREGISTER (cctx->valgrind_id); |
697 | #endif |
705 | #endif |
698 | |
706 | |
699 | #if HAVE_MMAP |
707 | #if HAVE_MMAP |
… | |
… | |
702 | Safefree (cctx->sptr); |
710 | Safefree (cctx->sptr); |
703 | #endif |
711 | #endif |
704 | |
712 | |
705 | Safefree (cctx); |
713 | Safefree (cctx); |
706 | } |
714 | } |
707 | |
|
|
708 | static coro_cctx *cctx_first; |
|
|
709 | static int cctx_count, cctx_idle; |
|
|
710 | |
715 | |
711 | static coro_cctx * |
716 | static coro_cctx * |
712 | cctx_get () |
717 | cctx_get () |
713 | { |
718 | { |
714 | coro_cctx *cctx; |
719 | coro_cctx *cctx; |
… | |
… | |
719 | cctx = cctx_first; |
724 | cctx = cctx_first; |
720 | cctx_first = cctx->next; |
725 | cctx_first = cctx->next; |
721 | } |
726 | } |
722 | else |
727 | else |
723 | { |
728 | { |
724 | ++cctx_count; |
|
|
725 | cctx = cctx_new (); |
729 | cctx = cctx_new (); |
726 | PL_op = PL_op->op_next; |
730 | PL_op = PL_op->op_next; |
727 | } |
731 | } |
728 | |
732 | |
729 | return cctx; |
733 | return cctx; |