… | |
… | |
33 | # define BOOT_PAGESIZE (void)0 |
33 | # define BOOT_PAGESIZE (void)0 |
34 | #endif |
34 | #endif |
35 | |
35 | |
36 | #if USE_VALGRIND |
36 | #if 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 | |
… | |
… | |
135 | typedef struct coro_cctx { |
138 | typedef 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; |
… | |
… | |
630 | |
633 | |
631 | cctx->ssize = ((STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + STACKGUARD) * PAGESIZE; |
634 | cctx->ssize = ((STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + STACKGUARD) * PAGESIZE; |
632 | /* mmap supposedly does allocate-on-write for us */ |
635 | /* 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); |
636 | cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); |
634 | |
637 | |
635 | if (cctx->sptr == (void *)-1) |
638 | if (cctx->sptr != (void *)-1) |
636 | { |
|
|
637 | perror ("FATAL: unable to mmap stack for coroutine"); |
|
|
638 | _exit (EXIT_FAILURE); |
|
|
639 | } |
639 | { |
640 | |
|
|
641 | # if STACKGUARD |
640 | # if STACKGUARD |
642 | mprotect (cctx->sptr, STACKGUARD * PAGESIZE, PROT_NONE); |
641 | mprotect (cctx->sptr, STACKGUARD * PAGESIZE, PROT_NONE); |
643 | # endif |
642 | # endif |
644 | |
643 | REGISTER_STACK ( |
645 | #else |
644 | 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, |
645 | STACKGUARD * PAGESIZE + (char *)cctx->sptr, |
661 | cctx->ssize + (char *)cctx->sptr |
646 | cctx->ssize + (char *)cctx->sptr |
662 | ); |
647 | ); |
663 | #endif |
|
|
664 | |
648 | |
665 | coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, cctx->ssize); |
649 | coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, cctx->ssize); |
|
|
650 | } |
|
|
651 | else |
|
|
652 | #endif |
|
|
653 | { |
|
|
654 | cctx->ssize = -STACKSIZE * (long)sizeof (long); |
|
|
655 | New (0, cctx->sptr, STACKSIZE, long); |
|
|
656 | |
|
|
657 | if (!cctx->sptr) |
|
|
658 | { |
|
|
659 | perror ("FATAL: unable to allocate stack for coroutine"); |
|
|
660 | _exit (EXIT_FAILURE); |
|
|
661 | } |
|
|
662 | |
|
|
663 | REGISTER_STACK ( |
|
|
664 | cctx, |
|
|
665 | (char *)cctx->sptr, |
|
|
666 | (char *)cctx->sptr - cctx->ssize |
|
|
667 | ); |
|
|
668 | |
|
|
669 | coro_create (&cctx->cctx, coro_run, (void *)cctx, cctx->sptr, -cctx->ssize); |
|
|
670 | } |
666 | |
671 | |
667 | return cctx; |
672 | return cctx; |
668 | } |
673 | } |
669 | |
674 | |
670 | static void |
675 | static void |
… | |
… | |
678 | #if USE_VALGRIND |
683 | #if USE_VALGRIND |
679 | VALGRIND_STACK_DEREGISTER (cctx->valgrind_id); |
684 | VALGRIND_STACK_DEREGISTER (cctx->valgrind_id); |
680 | #endif |
685 | #endif |
681 | |
686 | |
682 | #if HAVE_MMAP |
687 | #if HAVE_MMAP |
|
|
688 | if (cctx->ssize > 0) |
683 | munmap (cctx->sptr, cctx->ssize); |
689 | munmap (cctx->sptr, cctx->ssize); |
684 | #else |
690 | else |
|
|
691 | #endif |
685 | Safefree (cctx->sptr); |
692 | Safefree (cctx->sptr); |
686 | #endif |
|
|
687 | |
693 | |
688 | Safefree (cctx); |
694 | Safefree (cctx); |
689 | } |
695 | } |
690 | |
696 | |
691 | static coro_cctx * |
697 | static coro_cctx * |