4 #include "libthreads.h"
6 #define STACK_SIZE (1024 * 1024)
8 static struct thread *current, *main_thread;
10 static void *stack_allocate(size_t size)
15 static int create_context(struct thread *t)
19 memset(&t->context, 0, sizeof(t->context));
20 ret = getcontext(&t->context);
24 /* t->start_routine == NULL means this is our initial context */
25 if (!t->start_routine)
28 /* Initialize new managed context */
29 t->stack = stack_allocate(STACK_SIZE);
30 t->context.uc_stack.ss_sp = t->stack;
31 t->context.uc_stack.ss_size = STACK_SIZE;
32 t->context.uc_stack.ss_flags = 0;
33 t->context.uc_link = &main_thread->context;
34 makecontext(&t->context, t->start_routine, 1, t->arg);
39 static int create_initial_thread(struct thread *t)
41 memset(t, 0, sizeof(*t));
42 return create_context(t);
45 static int thread_swap(struct thread *old, struct thread *new)
47 return swapcontext(&old->context, &new->context);
50 static int thread_yield()
52 struct thread *old, *next;
57 schedule_add_thread(old);
61 schedule_choose_next(&next);
63 return thread_swap(old, next);
66 static int master_thread_yield()
73 DEBUG("completed thread %d\n", current->index);
74 current->completed = 1;
76 schedule_choose_next(&next);
77 if (next && !next->completed) {
79 return thread_swap(main_thread, next);
84 int thread_create(struct thread *t, void (*start_routine), void *arg)
86 static int created = 1;
91 memset(t, 0, sizeof(*t));
93 DEBUG("create thread %d\n", t->index);
95 t->start_routine = start_routine;
98 /* Initialize state */
99 ret = create_context(t);
103 schedule_add_thread(t);
107 void thread_join(struct thread *t)
109 while (!t->completed)
117 for (i = 0; i < 10; i++) {
118 printf("Thread %d, loop %d\n", *idx, i);
126 struct thread t1, t2;
129 printf("%s() creating 2 threads\n", __func__);
130 thread_create(&t1, &a, &i);
131 thread_create(&t2, &a, &j);
135 printf("%s() is finished\n", __func__);
140 struct thread user_thread;
142 main_thread = malloc(sizeof(struct thread));
143 create_initial_thread(main_thread);
145 thread_create(&user_thread, &user_main, NULL);
147 /* Wait for all threads to complete */
148 while (master_thread_yield() == 0);