X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=threads.cc;h=d170b7ada3554da89213ab6219fff15c11ed0019;hb=f19a959f1a76e35316df4b8dce39d17640305417;hp=09efcae619c06b78ed5c2668473c2b8143b9ea71;hpb=328a2c09c2ee06d0e1c49ccb84877fa17b436a01;p=c11tester.git diff --git a/threads.cc b/threads.cc index 09efcae6..d170b7ad 100644 --- a/threads.cc +++ b/threads.cc @@ -2,9 +2,11 @@ * @brief Thread functions. */ -#include "libthreads.h" +#include + +#include #include "common.h" -#include "threads.h" +#include "threads-model.h" /* global "model" object */ #include "model.h" @@ -32,8 +34,6 @@ Thread * thread_current(void) * Provides a startup wrapper for each thread, allowing some initial * model-checking data to be recorded. This method also gets around makecontext * not being 64-bit clean - * @todo We should make the START event always immediately follow the - * CREATE event, so we don't get redundant traces... */ void thread_startup() { @@ -104,12 +104,36 @@ int Thread::swap(ucontext_t *ctxt, Thread *t) /** Terminate a thread and free its stack. */ void Thread::complete() { - if (!is_complete()) { - DEBUG("completed thread %d\n", get_id()); - state = THREAD_COMPLETED; - if (stack) - stack_free(stack); - } + ASSERT(!is_complete()); + DEBUG("completed thread %d\n", id_to_int(get_id())); + state = THREAD_COMPLETED; + if (stack) + stack_free(stack); +} + +/** + * @brief Construct a new model-checker Thread + * + * A model-checker Thread is used for accounting purposes only. It will never + * have its own stack, and it should never be inserted into the Scheduler. + * + * @param tid The thread ID to assign + */ +Thread::Thread(thread_id_t tid) : + parent(NULL), + creation(NULL), + pending(NULL), + start_routine(NULL), + arg(NULL), + stack(NULL), + user_thread(NULL), + id(tid), + state(THREAD_READY), /* Thread is always ready? */ + wait_list(), + last_action_val(0), + model_thread(true) +{ + memset(&context, 0, sizeof(context)); } /** @@ -126,14 +150,15 @@ Thread::Thread(thrd_t *t, void (*func)(void *), void *a) : user_thread(t), state(THREAD_CREATED), wait_list(), - last_action_val(VALUE_NONE) + last_action_val(VALUE_NONE), + model_thread(false) { int ret; /* Initialize state */ ret = create_context(); if (ret) - printf("Error in create_context\n"); + model_print("Error in create_context\n"); id = model->get_next_id(); *user_thread = id; @@ -143,12 +168,23 @@ Thread::Thread(thrd_t *t, void (*func)(void *), void *a) : /** Destructor */ Thread::~Thread() { - complete(); + if (!is_complete()) + complete(); model->remove_thread(this); } /** @return The thread_id_t corresponding to this Thread object. */ -thread_id_t Thread::get_id() +thread_id_t Thread::get_id() const { return id; } + +/** + * Set a thread's THREAD_* state (@see thread_state) + * @param s The state to enter + */ +void Thread::set_state(thread_state s) +{ + ASSERT(s == THREAD_COMPLETED || state != THREAD_COMPLETED); + state = s; +}