From 8e649bb08299bf12cc4e50ffd5f956a4faf32f8f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 10 Apr 2012 14:09:42 -0700 Subject: [PATCH] threads_internal: add 'thread_switch_to_master()' internally In progress: moving more model-checking/thread actions so that they are performed only by a system thread, not by the user code. For now, we replace our uses of thread_yield() (which simply switched to the next user thread) while thread_switch_to_master() (which will later perform intermediate actions before choosing the next user thread). Also, we can begin creating internal and external interfaces in threads_indernal.h and libthreads.h, respectively. --- Makefile | 2 +- libatomic.cc | 6 +++--- libthreads.cc | 25 ++++++++++++++++--------- threads_internal.h | 8 ++++++++ 4 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 threads_internal.h diff --git a/Makefile b/Makefile index 327bbb5..7a442bd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=g++ BIN=libthreads SOURCE=libthreads.cc schedule.cc libatomic.cc userprog.c model.cc malloc.c -HEADERS=libthreads.h schedule.h common.h libatomic.h model.h +HEADERS=libthreads.h schedule.h common.h libatomic.h model.h threads_internal.h FLAGS=-Wall -ldl all: ${BIN} diff --git a/libatomic.cc b/libatomic.cc index a00838e..daf058a 100644 --- a/libatomic.cc +++ b/libatomic.cc @@ -1,13 +1,13 @@ #include "libatomic.h" -#include "libthreads.h" +#include "threads_internal.h" void atomic_store_explicit(struct atomic_object *obj, int value, memory_order order) { - thread_yield(); + thread_switch_to_master(); } int atomic_load_explicit(struct atomic_object *obj, memory_order order) { - thread_yield(); + thread_switch_to_master(); return 0; } diff --git a/libthreads.cc b/libthreads.cc index c0439ff..42e9198 100644 --- a/libthreads.cc +++ b/libthreads.cc @@ -4,6 +4,7 @@ #include "libthreads.h" #include "schedule.h" #include "common.h" +#include "threads_internal.h" /* global "model" object */ #include "model.h" @@ -97,6 +98,17 @@ static void thread_wait_finish(void) while (!thread_system_next()); } +int thread_switch_to_master() +{ + struct thread *old, *next; + + DBG(); + old = thread_current(); + old->state = THREAD_READY; + next = model->system_thread; + return thread_swap(old, next); +} + /* * User program API functions */ @@ -126,19 +138,14 @@ int thread_create(struct thread *t, void (*start_routine)(), void *arg) void thread_join(struct thread *t) { - while (t->state != THREAD_COMPLETED) - thread_yield(); + int ret = 0; + while (t->state != THREAD_COMPLETED && !ret) + ret = thread_switch_to_master(); } 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); + return thread_switch_to_master(); } struct thread *thread_current(void) diff --git a/threads_internal.h b/threads_internal.h new file mode 100644 index 0000000..37b446c --- /dev/null +++ b/threads_internal.h @@ -0,0 +1,8 @@ +#ifndef __THREADS_INTERNAL_H__ +#define __THREADS_INTERNAL_H__ + +#include "libthreads.h" + +int thread_switch_to_master(); + +#endif /* __THREADS_INTERNAL_H__ */ -- 2.34.1