ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.93 by root, Sun Nov 26 03:22:50 2006 UTC vs.
Revision 1.94 by root, Sun Nov 26 17:14:15 2006 UTC

65 * and should be unique. */ 65 * and should be unique. */
66#define dSTACKLEVEL int stacklevel 66#define dSTACKLEVEL int stacklevel
67#define STACKLEVEL ((void *)&stacklevel) 67#define STACKLEVEL ((void *)&stacklevel)
68 68
69#define IN_DESTRUCT (PL_main_cv == Nullcv) 69#define IN_DESTRUCT (PL_main_cv == Nullcv)
70
71#define labs(l) ((l) >= 0 ? (l) : -(l))
72 70
73#include "CoroAPI.h" 71#include "CoroAPI.h"
74 72
75#define TRANSFER_SET_STACKLEVEL 0x8bfbfbfb /* magic cookie */ 73#define TRANSFER_SET_STACKLEVEL 0x8bfbfbfb /* magic cookie */
76 74
585{ 583{
586 /* 584 /*
587 * this is a _very_ stripped down perl interpreter ;) 585 * this is a _very_ stripped down perl interpreter ;)
588 */ 586 */
589 dTHX; 587 dTHX;
588 int ret;
590 589
591 UNLOCK; 590 UNLOCK;
592 591
593 PL_top_env = &PL_start_env; 592 PL_top_env = &PL_start_env;
594 593
596 sv_setiv (get_sv ("Coro::State::cctx_restartop", FALSE), PTR2IV (PL_op)); 595 sv_setiv (get_sv ("Coro::State::cctx_restartop", FALSE), PTR2IV (PL_op));
597 596
598 /* continue at cctx_init, without entersub */ 597 /* continue at cctx_init, without entersub */
599 PL_restartop = CvSTART (get_cv ("Coro::State::cctx_init", FALSE)); 598 PL_restartop = CvSTART (get_cv ("Coro::State::cctx_init", FALSE));
600 599
601 /* somebody will hit me for both perl_run and PL_restart_op */ 600 /* somebody will hit me for both perl_run and PL_restartop */
602 perl_run (aTHX_ PERL_GET_CONTEXT); 601 ret = perl_run (aTHX_ PERL_GET_CONTEXT);
602 printf ("ret %d\n", ret);//D
603 603
604 fputs ("FATAL: C coroutine fell over the edge of the world, aborting.\n", stderr);
604 abort (); 605 abort ();
605} 606}
606 607
607static coro_stack * 608static coro_stack *
608stack_new () 609stack_new ()
611 612
612 New (0, stack, 1, coro_stack); 613 New (0, stack, 1, coro_stack);
613 614
614#if HAVE_MMAP 615#if HAVE_MMAP
615 616
616 stack->ssize = ((STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + STACKGUARD) * PAGESIZE; /* mmap should do allocate-on-write for us */ 617 stack->ssize = ((STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + STACKGUARD) * PAGESIZE;
618 /* mmap suppsedly does allocate-on-write for us */
617 stack->sptr = mmap (0, stack->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); 619 stack->sptr = mmap (0, stack->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
618 620
619 if (stack->sptr == (void *)-1) 621 if (stack->sptr == (void *)-1)
620 { 622 {
621 perror ("FATAL: unable to mmap stack for coroutine"); 623 perror ("FATAL: unable to mmap stack for coroutine");
622 _exit (EXIT_FAILURE); 624 _exit (EXIT_FAILURE);
623 } 625 }
624 626
627# if STACKGUARD
625 mprotect (stack->sptr, STACKGUARD * PAGESIZE, PROT_NONE); 628 mprotect (stack->sptr, STACKGUARD * PAGESIZE, PROT_NONE);
629# endif
626 630
627#else 631#else
628 632
629 stack->ssize = STACKSIZE * (long)sizeof (long); 633 stack->ssize = STACKSIZE * (long)sizeof (long);
630 New (0, stack->sptr, STACKSIZE, long); 634 New (0, stack->sptr, STACKSIZE, long);
731 735
732 if (prev__stack != next->stack) 736 if (prev__stack != next->stack)
733 { 737 {
734 prev__stack->top_env = PL_top_env; 738 prev__stack->top_env = PL_top_env;
735 PL_top_env = next->stack->top_env; 739 PL_top_env = next->stack->top_env;
740 printf ("stacksw %p %p\n", prev__stack->idle_sp, next->stack->idle_sp);//D
736 coro_transfer (&prev__stack->cctx, &next->stack->cctx); 741 coro_transfer (&prev__stack->cctx, &next->stack->cctx);
737 } 742 }
738 743
739 free_coro_mortal (); 744 free_coro_mortal ();
740 745
1034} 1039}
1035 OUTPUT: 1040 OUTPUT:
1036 RETVAL 1041 RETVAL
1037 1042
1038void 1043void
1039transfer (...) 1044_set_stacklevel (...)
1040 ALIAS: 1045 ALIAS:
1041 Coro::schedule = 1 1046 Coro::State::transfer = 1
1042 Coro::cede = 2 1047 Coro::schedule = 2
1043 _set_stacklevel = 3 1048 Coro::cede = 3
1049 Coro::Cont::yield = 4
1044 CODE: 1050 CODE:
1045{ 1051{
1046 struct transfer_args ta; 1052 struct transfer_args ta;
1047 1053
1048 switch (ix) 1054 switch (ix)
1049 { 1055 {
1050 case 0: 1056 case 0:
1051 if (items != 3)
1052 croak ("Coro::State::transfer(prev,next,flags) expects three arguments, not %d", items);
1053
1054 prepare_transfer (&ta, ST (0), ST (1), SvIV (ST (2)));
1055 break;
1056
1057 case 1:
1058 prepare_schedule (&ta);
1059 break;
1060
1061 case 2:
1062 prepare_cede (&ta);
1063 break;
1064
1065 case 3:
1066 ta.prev = (struct coro *)INT2PTR (coro_stack *, SvIV (ST (0))); 1057 ta.prev = (struct coro *)INT2PTR (coro_stack *, SvIV (ST (0)));
1067 ta.next = 0; 1058 ta.next = 0;
1068 ta.flags = TRANSFER_SET_STACKLEVEL; 1059 ta.flags = TRANSFER_SET_STACKLEVEL;
1069 break; 1060 break;
1061
1062 case 1:
1063 if (items != 3)
1064 croak ("Coro::State::transfer(prev,next,flags) expects three arguments, not %d", items);
1065
1066 prepare_transfer (&ta, ST (0), ST (1), SvIV (ST (2)));
1067 break;
1068
1069 case 2:
1070 prepare_schedule (&ta);
1071 break;
1072
1073 case 3:
1074 prepare_cede (&ta);
1075 break;
1076
1077 case 4:
1078 {
1079 SV *yieldstack;
1080 SV *sv;
1081 AV *defav = GvAV (PL_defgv);
1082
1083 yieldstack = *hv_fetch (
1084 (HV *)SvRV (GvSV (coro_current)),
1085 "yieldstack", sizeof ("yieldstack") - 1,
1086 0
1087 );
1088
1089 /* set up @_ -- ugly */
1090 av_clear (defav);
1091 av_fill (defav, items - 1);
1092 while (items--)
1093 av_store (defav, items, SvREFCNT_inc (ST(items)));
1094
1095 sv = av_pop ((AV *)SvRV (yieldstack));
1096 ta.prev = SvSTATE (*av_fetch ((AV *)SvRV (sv), 0, 0));
1097 ta.next = SvSTATE (*av_fetch ((AV *)SvRV (sv), 1, 0));
1098 ta.flags = 0;
1099 SvREFCNT_dec (sv);
1100 }
1101 break;
1102
1070 } 1103 }
1071 1104
1072 TRANSFER (ta); 1105 TRANSFER (ta);
1073} 1106}
1074 1107
1094_exit (code) 1127_exit (code)
1095 int code 1128 int code
1096 PROTOTYPE: $ 1129 PROTOTYPE: $
1097 CODE: 1130 CODE:
1098 _exit (code); 1131 _exit (code);
1099
1100MODULE = Coro::State PACKAGE = Coro::Cont
1101
1102void
1103yield (...)
1104 PROTOTYPE: @
1105 CODE:
1106{
1107 SV *yieldstack;
1108 SV *sv;
1109 AV *defav = GvAV (PL_defgv);
1110 struct coro *prev, *next;
1111
1112 yieldstack = *hv_fetch (
1113 (HV *)SvRV (GvSV (coro_current)),
1114 "yieldstack", sizeof ("yieldstack") - 1,
1115 0
1116 );
1117
1118 /* set up @_ -- ugly */
1119 av_clear (defav);
1120 av_fill (defav, items - 1);
1121 while (items--)
1122 av_store (defav, items, SvREFCNT_inc (ST(items)));
1123
1124 sv = av_pop ((AV *)SvRV (yieldstack));
1125 prev = SvSTATE (*av_fetch ((AV *)SvRV (sv), 0, 0));
1126 next = SvSTATE (*av_fetch ((AV *)SvRV (sv), 1, 0));
1127 SvREFCNT_dec (sv);
1128
1129 coro_state_transfer (aTHX_ prev, next, 0);
1130}
1131 1132
1132MODULE = Coro::State PACKAGE = Coro 1133MODULE = Coro::State PACKAGE = Coro
1133 1134
1134BOOT: 1135BOOT:
1135{ 1136{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines