X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=libthreads.c;h=2ffe958ed193909cc2960fabcf28c9ee4d3eae4c;hb=dcd84cc88d70497bdc173c4bb78ce30afe4fb5c5;hp=892d784587b7c00fa22083bde526567729326170;hpb=9d5424201af87d2824eb9411f1afa42e82e2f602;p=model-checker.git diff --git a/libthreads.c b/libthreads.c index 892d784..2ffe958 100644 --- a/libthreads.c +++ b/libthreads.c @@ -5,7 +5,7 @@ #include "schedule.h" #include "common.h" -/* global "model" struct */ +/* global "model" object */ #include "model.h" #define STACK_SIZE (1024 * 1024) @@ -47,56 +47,68 @@ static int create_context(struct thread *t) static int create_initial_thread(struct thread *t) { memset(t, 0, sizeof(*t)); + model->assign_id(t); return create_context(t); } -static int thread_swap(struct thread *old, struct thread *new) +static int thread_swap(struct thread *t1, struct thread *t2) { - return swapcontext(&old->context, &new->context); -} - -int thread_yield(void) -{ - struct thread *old, *next; - - DBG(); - old = thread_current(); - model->scheduler->add_thread(old); - next = model->scheduler->next_thread(); - DEBUG("(%d, %d)\n", old->index, next->index); - return thread_swap(old, next); + return swapcontext(&t1->context, &t2->context); } static void thread_dispose(struct thread *t) { - DEBUG("completed thread %d\n", thread_current()->index); + DEBUG("completed thread %d\n", thread_current()->id); t->state = THREAD_COMPLETED; stack_free(t->stack); } -static void thread_wait_finish(void) +/* + * Return 1 if found next thread, 0 otherwise + */ +static int thread_system_next(void) { struct thread *curr, *next; + curr = thread_current(); + if (curr) { + if (curr->state == THREAD_READY) + model->scheduler->add_thread(curr); + else if (curr->state == THREAD_RUNNING) + /* Stopped while running; i.e., completed */ + thread_dispose(curr); + else + DEBUG("ERROR: current thread in unexpected state??\n"); + } + next = model->scheduler->next_thread(); + if (next) + next->state = THREAD_RUNNING; + DEBUG("(%d, %d)\n", curr ? curr->id : -1, next ? next->id : -1); + if (!next) + return 1; + return thread_swap(model->system_thread, next); +} + +static void thread_wait_finish(void) +{ + DBG(); - do { - if ((curr = thread_current())) - thread_dispose(curr); - next = model->scheduler->next_thread(); - } while (next && !thread_swap(model->system_thread, next)); + while (!thread_system_next()); } -int thread_create(struct thread *t, void (*start_routine), void *arg) +/* + * User program API functions + */ +int thread_create(struct thread *t, void (*start_routine)(), void *arg) { - static int created = 1; int ret = 0; DBG(); memset(t, 0, sizeof(*t)); - t->index = created++; - DEBUG("create thread %d\n", t->index); + model->assign_id(t); + DEBUG("create thread %d\n", t->id); t->start_routine = start_routine; t->arg = arg; @@ -118,21 +130,35 @@ void thread_join(struct thread *t) thread_yield(); } +int thread_yield(void) +{ + struct thread *old, *next; + + DBG(); + old = thread_current(); + old->state = THREAD_READY; + next = model->system_thread; + return thread_swap(old, next); +} + struct thread *thread_current(void) { return model->scheduler->get_current_thread(); } +/* + * Main system function + */ int main() { struct thread user_thread; struct thread *main_thread; - model_checker_init(); + model = new ModelChecker(); - main_thread = malloc(sizeof(struct thread)); + main_thread = (struct thread *)malloc(sizeof(*main_thread)); create_initial_thread(main_thread); - model_checker_add_system_thread(main_thread); + model->add_system_thread(main_thread); /* Start user program */ thread_create(&user_thread, &user_main, NULL);