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.144 by root, Sun Mar 4 11:45:23 2007 UTC vs.
Revision 1.145 by root, Mon Mar 12 21:40:14 2007 UTC

124 I32 laststype; 124 I32 laststype;
125 int laststatval; 125 int laststatval;
126 Stat_t statcache; 126 Stat_t statcache;
127}; 127};
128 128
129static size_t coro_stacksize = CORO_STACKSIZE;
129static struct CoroAPI coroapi; 130static struct CoroAPI coroapi;
130static AV *main_mainstack; /* used to differentiate between $main and others */ 131static AV *main_mainstack; /* used to differentiate between $main and others */
131static HV *coro_state_stash, *coro_stash; 132static HV *coro_state_stash, *coro_stash;
132static SV *coro_mortal; /* will be freed after next transfer */ 133static SV *coro_mortal; /* will be freed after next transfer */
133 134
138typedef struct coro_cctx { 139typedef struct coro_cctx {
139 struct coro_cctx *next; 140 struct coro_cctx *next;
140 141
141 /* the stack */ 142 /* the stack */
142 void *sptr; 143 void *sptr;
143 ssize_t ssize; /* positive == mmap, otherwise malloc */ 144 size_t ssize;
144 145
145 /* cpu state */ 146 /* cpu state */
146 void *idle_sp; /* sp of top-level transfer/schedule/cede call */ 147 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
147 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */ 148 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */
148 JMPENV *top_env; 149 JMPENV *top_env;
149 coro_context cctx; 150 coro_context cctx;
150 151
151 int inuse;
152
153#if CORO_USE_VALGRIND 152#if CORO_USE_VALGRIND
154 int valgrind_id; 153 int valgrind_id;
155#endif 154#endif
155 char inuse, mapped;
156} coro_cctx; 156} coro_cctx;
157 157
158enum { 158enum {
159 CF_RUNNING = 0x0001, /* coroutine is running */ 159 CF_RUNNING = 0x0001, /* coroutine is running */
160 CF_READY = 0x0002, /* coroutine is ready */ 160 CF_READY = 0x0002, /* coroutine is ready */
625 625
626static coro_cctx * 626static coro_cctx *
627cctx_new () 627cctx_new ()
628{ 628{
629 coro_cctx *cctx; 629 coro_cctx *cctx;
630 void *stack_start;
631 size_t stack_size;
630 632
631 ++cctx_count; 633 ++cctx_count;
632 634
633 Newz (0, cctx, 1, coro_cctx); 635 Newz (0, cctx, 1, coro_cctx);
634 636
635#if HAVE_MMAP 637#if HAVE_MMAP
636 638
637 cctx->ssize = ((CORO_STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE; 639 cctx->ssize = ((coro_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
638 /* mmap supposedly does allocate-on-write for us */ 640 /* mmap supposedly does allocate-on-write for us */
639 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); 641 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
640 642
641 if (cctx->sptr != (void *)-1) 643 if (cctx->sptr != (void *)-1)
642 { 644 {
643# if CORO_STACKGUARD 645# if CORO_STACKGUARD
644 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE); 646 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
645# endif 647# endif
646 REGISTER_STACK (
647 cctx,
648 CORO_STACKGUARD * PAGESIZE + (char *)cctx->sptr, 648 stack_start = CORO_STACKGUARD * PAGESIZE + (char *)cctx->sptr;
649 cctx->ssize + (char *)cctx->sptr 649 stack_size = cctx->ssize - CORO_STACKGUARD * PAGESIZE;
650 ); 650 cctx->mapped = 1;
651
652 coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, cctx->ssize);
653 } 651 }
654 else 652 else
655#endif 653#endif
656 { 654 {
657 cctx->ssize = -CORO_STACKSIZE * (long)sizeof (long); 655 cctx->ssize = coro_stacksize * (long)sizeof (long);
658 New (0, cctx->sptr, CORO_STACKSIZE, long); 656 New (0, cctx->sptr, coro_stacksize, long);
659 657
660 if (!cctx->sptr) 658 if (!cctx->sptr)
661 { 659 {
662 perror ("FATAL: unable to allocate stack for coroutine"); 660 perror ("FATAL: unable to allocate stack for coroutine");
663 _exit (EXIT_FAILURE); 661 _exit (EXIT_FAILURE);
664 } 662 }
665 663
666 REGISTER_STACK ( 664 stack_start = cctx->sptr;
667 cctx, 665 stack_size = cctx->ssize;
668 (char *)cctx->sptr, 666 }
669 (char *)cctx->sptr - cctx->ssize
670 );
671 667
668 REGISTER_STACK (cctx, (char *)stack_start, (char *)stack_start + stack_size);
672 coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, -cctx->ssize); 669 coro_create (&cctx->cctx, coro_run, (void *)cctx, stack_start, stack_size);
673 }
674 670
675 return cctx; 671 return cctx;
676} 672}
677 673
678static void 674static void
686#if CORO_USE_VALGRIND 682#if CORO_USE_VALGRIND
687 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id); 683 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id);
688#endif 684#endif
689 685
690#if HAVE_MMAP 686#if HAVE_MMAP
691 if (cctx->ssize > 0) 687 if (cctx->mapped)
692 munmap (cctx->sptr, cctx->ssize); 688 munmap (cctx->sptr, cctx->ssize);
693 else 689 else
694#endif 690#endif
695 Safefree (cctx->sptr); 691 Safefree (cctx->sptr);
696 692
698} 694}
699 695
700static coro_cctx * 696static coro_cctx *
701cctx_get () 697cctx_get ()
702{ 698{
703 coro_cctx *cctx;
704
705 if (cctx_first) 699 while (cctx_first)
706 { 700 {
707 cctx = cctx_first; 701 coro_cctx *cctx = cctx_first;
708 cctx_first = cctx->next; 702 cctx_first = cctx->next;
709 --cctx_idle; 703 --cctx_idle;
704
705 if (cctx->ssize >= coro_stacksize)
706 return cctx;
707
708 cctx_destroy (cctx);
710 } 709 }
711 else 710
712 {
713 cctx = cctx_new ();
714 PL_op = PL_op->op_next; 711 PL_op = PL_op->op_next;
715 }
716
717 return cctx; 712 return cctx_new ();
718} 713}
719 714
720static void 715static void
721cctx_put (coro_cctx *cctx) 716cctx_put (coro_cctx *cctx)
722{ 717{
1258 PROTOTYPE: $ 1253 PROTOTYPE: $
1259 CODE: 1254 CODE:
1260 _exit (code); 1255 _exit (code);
1261 1256
1262int 1257int
1258cctx_stacksize (int new_stacksize = 0)
1259 CODE:
1260 RETVAL = coro_stacksize;
1261 if (new_stacksize)
1262 coro_stacksize = new_stacksize;
1263 OUTPUT:
1264 RETVAL
1265
1266int
1263cctx_count () 1267cctx_count ()
1264 CODE: 1268 CODE:
1265 RETVAL = cctx_count; 1269 RETVAL = cctx_count;
1266 OUTPUT: 1270 OUTPUT:
1267 RETVAL 1271 RETVAL

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines