… | |
… | |
436 | * not usually need a lot of stackspace. |
436 | * not usually need a lot of stackspace. |
437 | */ |
437 | */ |
438 | static void |
438 | static void |
439 | coro_init_stacks () |
439 | coro_init_stacks () |
440 | { |
440 | { |
441 | LOCK; |
|
|
442 | |
|
|
443 | PL_curstackinfo = new_stackinfo(96, 1024/sizeof(PERL_CONTEXT) - 1); |
441 | PL_curstackinfo = new_stackinfo(96, 1024/sizeof(PERL_CONTEXT) - 1); |
444 | PL_curstackinfo->si_type = PERLSI_MAIN; |
442 | PL_curstackinfo->si_type = PERLSI_MAIN; |
445 | PL_curstack = PL_curstackinfo->si_stack; |
443 | PL_curstack = PL_curstackinfo->si_stack; |
446 | PL_mainstack = PL_curstack; /* remember in case we switch stacks */ |
444 | PL_mainstack = PL_curstack; /* remember in case we switch stacks */ |
447 | |
445 | |
… | |
… | |
473 | #if PERL_VERSION < 9 |
471 | #if PERL_VERSION < 9 |
474 | New(54,PL_retstack,8,OP*); |
472 | New(54,PL_retstack,8,OP*); |
475 | PL_retstack_ix = 0; |
473 | PL_retstack_ix = 0; |
476 | PL_retstack_max = 8; |
474 | PL_retstack_max = 8; |
477 | #endif |
475 | #endif |
478 | |
|
|
479 | UNLOCK; |
|
|
480 | } |
476 | } |
481 | |
477 | |
482 | /* |
478 | /* |
483 | * destroy the stacks, the callchain etc... |
479 | * destroy the stacks, the callchain etc... |
484 | */ |
480 | */ |
… | |
… | |
572 | coro_mortal = 0; |
568 | coro_mortal = 0; |
573 | } |
569 | } |
574 | } |
570 | } |
575 | |
571 | |
576 | static void |
572 | static void |
|
|
573 | prepare_cctx (coro_stack *cctx) |
|
|
574 | { |
|
|
575 | dSP; |
|
|
576 | UNOP myop; |
|
|
577 | |
|
|
578 | Zero (&myop, 1, UNOP); |
|
|
579 | myop.op_next = PL_op; |
|
|
580 | myop.op_flags = OPf_WANT_VOID | OPf_STACKED; |
|
|
581 | |
|
|
582 | PUSHMARK(SP); |
|
|
583 | EXTEND (SP, 2); |
|
|
584 | PUSHs (newSViv (PTR2IV (cctx))); |
|
|
585 | PUSHs ((SV *)get_cv ("Coro::State::cctx_init", FALSE)); |
|
|
586 | PUTBACK; |
|
|
587 | PL_restartop = PL_ppaddr[OP_ENTERSUB](aTHX); |
|
|
588 | SPAGAIN; |
|
|
589 | } |
|
|
590 | |
|
|
591 | static void |
577 | coro_run (void *arg) |
592 | coro_run (void *arg) |
578 | { |
593 | { |
579 | /* |
594 | /* |
580 | * this is a _very_ stripped down perl interpreter ;) |
595 | * this is a _very_ stripped down perl interpreter ;) |
581 | */ |
596 | */ |
582 | dTHX; |
|
|
583 | int ret; |
|
|
584 | |
|
|
585 | UNLOCK; |
597 | UNLOCK; |
586 | |
598 | |
587 | PL_top_env = &PL_start_env; |
599 | PL_top_env = &PL_start_env; |
588 | |
600 | prepare_cctx ((coro_stack *)arg); |
589 | sv_setiv (get_sv ("Coro::State::cctx_stack", FALSE), PTR2IV ((coro_stack *)arg)); |
|
|
590 | sv_setiv (get_sv ("Coro::State::cctx_restartop", FALSE), PTR2IV (PL_op)); |
|
|
591 | |
|
|
592 | /* continue at cctx_init, without entersub */ |
|
|
593 | PL_restartop = CvSTART (get_cv ("Coro::State::cctx_init", FALSE)); |
|
|
594 | |
601 | |
595 | /* somebody will hit me for both perl_run and PL_restartop */ |
602 | /* somebody will hit me for both perl_run and PL_restartop */ |
596 | ret = perl_run (PERL_GET_CONTEXT); |
603 | perl_run (PERL_GET_CONTEXT); |
597 | printf ("ret %d\n", ret);//D |
|
|
598 | |
604 | |
599 | fputs ("FATAL: C coroutine fell over the edge of the world, aborting.\n", stderr); |
605 | fputs ("FATAL: C coroutine fell over the edge of the world, aborting.\n", stderr); |
600 | abort (); |
606 | abort (); |
601 | } |
607 | } |
602 | |
608 | |
… | |
… | |
909 | static void |
915 | static void |
910 | prepare_schedule (struct transfer_args *ta) |
916 | prepare_schedule (struct transfer_args *ta) |
911 | { |
917 | { |
912 | SV *current, *prev, *next; |
918 | SV *current, *prev, *next; |
913 | |
919 | |
914 | LOCK; |
|
|
915 | |
|
|
916 | current = GvSV (coro_current); |
920 | current = GvSV (coro_current); |
917 | |
921 | |
918 | for (;;) |
922 | for (;;) |
919 | { |
923 | { |
920 | LOCK; |
924 | LOCK; |
921 | |
|
|
922 | next = coro_deq (PRIO_MIN); |
925 | next = coro_deq (PRIO_MIN); |
|
|
926 | UNLOCK; |
923 | |
927 | |
924 | if (next) |
928 | if (next) |
925 | break; |
929 | break; |
926 | |
|
|
927 | UNLOCK; |
|
|
928 | |
930 | |
929 | { |
931 | { |
930 | dSP; |
932 | dSP; |
931 | |
933 | |
932 | ENTER; |
934 | ENTER; |
… | |
… | |
943 | |
945 | |
944 | prev = SvRV (current); |
946 | prev = SvRV (current); |
945 | SvRV (current) = next; |
947 | SvRV (current) = next; |
946 | |
948 | |
947 | /* free this only after the transfer */ |
949 | /* free this only after the transfer */ |
|
|
950 | LOCK; |
948 | free_coro_mortal (); |
951 | free_coro_mortal (); |
|
|
952 | UNLOCK; |
949 | coro_mortal = prev; |
953 | coro_mortal = prev; |
950 | |
954 | |
951 | ta->prev = SvSTATE (prev); |
955 | ta->prev = SvSTATE (prev); |
952 | ta->next = SvSTATE (next); |
956 | ta->next = SvSTATE (next); |
953 | ta->flags = TRANSFER_SAVE_ALL; |
957 | ta->flags = TRANSFER_SAVE_ALL; |
954 | |
|
|
955 | UNLOCK; |
|
|
956 | } |
958 | } |
957 | |
959 | |
958 | static void |
960 | static void |
959 | prepare_cede (struct transfer_args *ta) |
961 | prepare_cede (struct transfer_args *ta) |
960 | { |
962 | { |