6 #include "libthreads.h"
8 #define STACK_SIZE (1024 * 1024)
10 static struct thread *current, *main_thread;
12 static void *stack_allocate(size_t size)
17 static int create_context(struct thread *t)
21 memset(&t->context, 0, sizeof(t->context));
22 ret = getcontext(&t->context);
26 /* t->start_routine == NULL means this is our initial context */
27 if (!t->start_routine)
30 /* Initialize new managed context */
31 t->stack = stack_allocate(STACK_SIZE);
32 t->context.uc_stack.ss_sp = t->stack;
33 t->context.uc_stack.ss_size = STACK_SIZE;
34 t->context.uc_stack.ss_flags = 0;
35 t->context.uc_link = &main_thread->context;
36 makecontext(&t->context, t->start_routine, 1, t->arg);
41 static int create_initial_thread(struct thread *t)
43 memset(t, 0, sizeof(*t));
44 return create_context(t);
47 static int thread_swap(struct thread *old, struct thread *new)
49 return swapcontext(&old->context, &new->context);
52 static int thread_yield()
54 struct thread *old, *next;
59 schedule_add_thread(old);
63 schedule_choose_next(&next);
65 return thread_swap(old, next);
68 static int master_thread_yield()
75 DEBUG("completed thread %d\n", current->index);
76 current->completed = 1;
78 schedule_choose_next(&next);
79 if (next && !next->completed) {
81 return thread_swap(main_thread, next);
86 int thread_create(struct thread *t, void (*start_routine), void *arg)
88 static int created = 1;
92 memset(t, 0, sizeof(*t));
94 DEBUG("create thread %d\n", t->index);
96 t->start_routine = start_routine;
99 /* Initialize state */
100 return create_context(t);
103 void thread_start(struct thread *t)
107 schedule_add_thread(t);
110 void thread_join(struct thread *t)
112 while (!t->completed)
120 for (i = 0; i < 10; i++) {
121 printf("Thread %d, loop %d\n", *idx, i);
129 struct thread t1, t2;
132 thread_create(&t1, &a, &i);
133 thread_create(&t2, &a, &j);
135 printf("%s() is going to start 1 thread\n", __func__);
141 printf("%s() is finished\n", __func__);
146 struct thread user_thread;
148 main_thread = malloc(sizeof(struct thread));
149 create_initial_thread(main_thread);
151 thread_create(&user_thread, &user_main, NULL);
152 thread_start(&user_thread);
154 /* Wait for all threads to complete */
155 while (master_thread_yield() == 0);