add support for condition variable
authorweiyu <weiyuluo1232@gmail.com>
Fri, 1 Mar 2019 23:03:40 +0000 (15:03 -0800)
committerweiyu <weiyuluo1232@gmail.com>
Fri, 1 Mar 2019 23:03:40 +0000 (15:03 -0800)
execution.h
include/pthread.h
librace.cc
pthread.cc

index 5f5fd0a..090be71 100644 (file)
@@ -17,6 +17,7 @@
 #include "params.h"
 
 #include <mutex>
+#include <condition_variable>
 
 /* Forward declaration */
 class Node;
@@ -126,6 +127,7 @@ public:
        CycleGraph * const get_mo_graph() { return mo_graph; }
 
        HashTable<pthread_mutex_t *, std::mutex *, uintptr_t, 4> mutex_map;
+       HashTable<pthread_cond_t *, std::condition_variable *, uintptr_t, 4> cond_map;
 
        SNAPSHOTALLOC
 private:
index 92b1d1b..32f4e1b 100644 (file)
@@ -8,26 +8,7 @@
 #include <threads.h>
 #include <sched.h>
 #include <bits/pthreadtypes.h>
-
-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 <pthread.h>
 
 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
index 5dafc6f..b783627 100644 (file)
@@ -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); }
index 750a302..06e293d 100644 (file)
@@ -3,6 +3,8 @@
 #include "action.h"
 #include "pthread.h"
 #include <mutex>
+#include <condition_variable>
+#include <assert.h>
 
 /* 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;
+}