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.138 by root, Sun Jan 14 20:49:45 2007 UTC vs.
Revision 1.144 by root, Sun Mar 4 11:45:23 2007 UTC

31#else 31#else
32# define PAGESIZE 0 32# define PAGESIZE 0
33# define BOOT_PAGESIZE (void)0 33# define BOOT_PAGESIZE (void)0
34#endif 34#endif
35 35
36#if USE_VALGRIND 36#if CORO_USE_VALGRIND
37# include <valgrind/valgrind.h> 37# include <valgrind/valgrind.h>
38# define REGISTER_STACK(cctx,start,end) (cctx)->valgrind_id = VALGRIND_STACK_REGISTER ((start), (end))
39#else
40# define REGISTER_STACK(cctx,start,end)
38#endif 41#endif
39 42
40/* the maximum number of idle cctx that will be pooled */ 43/* the maximum number of idle cctx that will be pooled */
41#define MAX_IDLE_CCTX 8 44#define MAX_IDLE_CCTX 8
42 45
71#ifndef SvRV_set 74#ifndef SvRV_set
72# define SvRV_set(s,v) SvRV(s) = (v) 75# define SvRV_set(s,v) SvRV(s) = (v)
73#endif 76#endif
74 77
75#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64 78#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
76# undef STACKGUARD 79# undef CORO_STACKGUARD
77#endif 80#endif
78 81
79#ifndef STACKGUARD 82#ifndef CORO_STACKGUARD
80# define STACKGUARD 0 83# define CORO_STACKGUARD 0
81#endif 84#endif
82 85
83/* prefer perl internal functions over our own? */ 86/* prefer perl internal functions over our own? */
84#ifndef PREFER_PERL_FUNCTIONS 87#ifndef CORO_PREFER_PERL_FUNCTIONS
85# define PREFER_PERL_FUNCTIONS 0 88# define CORO_PREFER_PERL_FUNCTIONS 0
86#endif 89#endif
87 90
88/* The next macro should declare a variable stacklevel that contains and approximation 91/* The next macro should declare a variable stacklevel that contains and approximation
89 * to the current C stack pointer. Its property is that it changes with each call 92 * to the current C stack pointer. Its property is that it changes with each call
90 * and should be unique. */ 93 * and should be unique. */
135typedef struct coro_cctx { 138typedef struct coro_cctx {
136 struct coro_cctx *next; 139 struct coro_cctx *next;
137 140
138 /* the stack */ 141 /* the stack */
139 void *sptr; 142 void *sptr;
140 long ssize; /* positive == mmap, otherwise malloc */ 143 ssize_t ssize; /* positive == mmap, otherwise malloc */
141 144
142 /* cpu state */ 145 /* cpu state */
143 void *idle_sp; /* sp of top-level transfer/schedule/cede call */ 146 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
144 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */ 147 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */
145 JMPENV *top_env; 148 JMPENV *top_env;
146 coro_context cctx; 149 coro_context cctx;
147 150
148 int inuse; 151 int inuse;
149 152
150#if USE_VALGRIND 153#if CORO_USE_VALGRIND
151 int valgrind_id; 154 int valgrind_id;
152#endif 155#endif
153} coro_cctx; 156} coro_cctx;
154 157
155enum { 158enum {
285 288
286 if (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0) 289 if (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0)
287 CvPADLIST (cv) = (AV *)AvARRAY (av)[AvFILLp (av)--]; 290 CvPADLIST (cv) = (AV *)AvARRAY (av)[AvFILLp (av)--];
288 else 291 else
289 { 292 {
290#if PREFER_PERL_FUNCTIONS 293#if CORO_PREFER_PERL_FUNCTIONS
291 /* this is probably cleaner, but also slower? */ 294 /* this is probably cleaner, but also slower? */
292 CV *cp = Perl_cv_clone (cv); 295 CV *cp = Perl_cv_clone (cv);
293 CvPADLIST (cv) = CvPADLIST (cp); 296 CvPADLIST (cv) = CvPADLIST (cp);
294 CvPADLIST (cp) = 0; 297 CvPADLIST (cp) = 0;
295 SvREFCNT_dec (cp); 298 SvREFCNT_dec (cp);
362 CvPADLIST (cv) = (AV *)POPs; 365 CvPADLIST (cv) = (AV *)POPs;
363 } 366 }
364 367
365 PUTBACK; 368 PUTBACK;
366 } 369 }
370 assert (!PL_comppad || AvARRAY (PL_comppad));//D
367} 371}
368 372
369static void 373static void
370save_perl (Coro__State c) 374save_perl (Coro__State c)
371{ 375{
376 assert (!PL_comppad || AvARRAY (PL_comppad));//D
372 { 377 {
373 dSP; 378 dSP;
374 I32 cxix = cxstack_ix; 379 I32 cxix = cxstack_ix;
375 PERL_CONTEXT *ccstk = cxstack; 380 PERL_CONTEXT *ccstk = cxstack;
376 PERL_SI *top_si = PL_curstackinfo; 381 PERL_SI *top_si = PL_curstackinfo;
431 * allocate various perl stacks. This is an exact copy 436 * allocate various perl stacks. This is an exact copy
432 * of perl.c:init_stacks, except that it uses less memory 437 * of perl.c:init_stacks, except that it uses less memory
433 * on the (sometimes correct) assumption that coroutines do 438 * on the (sometimes correct) assumption that coroutines do
434 * not usually need a lot of stackspace. 439 * not usually need a lot of stackspace.
435 */ 440 */
436#if PREFER_PERL_FUNCTIONS 441#if CORO_PREFER_PERL_FUNCTIONS
437# define coro_init_stacks init_stacks 442# define coro_init_stacks init_stacks
438#else 443#else
439static void 444static void
440coro_init_stacks () 445coro_init_stacks ()
441{ 446{
535 540
536 coro_init_stacks (); 541 coro_init_stacks ();
537 542
538 PL_curcop = &PL_compiling; 543 PL_curcop = &PL_compiling;
539 PL_in_eval = EVAL_NULL; 544 PL_in_eval = EVAL_NULL;
545 PL_comppad = 0;
540 PL_curpm = 0; 546 PL_curpm = 0;
541 PL_localizing = 0; 547 PL_localizing = 0;
542 PL_dirty = 0; 548 PL_dirty = 0;
543 PL_restartop = 0; 549 PL_restartop = 0;
544 550
626 632
627 Newz (0, cctx, 1, coro_cctx); 633 Newz (0, cctx, 1, coro_cctx);
628 634
629#if HAVE_MMAP 635#if HAVE_MMAP
630 636
631 cctx->ssize = ((STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + STACKGUARD) * PAGESIZE; 637 cctx->ssize = ((CORO_STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
632 /* mmap supposedly does allocate-on-write for us */ 638 /* mmap supposedly does allocate-on-write for us */
633 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); 639 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
634 640
635 if (cctx->sptr == (void *)-1) 641 if (cctx->sptr != (void *)-1)
636 {
637 perror ("FATAL: unable to mmap stack for coroutine");
638 _exit (EXIT_FAILURE);
639 } 642 {
640
641# if STACKGUARD 643# if CORO_STACKGUARD
642 mprotect (cctx->sptr, STACKGUARD * PAGESIZE, PROT_NONE); 644 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
643# endif 645# endif
644 646 REGISTER_STACK (
645#else 647 cctx,
646
647 cctx->ssize = STACKSIZE * (long)sizeof (long);
648 New (0, cctx->sptr, STACKSIZE, long);
649
650 if (!cctx->sptr)
651 {
652 perror ("FATAL: unable to malloc stack for coroutine");
653 _exit (EXIT_FAILURE);
654 }
655
656#endif
657
658#if USE_VALGRIND
659 cctx->valgrind_id = VALGRIND_STACK_REGISTER (
660 STACKGUARD * PAGESIZE + (char *)cctx->sptr, 648 CORO_STACKGUARD * PAGESIZE + (char *)cctx->sptr,
661 cctx->ssize + (char *)cctx->sptr 649 cctx->ssize + (char *)cctx->sptr
662 ); 650 );
663#endif
664 651
665 coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, cctx->ssize); 652 coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, cctx->ssize);
653 }
654 else
655#endif
656 {
657 cctx->ssize = -CORO_STACKSIZE * (long)sizeof (long);
658 New (0, cctx->sptr, CORO_STACKSIZE, long);
659
660 if (!cctx->sptr)
661 {
662 perror ("FATAL: unable to allocate stack for coroutine");
663 _exit (EXIT_FAILURE);
664 }
665
666 REGISTER_STACK (
667 cctx,
668 (char *)cctx->sptr,
669 (char *)cctx->sptr - cctx->ssize
670 );
671
672 coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, -cctx->ssize);
673 }
666 674
667 return cctx; 675 return cctx;
668} 676}
669 677
670static void 678static void
673 if (!cctx) 681 if (!cctx)
674 return; 682 return;
675 683
676 --cctx_count; 684 --cctx_count;
677 685
678#if USE_VALGRIND 686#if CORO_USE_VALGRIND
679 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id); 687 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id);
680#endif 688#endif
681 689
682#if HAVE_MMAP 690#if HAVE_MMAP
691 if (cctx->ssize > 0)
683 munmap (cctx->sptr, cctx->ssize); 692 munmap (cctx->sptr, cctx->ssize);
684#else 693 else
694#endif
685 Safefree (cctx->sptr); 695 Safefree (cctx->sptr);
686#endif
687 696
688 Safefree (cctx); 697 Safefree (cctx);
689} 698}
690 699
691static coro_cctx * 700static coro_cctx *
838 coro->flags |= CF_DESTROYED; 847 coro->flags |= CF_DESTROYED;
839 848
840 if (coro->flags & CF_READY) 849 if (coro->flags & CF_READY)
841 { 850 {
842 /* reduce nready, as destroying a ready coro effectively unreadies it */ 851 /* reduce nready, as destroying a ready coro effectively unreadies it */
843 /* alternative: look through all ready queues and remove it */ 852 /* alternative: look through all ready queues and remove the coro */
844 LOCK; 853 LOCK;
845 --coro_nready; 854 --coro_nready;
846 UNLOCK; 855 UNLOCK;
847 } 856 }
848 else 857 else
849 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */ 858 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */
850 859
851 if (coro->mainstack && coro->mainstack != main_mainstack) 860 if (coro->mainstack && coro->mainstack != main_mainstack)
852 { 861 {
862 struct coro temp;
863
853 assert (!(coro->flags & CF_RUNNING)); 864 assert (!(coro->flags & CF_RUNNING));
854 865
855 struct coro temp;
856 Zero (&temp, 1, struct coro); 866 Zero (&temp, 1, struct coro);
857 temp.save = CORO_SAVE_ALL; 867 temp.save = CORO_SAVE_ALL;
858 868
859 if (coro->flags & CF_RUNNING) 869 if (coro->flags & CF_RUNNING)
860 croak ("FATAL: tried to destroy currently running coroutine"); 870 croak ("FATAL: tried to destroy currently running coroutine");
926 /* very slow, but rare, check */ 936 /* very slow, but rare, check */
927 if (!sv_derived_from (sv_2mortal (newRV_inc (coro)), "Coro::State")) 937 if (!sv_derived_from (sv_2mortal (newRV_inc (coro)), "Coro::State"))
928 croak ("Coro::State object required"); 938 croak ("Coro::State object required");
929 } 939 }
930 940
931 mg = SvMAGIC (coro); 941 mg = CORO_MAGIC (coro);
932 assert (mg->mg_type == PERL_MAGIC_ext);
933 return (struct coro *)mg->mg_ptr; 942 return (struct coro *)mg->mg_ptr;
934} 943}
935 944
936static void 945static void
937prepare_transfer (struct transfer_args *ta, SV *prev_sv, SV *next_sv) 946prepare_transfer (struct transfer_args *ta, SV *prev_sv, SV *next_sv)
1025 next_sv = coro_deq (PRIO_MIN); 1034 next_sv = coro_deq (PRIO_MIN);
1026 1035
1027 /* nothing to schedule: call the idle handler */ 1036 /* nothing to schedule: call the idle handler */
1028 if (!next_sv) 1037 if (!next_sv)
1029 { 1038 {
1039 dSP;
1030 UNLOCK; 1040 UNLOCK;
1031 dSP;
1032 1041
1033 ENTER; 1042 ENTER;
1034 SAVETMPS; 1043 SAVETMPS;
1035 1044
1036 PUSHMARK (SP); 1045 PUSHMARK (SP);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines