-
-
Save lotusnowshen/3d436f3543934f328f6c to your computer and use it in GitHub Desktop.
cor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <ucontext.h> | |
| #include <unistd.h> | |
| int main(int argc, const char *argv[]) | |
| { | |
| ucontext_t context; | |
| getcontext(&context); | |
| puts("hello world\n"); | |
| sleep(1); | |
| setcontext(&context); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <ucontext.h> | |
| void func1(void) | |
| { | |
| printf("1\n"); | |
| printf("11\n"); | |
| printf("111\n"); | |
| printf("1111\n"); | |
| } | |
| int main(int argc, const char *argv[]) | |
| { | |
| char stack[1024*128]; | |
| ucontext_t child; | |
| ucontext_t main; | |
| getcontext(&child); | |
| child.uc_stack.ss_sp = stack; | |
| child.uc_stack.ss_size = sizeof(stack); | |
| child.uc_stack.ss_flags = 0; | |
| // child.uc_link = &main; | |
| child.uc_link = NULL; | |
| makecontext(&child, func1, 0); | |
| swapcontext(&main, &child); | |
| printf("main\n"); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <ucontext.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| static ucontext_t uctx_main, uctx_func1, uctx_func2; | |
| #define handle_error(msg) \ | |
| do { perror(msg); exit(EXIT_FAILURE); } while (0) | |
| static void | |
| func1(void) | |
| { | |
| printf("func1: started\n"); | |
| printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n"); | |
| if (swapcontext(&uctx_func1, &uctx_func2) == -1) | |
| handle_error("swapcontext"); | |
| printf("func1: returning\n"); | |
| } | |
| static void | |
| func2(void) | |
| { | |
| printf("func2: started\n"); | |
| printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n"); | |
| if (swapcontext(&uctx_func2, &uctx_func1) == -1) | |
| handle_error("swapcontext"); | |
| printf("func2: returning\n"); | |
| } | |
| int | |
| main(int argc, char *argv[]) | |
| { | |
| char func1_stack[16384]; | |
| char func2_stack[16384]; | |
| if (getcontext(&uctx_func1) == -1) | |
| handle_error("getcontext"); | |
| uctx_func1.uc_stack.ss_sp = func1_stack; | |
| uctx_func1.uc_stack.ss_size = sizeof(func1_stack); | |
| uctx_func1.uc_link = &uctx_main; | |
| makecontext(&uctx_func1, func1, 0); | |
| if (getcontext(&uctx_func2) == -1) | |
| handle_error("getcontext"); | |
| uctx_func2.uc_stack.ss_sp = func2_stack; | |
| uctx_func2.uc_stack.ss_size = sizeof(func2_stack); | |
| /* Successor context is f1(), unless argc > 1 */ | |
| uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1; | |
| printf("%p\n", uctx_func2.uc_link); | |
| makecontext(&uctx_func2, func2, 0); | |
| printf("main: swapcontext(&uctx_main, &uctx_func2)\n"); | |
| if (swapcontext(&uctx_main, &uctx_func2) == -1) | |
| handle_error("swapcontext"); | |
| printf("main: exiting\n"); | |
| exit(EXIT_SUCCESS); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <assert.h> | |
| #include <ucontext.h> | |
| enum ThreadState{RUNNABLE, RUNNING, SUSPEND}; | |
| typedef void (*Func) (); | |
| typedef struct { | |
| ucontext_t ctx; | |
| Func func; | |
| void *arg; | |
| enum ThreadState state; | |
| char stack[1024*1024]; | |
| } uthread_t; | |
| typedef struct { | |
| ucontext_t main; | |
| int running_thread; | |
| uthread_t **threads; | |
| size_t size; | |
| } schedule_t; | |
| schedule_t *open_schedule() | |
| { | |
| schedule_t *st = (schedule_t *)malloc(sizeof(schedule_t)); | |
| st->running_thread = -1; | |
| st->size = 20; | |
| st->threads = (uthread_t**)malloc(st->size*sizeof(uthread_t*)); | |
| // memset(st->threads, 0, (st->size)*sizeof(uthread_t*)); | |
| int i; | |
| for (i = 0; i < st->size; ++i) | |
| st->threads[i] = NULL; | |
| return st; | |
| } | |
| int uthread_create(schedule_t *st, Func func, void *arg) | |
| { | |
| uthread_t *ut = (uthread_t *)malloc(sizeof(uthread_t)); | |
| ut->func = func; | |
| ut->arg = arg; | |
| ut->state = RUNNABLE; | |
| memset(ut->stack, 0, sizeof(ut->stack)); | |
| int i; | |
| for (i = 0; i < st->size; ++i) | |
| if (st->threads[i] == NULL) | |
| break; | |
| assert(i < st->size); | |
| st->threads[i] = ut; | |
| getcontext(&ut->ctx); | |
| ut->ctx.uc_stack.ss_sp = ut->stack; | |
| ut->ctx.uc_stack.ss_size = sizeof(ut->stack); | |
| ut->ctx.uc_stack.ss_flags = 0; | |
| ut->ctx.uc_link = &st->main; | |
| makecontext(&ut->ctx, (void (*)(void))func, 0); | |
| return i; | |
| } | |
| void uthread_resume(schedule_t *st, int id) | |
| { | |
| assert(id < st->size); | |
| uthread_t *ut = st->threads[id]; | |
| if (ut == NULL) | |
| return; | |
| ut->state = RUNNING; | |
| st->running_thread = id; | |
| swapcontext(&st->main, &ut->ctx); | |
| } | |
| void uthread_yield(schedule_t *st) | |
| { | |
| int id = st->running_thread; | |
| st->running_thread = -1; | |
| uthread_t *ut = st->threads[id]; | |
| ut->state = SUSPEND; | |
| swapcontext(&ut->ctx, &st->main); | |
| } | |
| schedule_t *S; | |
| void foo() | |
| { | |
| printf("begin foo....\n"); | |
| uthread_yield(S); | |
| printf("resume foo.....\n"); | |
| } | |
| void bar() | |
| { | |
| printf("begin bar....\n"); | |
| uthread_yield(S); | |
| printf("resume bar.....\n"); | |
| } | |
| int main(int argc, const char *argv[]) | |
| { | |
| schedule_t *st = open_schedule(); | |
| S = st; | |
| int id1 = uthread_create(st, foo, NULL); | |
| int id2 = uthread_create(st, bar, NULL); | |
| printf("begin main\n"); | |
| uthread_resume(st, id1); | |
| printf("resume main\n"); | |
| uthread_resume(st, id2); | |
| printf("resume main\n"); | |
| uthread_resume(st, id1); | |
| printf("resume main\n"); | |
| uthread_resume(st, id2); | |
| printf("resume main\n"); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment