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.
CC=g++
BIN=libthreads
SOURCE=libthreads.cc schedule.cc libatomic.cc userprog.c model.cc malloc.c
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}
FLAGS=-Wall -ldl
all: ${BIN}
+#include "threads_internal.h"
void atomic_store_explicit(struct atomic_object *obj, int value, memory_order order)
{
void atomic_store_explicit(struct atomic_object *obj, int value, memory_order order)
{
+ thread_switch_to_master();
}
int atomic_load_explicit(struct atomic_object *obj, memory_order order)
{
}
int atomic_load_explicit(struct atomic_object *obj, memory_order order)
{
+ thread_switch_to_master();
#include "libthreads.h"
#include "schedule.h"
#include "common.h"
#include "libthreads.h"
#include "schedule.h"
#include "common.h"
+#include "threads_internal.h"
/* global "model" object */
#include "model.h"
/* global "model" object */
#include "model.h"
while (!thread_system_next());
}
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
*/
/*
* User program API functions
*/
void thread_join(struct thread *t)
{
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)
{
}
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)
}
struct thread *thread_current(void)
--- /dev/null
+#ifndef __THREADS_INTERNAL_H__
+#define __THREADS_INTERNAL_H__
+
+#include "libthreads.h"
+
+int thread_switch_to_master();
+
+#endif /* __THREADS_INTERNAL_H__ */