X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=threads.cc;h=6c7b89028e520d156ab6824a75648ca5aabe5d16;hp=1a83283a680a8b071709b209db58fc12132756e7;hb=11349f4e83c1446d5c678384a7d45e410c82c3e2;hpb=95ee0b6522a582a1a4501c12244d661905ba8a00 diff --git a/threads.cc b/threads.cc index 1a83283a..6c7b8902 100644 --- a/threads.cc +++ b/threads.cc @@ -5,13 +5,32 @@ #include #include -#include +#include "mutex.h" #include "common.h" #include "threads-model.h" #include "action.h" /* global "model" object */ #include "model.h" +#include "execution.h" + +#ifdef TLS +uintptr_t get_tls_addr() { + uintptr_t addr; + asm ("mov %%fs:0, %0" : "=r" (addr)); + return addr; +} + +#include +#include +extern "C" { +int arch_prctl(int code, unsigned long addr); +} +static void set_tls_addr(uintptr_t addr) { + arch_prctl(ARCH_SET_FS, addr); + asm ("mov %0, %%fs:0" : : "r" (addr) : "memory"); +} +#endif /** Allocate a stack for a new thread. */ static void * stack_allocate(size_t size) @@ -50,6 +69,17 @@ void thread_startup() /* Add dummy "start" action, just to create a first clock vector */ model->switch_to_master(new ModelAction(THREAD_START, std::memory_order_seq_cst, curr_thread)); +#ifdef TLS + if (curr_thread->tls == NULL) { + uintptr_t tlssize = model->get_execution()->getTLSSize(); + uintptr_t thddesc = model->get_execution()->getThdDescSize(); + curr_thread->tls = (char*) Thread_malloc(tlssize); + memcpy(curr_thread->tls, model->get_execution()->getTLSBase(), tlssize); + curr_thread->tls += tlssize - thddesc; + set_tls_addr((uintptr_t)curr_thread->tls); + } +#endif + /* Call the actual thread function */ if (curr_thread->start_routine != NULL) { curr_thread->start_routine(curr_thread->arg); @@ -98,6 +128,9 @@ int Thread::create_context() int Thread::swap(Thread *t, ucontext_t *ctxt) { t->set_state(THREAD_READY); +#ifdef TLS + set_tls_addr((uintptr_t)model->getInitThread()->tls); +#endif return model_swapcontext(&t->context, ctxt); } @@ -112,6 +145,10 @@ int Thread::swap(Thread *t, ucontext_t *ctxt) int Thread::swap(ucontext_t *ctxt, Thread *t) { t->set_state(THREAD_RUNNING); +#ifdef TLS + if (t->tls != NULL) + set_tls_addr((uintptr_t)t->tls); +#endif return model_swapcontext(ctxt, &t->context); } @@ -124,6 +161,11 @@ void Thread::complete() state = THREAD_COMPLETED; if (stack) stack_free(stack); +#ifdef TLS + if (tls && get_id() != 1) + tls += model->get_execution()->getTLSSize() - model->get_execution()->getThdDescSize(); + Thread_free(tls); +#endif } /** @@ -141,9 +183,12 @@ Thread::Thread(thread_id_t tid) : start_routine(NULL), arg(NULL), stack(NULL), +#ifdef TLS + tls(NULL), +#endif user_thread(NULL), id(tid), - state(THREAD_READY), /* Thread is always ready? */ + state(THREAD_READY), /* Thread is always ready? */ last_action_val(0), model_thread(true) { @@ -163,6 +208,9 @@ Thread::Thread(thread_id_t tid, thrd_t *t, void (*func)(void *), void *a, Thread start_routine(func), pstart_routine(NULL), arg(a), +#ifdef TLS + tls(NULL), +#endif user_thread(t), id(tid), state(THREAD_CREATED), @@ -176,7 +224,7 @@ Thread::Thread(thread_id_t tid, thrd_t *t, void (*func)(void *), void *a, Thread if (ret) model_print("Error in create_context\n"); - user_thread->priv = this; // WL + user_thread->priv = this; // WL } /** @@ -192,6 +240,9 @@ Thread::Thread(thread_id_t tid, thrd_t *t, void *(*func)(void *), void *a, Threa start_routine(NULL), pstart_routine(func), arg(a), +#ifdef TLS + tls(NULL), +#endif user_thread(t), id(tid), state(THREAD_CREATED), @@ -258,7 +309,7 @@ Thread * Thread::waiting_on() const bool Thread::is_waiting_on(const Thread *t) const { Thread *wait; - for (wait = waiting_on(); wait != NULL; wait = wait->waiting_on()) + for (wait = waiting_on();wait != NULL;wait = wait->waiting_on()) if (wait == t) return true; return false;