Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // portable coroutine implementation (sketch)
- // note that Clang (LLVM) compiler requires -fno-stack-check option
- #include <stdio.h>
- #include <stdlib.h>
- #include <setjmp.h>
- jmp_buf contexts[2];
- int cid = 0; // coroutine id
- void printsp()
- {
- int x;
- printf("stack pointer = %p\n", &x);
- }
- // execute the func on the specified stack
- void exec_on_altstack(void *stkbase, size_t stksz, void (*func)())
- {
- size_t diff = (void*)&diff - stkbase - stksz;
- // allocate a dummy local variable to change the stack pointer
- volatile char dummy[diff];
- dummy[0] = '\0'; // don't remove dummy, optimizer
- (*func)();
- }
- // context switch
- void csw(int target) {
- if (_setjmp(contexts[cid]) == 0) {
- printf("# coroutine[%d] context saved\n", cid);
- cid = target;
- _longjmp(contexts[target], 1);
- } else {
- printf("# coroutine[%d] resumes\n", cid);
- }
- }
- void test() {
- printf("test started\n");
- printsp();
- csw(0);
- printf("test resumed\n");
- csw(0);
- printf("test resumed2\n");
- csw(0);
- }
- extern int main(int argc, char **argv)
- {
- printsp();
- size_t stksz = 4096;
- void *stkbase = malloc(stksz);
- printf("allocated stack = %p to %p\n", stkbase, stkbase + stksz - 1);
- if (_setjmp(contexts[cid]) == 0) {
- cid = 1;
- exec_on_altstack(stkbase, stksz, test);
- } else {
- printf("main started\n");
- csw(1);
- printf("main resumed\n");
- csw(1);
- printf("main resumed2\n");
- }
- return 0;
- }
- /* executed on OSX 10.10.4
- ~/stacktest% ./a.out
- stack pointer = 0x7fff5917492c
- allocated stack = 0x7feb08804200 to 0x7feb088051ff
- test started
- stack pointer = 0x7feb088051bc
- # coroutine[1] context saved
- main started
- # coroutine[0] context saved
- # coroutine[1] resumes
- test continued
- # coroutine[1] context saved
- # coroutine[0] resumes
- main resumed
- # coroutine[0] context saved
- # coroutine[1] resumes
- test continued2
- # coroutine[1] context saved
- # coroutine[0] resumes
- main resumed2
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement