9 #define DBG() do { printf("Here: %s, L%d\n", __func__, __LINE__); } while (0)
10 #define DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
13 #define DEBUG(fmt, ...)
16 #define STACK_SIZE (1024 * 1024)
19 void (*start_routine);
27 static struct thread *current;
28 static ucontext_t *cleanup;
30 static void *stack_allocate(size_t size)
35 int thread_create(struct thread *t, void (*start_routine), void *arg)
43 DEBUG("create thread %d\n", t->index);
45 t->start_routine = start_routine;
49 /* Initialize state */
50 getcontext(&t->context);
51 t->stack = stack_allocate(STACK_SIZE);
52 t->context.uc_stack.ss_sp = t->stack;
53 t->context.uc_stack.ss_size = STACK_SIZE;
54 t->context.uc_stack.ss_flags = 0;
56 t->context.uc_link = ¤t->context;
58 t->context.uc_link = cleanup;
59 makecontext(&t->context, t->start_routine, 1, t->arg);
64 void thread_start(struct thread *t)
71 struct thread *old = current;
73 swapcontext(&old->context, ¤t->context);
76 swapcontext(cleanup, ¤t->context);
85 for (i = 0; i < 10; i++)
86 printf("Thread %d, loop %d\n", *idx, i);
94 thread_create(&t1, &a, &i);
95 thread_create(&t2, &a, &j);
97 printf("user_main() is going to start 2 threads\n");
100 printf("user_main() is finished\n");
106 ucontext_t main_context;
109 cleanup = &main_context;
111 thread_create(&t, &user_main, NULL);
113 getcontext(&main_context);