4 #include "libthreads.h"
8 /* global "model" object */
11 #define STACK_SIZE (1024 * 1024)
13 static void *stack_allocate(size_t size)
18 static void stack_free(void *stack)
23 static int create_context(struct thread *t)
27 memset(&t->context, 0, sizeof(t->context));
28 ret = getcontext(&t->context);
32 /* t->start_routine == NULL means this is our initial context */
33 if (!t->start_routine)
36 /* Initialize new managed context */
37 t->stack = stack_allocate(STACK_SIZE);
38 t->context.uc_stack.ss_sp = t->stack;
39 t->context.uc_stack.ss_size = STACK_SIZE;
40 t->context.uc_stack.ss_flags = 0;
41 t->context.uc_link = &model->system_thread->context;
42 makecontext(&t->context, t->start_routine, 1, t->arg);
47 static int create_initial_thread(struct thread *t)
49 memset(t, 0, sizeof(*t));
51 return create_context(t);
54 static int thread_swap(struct thread *t1, struct thread *t2)
56 return swapcontext(&t1->context, &t2->context);
59 static void thread_dispose(struct thread *t)
61 DEBUG("completed thread %d\n", thread_current()->id);
62 t->state = THREAD_COMPLETED;
67 * Return 1 if found next thread, 0 otherwise
69 static int thread_system_next(void)
71 struct thread *curr, *next;
73 curr = thread_current();
75 if (curr->state == THREAD_READY)
76 model->scheduler->add_thread(curr);
77 else if (curr->state == THREAD_RUNNING)
78 /* Stopped while running; i.e., completed */
81 DEBUG("ERROR: current thread in unexpected state??\n");
83 next = model->scheduler->next_thread();
85 next->state = THREAD_RUNNING;
86 DEBUG("(%d, %d)\n", curr ? curr->id : -1, next ? next->id : -1);
89 return thread_swap(model->system_thread, next);
92 static void thread_wait_finish(void)
97 while (!thread_system_next());
101 * User program API functions
103 int thread_create(struct thread *t, void (*start_routine)(), void *arg)
109 memset(t, 0, sizeof(*t));
111 DEBUG("create thread %d\n", t->id);
113 t->start_routine = start_routine;
116 /* Initialize state */
117 ret = create_context(t);
121 t->state = THREAD_CREATED;
123 model->scheduler->add_thread(t);
127 void thread_join(struct thread *t)
129 while (t->state != THREAD_COMPLETED)
133 int thread_yield(void)
135 struct thread *old, *next;
138 old = thread_current();
139 old->state = THREAD_READY;
140 next = model->system_thread;
141 return thread_swap(old, next);
144 struct thread *thread_current(void)
146 return model->scheduler->get_current_thread();
150 * Main system function
154 struct thread user_thread;
155 struct thread *main_thread;
157 model = new ModelChecker();
159 main_thread = (struct thread *)malloc(sizeof(*main_thread));
160 create_initial_thread(main_thread);
161 model->add_system_thread(main_thread);
163 /* Start user program */
164 thread_create(&user_thread, &user_main, NULL);
166 /* Wait for all threads to complete */
167 thread_wait_finish();