Created
September 13, 2015 16:01
-
-
Save jaz303/f39dc365b85d2bb78fa5 to your computer and use it in GitHub Desktop.
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
#define _XOPEN_SOURCE | |
#include <ucontext.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <signal.h> | |
// If I make this 16KiB the program crashes. why? | |
#define STACK_SIZE (32 * 1024) | |
void task(int); | |
typedef void (task_entry_f)(int); | |
struct task; | |
struct task { | |
int id; | |
ucontext_t ctx; | |
struct task *prev; | |
struct task *next; | |
}; | |
int next_task_id = 1; | |
struct task *active = 0; | |
void spawn(task_entry_f fn, int arg) { | |
struct task *t = malloc(sizeof(struct task)); | |
t->id = next_task_id++; | |
if (getcontext(&t->ctx) != 0) { | |
printf("getcontext failed\n"); | |
exit(1); | |
} | |
t->ctx.uc_link = 0; | |
t->ctx.uc_stack.ss_sp = malloc(STACK_SIZE); | |
t->ctx.uc_stack.ss_size = STACK_SIZE; | |
t->ctx.uc_stack.ss_flags = 0; | |
if (t->ctx.uc_stack.ss_sp == 0) { | |
printf("no stack\n"); | |
exit(1); | |
} | |
makecontext(&t->ctx, fn, 1, arg); | |
if (active == 0) { | |
t->next = t; | |
t->prev = t; | |
active = t; | |
} else { | |
t->next = active; | |
t->prev = active->prev; | |
active->prev->next = t; | |
active->prev = t; | |
} | |
printf("spawned task %d\n", t->id); | |
} | |
void yield() { | |
struct task *yielder = active; | |
active = yielder->next; | |
if (yielder == active) { | |
return; | |
} | |
swapcontext(&yielder->ctx, &active->ctx); | |
} | |
void task(int n) { | |
printf("initialising task %d\n", n); | |
for (;;) { | |
printf("hello task %d\n", n); | |
yield(); | |
} | |
} | |
void start() { | |
printf("starting...\n"); | |
setcontext(&active->ctx); | |
printf("you will never see this.\n"); | |
} | |
int main(int argc, char *argv[]) { | |
spawn(&task, 1); | |
spawn(&task, 2); | |
spawn(&task, 3); | |
spawn(&task, 4); | |
start(); | |
printf("you will never see me either!\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment