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 void stack_free(void *stack)
20 static int create_context(struct thread *t)
24 memset(&t->context, 0, sizeof(t->context));
25 ret = getcontext(&t->context);
29 /* t->start_routine == NULL means this is our initial context */
30 if (!t->start_routine)
33 /* Initialize new managed context */
34 t->stack = stack_allocate(STACK_SIZE);
35 t->context.uc_stack.ss_sp = t->stack;
36 t->context.uc_stack.ss_size = STACK_SIZE;
37 t->context.uc_stack.ss_flags = 0;
38 t->context.uc_link = &main_thread->context;
39 makecontext(&t->context, t->start_routine, 1, t->arg);
44 static int create_initial_thread(struct thread *t)
46 memset(t, 0, sizeof(*t));
47 return create_context(t);
50 static int thread_swap(struct thread *old, struct thread *new)
52 return swapcontext(&old->context, &new->context);
55 static int thread_yield()
57 struct thread *old, *next;
62 schedule_add_thread(old);
66 schedule_choose_next(&next);
68 return thread_swap(old, next);
71 static void thread_dispose(struct thread *t)
73 DEBUG("completed thread %d\n", current->index);
78 static void thread_wait_finish()
86 thread_dispose(current);
87 schedule_choose_next(&next);
89 } while (next && !thread_swap(main_thread, next));
92 int thread_create(struct thread *t, void (*start_routine), void *arg)
94 static int created = 1;
99 memset(t, 0, sizeof(*t));
100 t->index = created++;
101 DEBUG("create thread %d\n", t->index);
103 t->start_routine = start_routine;
106 /* Initialize state */
107 ret = create_context(t);
111 schedule_add_thread(t);
115 void thread_join(struct thread *t)
117 while (!t->completed)
125 for (i = 0; i < 10; i++) {
126 printf("Thread %d, magic number %d, loop %d\n", current->index, *parm, i);
134 struct thread t1, t2;
137 printf("%s() creating 2 threads\n", __func__);
138 thread_create(&t1, &a, &i);
139 thread_create(&t2, &a, &j);
143 printf("%s() is finished\n", __func__);
148 struct thread user_thread;
150 main_thread = malloc(sizeof(struct thread));
151 create_initial_thread(main_thread);
153 /* Start user program */
154 thread_create(&user_thread, &user_main, NULL);
156 /* Wait for all threads to complete */
157 thread_wait_finish();