4 #include "libthreads.h"
7 #define STACK_SIZE (1024 * 1024)
9 static struct thread *current, *main_thread;
11 static void *stack_allocate(size_t size)
16 static void stack_free(void *stack)
21 static int create_context(struct thread *t)
25 memset(&t->context, 0, sizeof(t->context));
26 ret = getcontext(&t->context);
30 /* t->start_routine == NULL means this is our initial context */
31 if (!t->start_routine)
34 /* Initialize new managed context */
35 t->stack = stack_allocate(STACK_SIZE);
36 t->context.uc_stack.ss_sp = t->stack;
37 t->context.uc_stack.ss_size = STACK_SIZE;
38 t->context.uc_stack.ss_flags = 0;
39 t->context.uc_link = &main_thread->context;
40 makecontext(&t->context, t->start_routine, 1, t->arg);
45 static int create_initial_thread(struct thread *t)
47 memset(t, 0, sizeof(*t));
48 return create_context(t);
51 static int thread_swap(struct thread *old, struct thread *new)
53 return swapcontext(&old->context, &new->context);
56 static int thread_yield()
58 struct thread *old, *next;
62 schedule_add_thread(old);
63 schedule_choose_next(&next);
65 DEBUG("(%d, %d)\n", old->index, next->index);
66 return thread_swap(old, next);
69 static void thread_dispose(struct thread *t)
71 DEBUG("completed thread %d\n", thread_current()->index);
76 static void thread_wait_finish()
84 thread_dispose(current);
85 schedule_choose_next(&next);
87 } while (next && !thread_swap(main_thread, next));
90 int thread_create(struct thread *t, void (*start_routine), void *arg)
92 static int created = 1;
97 memset(t, 0, sizeof(*t));
99 DEBUG("create thread %d\n", t->index);
101 t->start_routine = start_routine;
104 /* Initialize state */
105 ret = create_context(t);
109 schedule_add_thread(t);
113 void thread_join(struct thread *t)
115 while (!t->completed)
119 struct thread *thread_current(void)
128 for (i = 0; i < 10; i++) {
129 printf("Thread %d, magic number %d, loop %d\n", thread_current()->index, *parm, i);
137 struct thread t1, t2;
140 printf("%s() creating 2 threads\n", __func__);
141 thread_create(&t1, &a, &i);
142 thread_create(&t2, &a, &j);
146 printf("%s() is finished\n", __func__);
151 struct thread user_thread;
153 main_thread = malloc(sizeof(struct thread));
154 create_initial_thread(main_thread);
156 /* Start user program */
157 thread_create(&user_thread, &user_main, NULL);
159 /* Wait for all threads to complete */
160 thread_wait_finish();