From: weiyu Date: Fri, 1 Mar 2019 23:03:40 +0000 (-0800) Subject: add support for condition variable X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=d636a580c23766d2734cb3bca516b2f25177bae5 add support for condition variable --- diff --git a/execution.h b/execution.h index 5f5fd0a2..090be717 100644 --- a/execution.h +++ b/execution.h @@ -17,6 +17,7 @@ #include "params.h" #include +#include /* Forward declaration */ class Node; @@ -126,6 +127,7 @@ public: CycleGraph * const get_mo_graph() { return mo_graph; } HashTable mutex_map; + HashTable cond_map; SNAPSHOTALLOC private: diff --git a/include/pthread.h b/include/pthread.h index 92b1d1b8..32f4e1b1 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -8,26 +8,7 @@ #include #include #include - -enum -{ - PTHREAD_MUTEX_TIMED_NP, - PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_ADAPTIVE_NP -#if defined __USE_UNIX98 || defined __USE_XOPEN2K8 - , - PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP, - PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL -#endif -#ifdef __USE_GNU - /* For compatibility. */ - , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP -#endif -}; - +#include typedef void *(*pthread_start_t)(void *); @@ -36,15 +17,26 @@ struct pthread_params { void *arg; }; +extern "C" { int pthread_create(pthread_t *, const pthread_attr_t *, void *(*start_routine) (void *), void * arg); void pthread_exit(void *); int pthread_join(pthread_t, void **); +pthread_t pthread_self(void); + int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); int pthread_mutex_lock(pthread_mutex_t *); int pthread_mutex_trylock(pthread_mutex_t *); int pthread_mutex_unlock(pthread_mutex_t *); +int pthread_mutex_timedlock (pthread_mutex_t *__restrict p_mutex, + const struct timespec *__restrict __abstime); + +int pthread_cond_init(pthread_cond_t *p_cond, const pthread_condattr_t *attr); +int pthread_cond_wait(pthread_cond_t *p_cond, pthread_mutex_t *p_mutex); +int pthread_cond_timedwait(pthread_cond_t *p_cond, + pthread_mutex_t *p_mutex, const struct timespec *abstime); +int pthread_cond_signal(pthread_cond_t *); int user_main(int, char**); @@ -73,11 +65,6 @@ int pthread_attr_setstacksize(pthread_attr_t *, size_t); int pthread_cancel(pthread_t); int pthread_cond_broadcast(pthread_cond_t *); int pthread_cond_destroy(pthread_cond_t *); -int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); -int pthread_cond_signal(pthread_cond_t *); -int pthread_cond_timedwait(pthread_cond_t *, - pthread_mutex_t *, const struct timespec *); -int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); int pthread_condattr_destroy(pthread_condattr_t *); int pthread_condattr_getpshared(const pthread_condattr_t *, int *); int pthread_condattr_init(pthread_condattr_t *); @@ -118,8 +105,6 @@ int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); int pthread_rwlockattr_init(pthread_rwlockattr_t *); int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); -pthread_t - pthread_self(void); int pthread_setcancelstate(int, int *); int pthread_setcanceltype(int, int *); int pthread_setconcurrency(int); @@ -128,9 +113,7 @@ int pthread_setschedparam(pthread_t, int , int pthread_setspecific(pthread_key_t, const void *); void pthread_testcancel(void); -int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, - const struct timespec *__restrict - __abstime) __THROWNL __nonnull ((1, 2)); +} void check(); #endif diff --git a/librace.cc b/librace.cc index 5dafc6ff..b7836278 100644 --- a/librace.cc +++ b/librace.cc @@ -100,14 +100,14 @@ uint64_t load_64(const void *addr) void cds_store8(void *addr) { - DEBUG("addr = %p, val = %" PRIu8 "\n", addr, val); + //DEBUG("addr = %p, val = %" PRIu8 "\n", addr, val); thread_id_t tid = thread_current()->get_id(); raceCheckWrite(tid, addr); } void cds_store16(void *addr) { - DEBUG("addr = %p, val = %" PRIu16 "\n", addr, val); + //DEBUG("addr = %p, val = %" PRIu16 "\n", addr, val); thread_id_t tid = thread_current()->get_id(); raceCheckWrite(tid, addr); raceCheckWrite(tid, (void *)(((uintptr_t)addr) + 1)); @@ -115,7 +115,7 @@ void cds_store16(void *addr) void cds_store32(void *addr) { - DEBUG("addr = %p, val = %" PRIu32 "\n", addr, val); + //DEBUG("addr = %p, val = %" PRIu32 "\n", addr, val); thread_id_t tid = thread_current()->get_id(); raceCheckWrite(tid, addr); raceCheckWrite(tid, (void *)(((uintptr_t)addr) + 1)); @@ -125,7 +125,7 @@ void cds_store32(void *addr) void cds_store64(void *addr) { - DEBUG("addr = %p, val = %" PRIu64 "\n", addr, val); + //DEBUG("addr = %p, val = %" PRIu64 "\n", addr, val); thread_id_t tid = thread_current()->get_id(); raceCheckWrite(tid, addr); raceCheckWrite(tid, (void *)(((uintptr_t)addr) + 1)); @@ -140,4 +140,4 @@ void cds_store64(void *addr) void cds_load8(const void *addr) { load_8(addr); } void cds_load16(const void *addr) { load_16(addr); } void cds_load32(const void *addr) { load_32(addr); } -void cds_load64(const void *addr) { load_64(addr); } \ No newline at end of file +void cds_load64(const void *addr) { load_64(addr); } diff --git a/pthread.cc b/pthread.cc index 750a302c..06e293de 100644 --- a/pthread.cc +++ b/pthread.cc @@ -3,6 +3,8 @@ #include "action.h" #include "pthread.h" #include +#include +#include /* global "model" object */ #include "model.h" @@ -59,14 +61,19 @@ int pthread_mutex_trylock(pthread_mutex_t *p_mutex) { ModelExecution *execution = model->get_execution(); std::mutex *m = execution->mutex_map.get(p_mutex); return m->try_lock(); - - /* error message? */ } int pthread_mutex_unlock(pthread_mutex_t *p_mutex) { ModelExecution *execution = model->get_execution(); std::mutex *m = execution->mutex_map.get(p_mutex); m->unlock(); + return 0; +} +int pthread_mutex_timedlock (pthread_mutex_t *__restrict p_mutex, + const struct timespec *__restrict abstime) { + ModelExecution *execution = model->get_execution(); + std::mutex *m = execution->mutex_map.get(p_mutex); + m->lock(); return 0; } @@ -79,3 +86,40 @@ int pthread_key_delete(pthread_key_t) { model_print("key_delete is called\n"); return 0; } + +int pthread_cond_init(pthread_cond_t *p_cond, const pthread_condattr_t *attr) { + std::condition_variable *v = new std::condition_variable(); + + ModelExecution *execution = model->get_execution(); + execution->cond_map.put(p_cond, v); + return 0; +} + +int pthread_cond_wait(pthread_cond_t *p_cond, pthread_mutex_t *p_mutex) { + ModelExecution *execution = model->get_execution(); + std::condition_variable *v = execution->cond_map.get(p_cond); + std::mutex *m = execution->mutex_map.get(p_mutex); + + v->wait(*m); + return 0; + +} + +int pthread_cond_timedwait(pthread_cond_t *p_cond, + pthread_mutex_t *p_mutex, const struct timespec *abstime) { + ModelExecution *execution = model->get_execution(); + std::condition_variable *v = execution->cond_map.get(p_cond); + std::mutex *m = execution->mutex_map.get(p_mutex); + + v->wait(*m); + return 0; +} + +int pthread_cond_signal(pthread_cond_t *p_cond) { + // notify only one blocked thread + ModelExecution *execution = model->get_execution(); + std::condition_variable *v = execution->cond_map.get(p_cond); + + v->notify_one(); + return 0; +}