Skip to content

Instantly share code, notes, and snippets.

@lotusnowshen
Created January 12, 2016 10:13
Show Gist options
  • Select an option

  • Save lotusnowshen/3d436f3543934f328f6c to your computer and use it in GitHub Desktop.

Select an option

Save lotusnowshen/3d436f3543934f328f6c to your computer and use it in GitHub Desktop.
cor
#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;
}
#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;
}
#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);
}
#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