4 #include "libthreads.h"
8 /* global "model" struct */
11 #define STACK_SIZE (1024 * 1024)
13 static struct thread *main_thread;
15 static void *stack_allocate(size_t size)
20 static void stack_free(void *stack)
25 static int create_context(struct thread *t)
29 memset(&t->context, 0, sizeof(t->context));
30 ret = getcontext(&t->context);
34 /* t->start_routine == NULL means this is our initial context */
35 if (!t->start_routine)
38 /* Initialize new managed context */
39 t->stack = stack_allocate(STACK_SIZE);
40 t->context.uc_stack.ss_sp = t->stack;
41 t->context.uc_stack.ss_size = STACK_SIZE;
42 t->context.uc_stack.ss_flags = 0;
43 t->context.uc_link = &main_thread->context;
44 makecontext(&t->context, t->start_routine, 1, t->arg);
49 static int create_initial_thread(struct thread *t)
51 memset(t, 0, sizeof(*t));
52 return create_context(t);
55 static int thread_swap(struct thread *old, struct thread *new)
57 return swapcontext(&old->context, &new->context);
60 int thread_yield(void)
62 struct thread *old, *next;
65 old = thread_current();
66 model->scheduler->add_thread(old);
67 next = model->scheduler->next_thread();
68 DEBUG("(%d, %d)\n", old->index, next->index);
69 return thread_swap(old, next);
72 static void thread_dispose(struct thread *t)
74 DEBUG("completed thread %d\n", thread_current()->index);
79 static void thread_wait_finish(void)
81 struct thread *curr, *next;
86 if ((curr = thread_current()))
88 next = model->scheduler->next_thread();
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 model->scheduler->add_thread(t);
115 void thread_join(struct thread *t)
117 while (!t->completed)
121 struct thread *thread_current(void)
123 return model->scheduler->get_current_thread();
128 struct thread user_thread;
130 model_checker_init();
132 main_thread = malloc(sizeof(struct thread));
133 create_initial_thread(main_thread);
135 /* Start user program */
136 thread_create(&user_thread, &user_main, NULL);
138 /* Wait for all threads to complete */
139 thread_wait_finish();