Merge branch 'branch-weiyu' into new_fuzzer
authorBrian Demsky <bdemsky@uci.edu>
Wed, 19 Jun 2019 20:59:56 +0000 (13:59 -0700)
committerBrian Demsky <bdemsky@uci.edu>
Wed, 19 Jun 2019 20:59:56 +0000 (13:59 -0700)
43 files changed:
Makefile
action.cc
action.h
cmodelint.cc
execution.cc
include/cmodelint.h
include/mypthread.h
libcdsTest/ms-queue/.intrusive_msqueue_hp.cc [new file with mode: 0644]
libcdsTest/ms-queue/Makefile [new file with mode: 0644]
libcdsTest/ms-queue/intrusive_msqueue_hp.cc [new file with mode: 0644]
libcdsTest/ms-queue/msqueue [new file with mode: 0755]
libcdsTest/ms-queue/msqueue2 [new file with mode: 0755]
libcdsTest/ms-queue/other [new file with mode: 0755]
libcdsTest/ms-queue/script.sh [new file with mode: 0755]
libcdsTest/ms-queue/test_intrusive_msqueue.h [new file with mode: 0644]
libcdsTest/ms-queue/tmp [new file with mode: 0644]
pthread_test/CDSPass/addr-satcycle.cc [new file with mode: 0755]
pthread_test/CDSPass/bug1.cc [new file with mode: 0755]
pthread_test/CDSPass/compile.sh [new file with mode: 0755]
pthread_test/CDSPass/condvar.cc [new file with mode: 0755]
pthread_test/CDSPass/deadlock.cc [new file with mode: 0755]
pthread_test/CDSPass/insanesync.cc [new file with mode: 0755]
pthread_test/CDSPass/iriw.cc [new file with mode: 0755]
pthread_test/CDSPass/iriw_wildcard.cc [new file with mode: 0755]
pthread_test/CDSPass/mo-satcycle.cc [new file with mode: 0755]
pthread_test/CDSPass/mutex_test.cc [new file with mode: 0755]
pthread_test/CDSPass/pthread_mutex_test.cc [new file with mode: 0755]
pthread_test/CDSPass/uninit [new file with mode: 0755]
pthread_test/CDSPass/uninit.cc [new file with mode: 0755]
pthread_test/addr-satcycle.cc [new file with mode: 0644]
pthread_test/bug1.cc [new file with mode: 0644]
pthread_test/condvar.cc [new file with mode: 0644]
pthread_test/deadlock.cc [new file with mode: 0644]
pthread_test/insanesync.cc [new file with mode: 0644]
pthread_test/iriw.cc [new file with mode: 0644]
pthread_test/iriw_wildcard.cc [new file with mode: 0644]
pthread_test/mo-satcycle.cc [new file with mode: 0644]
pthread_test/normal_compile.sh [new file with mode: 0755]
pthread_test/protect/mutex_test.cc [new file with mode: 0644]
pthread_test/pthread_mutex_test.cc [new file with mode: 0644]
pthread_test/test.cc [new file with mode: 0644]
pthread_test/uninit.cc [new file with mode: 0644]
sleeps.cc [new file with mode: 0644]

index b0d946d..7c73b9b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,8 @@ OBJECTS := libthreads.o schedule.o model.o threads.o librace.o action.o \
           nodestack.o clockvector.o main.o snapshot-interface.o cyclegraph.o \
           datarace.o impatomic.o cmodelint.o \
           snapshot.o malloc.o mymemory.o common.o mutex.o conditionvariable.o \
-          context.o execution.o libannotate.o plugins.o pthread.o futex.o fuzzer.o
+          context.o execution.o libannotate.o plugins.o pthread.o futex.o fuzzer.o \
+          sleeps.o
 
 CPPFLAGS += -Iinclude -I.
 LDFLAGS := -ldl -lrt -rdynamic
index cfdb6e6..b3db1f1 100644 (file)
--- a/action.cc
+++ b/action.cc
@@ -31,8 +31,8 @@
  * @param thread (optional) The Thread in which this action occurred. If NULL
  * (default), then a Thread is assigned according to the scheduler.
  */
-ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
-                                                                                                uint64_t value, Thread *thread) :
+ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, 
+               uint64_t value, Thread *thread) :
        location(loc),
        reads_from(NULL),
        last_fence_release(NULL),
@@ -45,7 +45,7 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
        seq_number(ACTION_INITIAL_CLOCK)
 {
        /* References to NULL atomic variables can end up here */
-       ASSERT(loc || type == ATOMIC_FENCE);
+       ASSERT(loc || type == ATOMIC_FENCE || type == NOOP);
 
        Thread *t = thread ? thread : thread_current();
        this->tid = t->get_id();
@@ -65,7 +65,7 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
  * (default), then a Thread is assigned according to the scheduler.
  */
 ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
-                                                                                                uint64_t value, int size) :
+               uint64_t value, int size) :
        location(loc),
        reads_from(NULL),
        last_fence_release(NULL),
@@ -84,6 +84,43 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
        this->tid = t->get_id();
 }
 
+
+/**
+ * @brief Construct a new ModelAction with source line number (requires llvm support)
+ *
+ * @param type The type of action
+ * @param position The source line number of this atomic operation
+ * @param order The memory order of this action. A "don't care" for non-ATOMIC
+ * actions (e.g., THREAD_* or MODEL_* actions).
+ * @param loc The location that this action acts upon
+ * @param value (optional) A value associated with the action (e.g., the value
+ * read or written). Defaults to a given macro constant, for debugging purposes.
+ * @param thread (optional) The Thread in which this action occurred. If NULL
+ * (default), then a Thread is assigned according to the scheduler.
+ */
+ModelAction::ModelAction(action_type_t type, const char * position, memory_order order, 
+               void *loc, uint64_t value, Thread *thread) :
+       location(loc),
+       position(position),
+       reads_from(NULL),
+       last_fence_release(NULL),
+       node(NULL),
+       cv(NULL),
+       value(value),
+       type(type),
+       order(order),
+       original_order(order),
+       seq_number(ACTION_INITIAL_CLOCK)
+{
+       /* References to NULL atomic variables can end up here */
+       ASSERT(loc || type == ATOMIC_FENCE);
+
+       Thread *t = thread ? thread : thread_current();
+       this->tid = t->get_id();
+       // model_print("position: %s\n", position);
+}
+
+
 /** @brief ModelAction destructor */
 ModelAction::~ModelAction()
 {
index 2bde6b8..1797e61 100644 (file)
--- a/action.h
+++ b/action.h
@@ -70,7 +70,7 @@ typedef enum action_type {
        ATOMIC_NOTIFY_ALL,      // < A notify all action
        ATOMIC_WAIT,    // < A wait action
        ATOMIC_ANNOTATION,      // < An annotation action to pass information to a trace analysis
-       NOOP
+       NOOP            // no operation, which returns control to scheduler
 } action_type_t;
 
 
@@ -86,6 +86,7 @@ class ModelAction {
 public:
        ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value = VALUE_NONE, Thread *thread = NULL);
        ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value, int size);
+       ModelAction(action_type_t type, const char * position, memory_order order, void *loc, uint64_t value = VALUE_NONE, Thread *thread = NULL);
        ~ModelAction();
        void print() const;
 
@@ -95,6 +96,7 @@ public:
        memory_order get_original_mo() const { return original_order; }
        void set_mo(memory_order order) { this->order = order; }
        void * get_location() const { return location; }
+       const char * get_position() const { return position; }
        modelclock_t get_seq_number() const { return seq_number; }
        uint64_t get_value() const { return value; }
        uint64_t get_reads_from_value() const;
@@ -182,6 +184,9 @@ private:
        /** @brief A pointer to the memory location for this action. */
        void *location;
 
+       /** @brief A pointer to the source line for this atomic action. */
+       const char * position;
+
        union {
                /**
                 * @brief The store that this action reads from
index cdd8b44..2f892f0 100644 (file)
@@ -33,15 +33,6 @@ uint64_t model_rmwr_action(void *obj, memory_order ord) {
        return model->switch_to_master(new ModelAction(ATOMIC_RMWR, ord, obj));
 }
 
-/**
- * Performs the read part of a RMW CAS action. The next action must
- * either be the write part of the RMW action or an explicit close out
- * of the RMW action w/o a write.
- */
-uint64_t model_rmwrcas_action(void *obj, memory_order ord, uint64_t oldval, int size) {
-       return model->switch_to_master(new ModelAction(ATOMIC_RMWRCAS, ord, obj, oldval, size));
-}
-
 /** Performs the write part of a RMW action. */
 void model_rmw_action(void *obj, memory_order ord, uint64_t val) {
        model->switch_to_master(new ModelAction(ATOMIC_RMW, ord, obj, val));
@@ -57,198 +48,288 @@ void model_fence_action(memory_order ord) {
        model->switch_to_master(new ModelAction(ATOMIC_FENCE, ord, FENCE_LOCATION));
 }
 
-// --------------------- helper functions --------------------------------
-uint64_t model_rmwr_action_helper(void *obj, int atomic_index) {
-       return model->switch_to_master(new ModelAction(ATOMIC_RMWR, orders[atomic_index], obj));
+/* ---  helper functions --- */
+uint64_t model_rmwr_action_helper(void *obj, int atomic_index, const char *position) {
+       return model->switch_to_master(
+               new ModelAction(ATOMIC_RMWR, position, orders[atomic_index], obj)
+       );
+}
+
+void model_rmw_action_helper(void *obj, uint64_t val, int atomic_index, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_RMW, position, orders[atomic_index], obj, val)
+       );
 }
 
-void model_rmw_action_helper(void *obj, int atomic_index, uint64_t val) {
+/*
+void model_rmw_action_helper(void *obj, uint64_t val, int atomic_index) {
        model->switch_to_master(new ModelAction(ATOMIC_RMW, orders[atomic_index], obj, val));
 }
+*/
 
-void model_rmwc_action_helper(void *obj, int atomic_index) {
-       model->switch_to_master(new ModelAction(ATOMIC_RMWC, orders[atomic_index], obj));
+void model_rmwc_action_helper(void *obj, int atomic_index, const char *position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_RMWC, position, orders[atomic_index], obj)
+       );
 }
 
+/*
 void model_fence_action_helper(int atomic_index) {
-       model->switch_to_master(new ModelAction(ATOMIC_FENCE, orders[atomic_index], FENCE_LOCATION));
+       model->switch_to_master(
+               new ModelAction(ATOMIC_FENCE, orders[atomic_index], FENCE_LOCATION)
+       );
 }
+*/
 
-// cds atomic loads
-uint8_t cds_atomic_load8(void * obj, int atomic_index) {
-       return (uint8_t) ( model->switch_to_master(new ModelAction(ATOMIC_READ, orders[atomic_index], obj)) );
+// cds atomic inits
+void cds_atomic_init8(void * obj, uint8_t val, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)
+       );
 }
-uint16_t cds_atomic_load16(void * obj, int atomic_index) {
-       return (uint16_t) ( model->switch_to_master(new ModelAction(ATOMIC_READ, orders[atomic_index], obj)) );
+void cds_atomic_init16(void * obj, uint16_t val, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)
+       );
 }
-uint32_t cds_atomic_load32(void * obj, int atomic_index) {
-       return (uint32_t) ( model->switch_to_master(new ModelAction(ATOMIC_READ, orders[atomic_index], obj)) );
+void cds_atomic_init32(void * obj, uint32_t val, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)
+       );
 }
-uint64_t cds_atomic_load64(void * obj, int atomic_index) {
-       return model->switch_to_master(new ModelAction(ATOMIC_READ, orders[atomic_index], obj));
+void cds_atomic_init64(void * obj, uint64_t val, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, val)
+       );
 }
 
-// cds atomic stores
-void cds_atomic_store8(void * obj, int atomic_index, uint8_t val) {
-       model->switch_to_master(new ModelAction(ATOMIC_WRITE, orders[atomic_index], obj, (uint64_t) val));
+
+// cds atomic loads
+uint8_t cds_atomic_load8(void * obj, int atomic_index, const char * position) {        
+       return (uint8_t) ( model->switch_to_master(
+               new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj))
+       );
 }
-void cds_atomic_store16(void * obj, int atomic_index, uint16_t val) {
-       model->switch_to_master(new ModelAction(ATOMIC_WRITE, orders[atomic_index], obj, (uint64_t) val));
+uint16_t cds_atomic_load16(void * obj, int atomic_index, const char * position) {
+       return (uint16_t) ( model->switch_to_master(
+               new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj))
+       );
 }
-void cds_atomic_store32(void * obj, int atomic_index, uint32_t val) {
-       model->switch_to_master(new ModelAction(ATOMIC_WRITE, orders[atomic_index], obj, (uint64_t) val));
+uint32_t cds_atomic_load32(void * obj, int atomic_index, const char * position) {
+       return (uint32_t) ( model->switch_to_master(
+               new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj))
+       );
 }
-void cds_atomic_store64(void * obj, int atomic_index, uint64_t val) {
-       model->switch_to_master(new ModelAction(ATOMIC_WRITE, orders[atomic_index], obj, val));
+uint64_t cds_atomic_load64(void * obj, int atomic_index, const char * position) {
+       return model->switch_to_master(
+               new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj)
+       );
 }
 
-/*
- #define _ATOMIC_RMW_(__op__, size, addr, atomic_index, val )            \
-   ({                                                                      \
-   uint##size##_t _old = model_rmwr_action_helper(addr, atomic_index);   \
-   uint##size##_t _copy = _old;                                          \
-   _copy __op__ ( uint##size##_t ) _val;                                 \
-   model_rmw_action_helper(addr, atomic_index, (uint64_t) _copy);        \
-   return _old;                                                          \
-   })*/
-
-#define _ATOMIC_RMW_(__op__, size, addr, atomic_index, val )            \
-       ({                                                                      \
-               uint ## size ## _t _old = model_rmwr_action_helper(addr, atomic_index);   \
-               uint ## size ## _t _copy = _old;                                          \
-               uint ## size ## _t _val = val;                                            \
-               _copy __op__ _val;                                                    \
-               model_rmw_action_helper(addr, atomic_index, (uint64_t) _copy);        \
-               return _old;                                                          \
-       })
+// cds atomic stores
+void cds_atomic_store8(void * obj, uint8_t val, int atomic_index, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)
+       );
+}
+void cds_atomic_store16(void * obj, uint16_t val, int atomic_index, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)
+       );
+}
+void cds_atomic_store32(void * obj, uint32_t val, int atomic_index, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)
+       );
+}
+void cds_atomic_store64(void * obj, uint64_t val, int atomic_index, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, val)
+       );
+}
+
+#define _ATOMIC_RMW_(__op__, size, addr, val, atomic_index, position)            \
+({                                                                      \
+  uint##size##_t _old = model_rmwr_action_helper(addr, atomic_index, position);   \
+  uint##size##_t _copy = _old;                                          \
+  uint##size##_t _val = val;                                            \
+  _copy __op__ _val;                                                    \
+  model_rmw_action_helper(addr, (uint64_t) _copy, atomic_index, position);        \
+  return _old;                                                          \
+})
 
 // cds atomic exchange
-uint8_t cds_atomic_exchange8(void* addr, int atomic_index, uint8_t val) {
-       _ATOMIC_RMW_( =, 8, addr, atomic_index, val);
+uint8_t cds_atomic_exchange8(void* addr, uint8_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( = , 8, addr, val, atomic_index, position);
 }
-uint16_t cds_atomic_exchange16(void* addr, int atomic_index, uint16_t val) {
-       _ATOMIC_RMW_( =, 16, addr, atomic_index, val);
+uint16_t cds_atomic_exchange16(void* addr, uint16_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( = , 16, addr, val, atomic_index, position);
 }
-uint32_t cds_atomic_exchange32(void* addr, int atomic_index, uint32_t val) {
-       _ATOMIC_RMW_( =, 32, addr, atomic_index, val);
+uint32_t cds_atomic_exchange32(void* addr, uint32_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( = , 32, addr, val, atomic_index, position);
 }
-uint64_t cds_atomic_exchange64(void* addr, int atomic_index, uint64_t val) {
-       _ATOMIC_RMW_( =, 64, addr, atomic_index, val);
+uint64_t cds_atomic_exchange64(void* addr, uint64_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( = , 64, addr, val, atomic_index, position);
 }
 
 // cds atomic fetch add
-uint8_t cds_atomic_fetch_add8(void* addr, int atomic_index, uint8_t val) {
-       _ATOMIC_RMW_( +=, 8, addr, atomic_index, val);
+uint8_t cds_atomic_fetch_add8(void* addr, uint8_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( += , 8, addr, val, atomic_index, position);
 }
-uint16_t cds_atomic_fetch_add16(void* addr, int atomic_index, uint16_t val) {
-       _ATOMIC_RMW_( +=, 16, addr, atomic_index, val);
+uint16_t cds_atomic_fetch_add16(void* addr, uint16_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( += , 16, addr, val, atomic_index, position);
 }
-uint32_t cds_atomic_fetch_add32(void* addr, int atomic_index, uint32_t val) {
-       _ATOMIC_RMW_( +=, 32, addr, atomic_index, val);
+uint32_t cds_atomic_fetch_add32(void* addr, uint32_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( += , 32, addr, val, atomic_index, position);
 }
-uint64_t cds_atomic_fetch_add64(void* addr, int atomic_index, uint64_t val) {
-       _ATOMIC_RMW_( +=, 64, addr, atomic_index, val);
+uint64_t cds_atomic_fetch_add64(void* addr, uint64_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( += , 64, addr, val, atomic_index, position);
 }
 
 // cds atomic fetch sub
-uint8_t cds_atomic_fetch_sub8(void* addr, int atomic_index, uint8_t val) {
-       _ATOMIC_RMW_( -=, 8, addr, atomic_index, val);
+uint8_t cds_atomic_fetch_sub8(void* addr, uint8_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( -= , 8, addr, val, atomic_index, position);
 }
-uint16_t cds_atomic_fetch_sub16(void* addr, int atomic_index, uint16_t val) {
-       _ATOMIC_RMW_( -=, 16, addr, atomic_index, val);
+uint16_t cds_atomic_fetch_sub16(void* addr, uint16_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( -= , 16, addr, val, atomic_index, position);
 }
-uint32_t cds_atomic_fetch_sub32(void* addr, int atomic_index, uint32_t val) {
-       _ATOMIC_RMW_( -=, 32, addr, atomic_index, val);
+uint32_t cds_atomic_fetch_sub32(void* addr, uint32_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( -= , 32, addr, val, atomic_index, position);
 }
-uint64_t cds_atomic_fetch_sub64(void* addr, int atomic_index, uint64_t val) {
-       _ATOMIC_RMW_( -=, 64, addr, atomic_index, val);
+uint64_t cds_atomic_fetch_sub64(void* addr, uint64_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( -= , 64, addr, val, atomic_index, position);
 }
 
 // cds atomic fetch and
-uint8_t cds_atomic_fetch_and8(void* addr, int atomic_index, uint8_t val) {
-       _ATOMIC_RMW_( &=, 8, addr, atomic_index, val);
+uint8_t cds_atomic_fetch_and8(void* addr, uint8_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( &= , 8, addr, val, atomic_index, position);
 }
-uint16_t cds_atomic_fetch_and16(void* addr, int atomic_index, uint16_t val) {
-       _ATOMIC_RMW_( &=, 16, addr, atomic_index, val);
+uint16_t cds_atomic_fetch_and16(void* addr, uint16_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( &= , 16, addr, val, atomic_index, position);
 }
-uint32_t cds_atomic_fetch_and32(void* addr, int atomic_index, uint32_t val) {
-       _ATOMIC_RMW_( &=, 32, addr, atomic_index, val);
+uint32_t cds_atomic_fetch_and32(void* addr, uint32_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( &= , 32, addr, val, atomic_index, position);
 }
-uint64_t cds_atomic_fetch_and64(void* addr, int atomic_index, uint64_t val) {
-       _ATOMIC_RMW_( &=, 64, addr, atomic_index, val);
+uint64_t cds_atomic_fetch_and64(void* addr, uint64_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( &= , 64, addr, val, atomic_index, position);
 }
 
 // cds atomic fetch or
-uint8_t cds_atomic_fetch_or8(void* addr, int atomic_index, uint8_t val) {
-       _ATOMIC_RMW_( |=, 8, addr, atomic_index, val);
+uint8_t cds_atomic_fetch_or8(void* addr, uint8_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( |= , 8, addr, val, atomic_index, position);
 }
-uint16_t cds_atomic_fetch_or16(void* addr, int atomic_index, uint16_t val) {
-       _ATOMIC_RMW_( |=, 16, addr, atomic_index, val);
+uint16_t cds_atomic_fetch_or16(void* addr, uint16_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( |= , 16, addr, val, atomic_index, position);
 }
-uint32_t cds_atomic_fetch_or32(void* addr, int atomic_index, uint32_t val) {
-       _ATOMIC_RMW_( |=, 32, addr, atomic_index, val);
+uint32_t cds_atomic_fetch_or32(void* addr, uint32_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( |= , 32, addr, val, atomic_index, position);
 }
-uint64_t cds_atomic_fetch_or64(void* addr, int atomic_index, uint64_t val) {
-       _ATOMIC_RMW_( |=, 64, addr, atomic_index, val);
+uint64_t cds_atomic_fetch_or64(void* addr, uint64_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( |= , 64, addr, val, atomic_index, position);
 }
 
 // cds atomic fetch xor
-uint8_t cds_atomic_fetch_xor8(void* addr, int atomic_index, uint8_t val) {
-       _ATOMIC_RMW_( ^=, 8, addr, atomic_index, val);
+uint8_t cds_atomic_fetch_xor8(void* addr, uint8_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( ^= , 8, addr, val, atomic_index, position);
 }
-uint16_t cds_atomic_fetch_xor16(void* addr, int atomic_index, uint16_t val) {
-       _ATOMIC_RMW_( ^=, 16, addr, atomic_index, val);
+uint16_t cds_atomic_fetch_xor16(void* addr, uint16_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( ^= , 16, addr, val, atomic_index, position);
 }
-uint32_t cds_atomic_fetch_xor32(void* addr, int atomic_index, uint32_t val) {
-       _ATOMIC_RMW_( ^=, 32, addr, atomic_index, val);
+uint32_t cds_atomic_fetch_xor32(void* addr, uint32_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( ^= , 32, addr, val, atomic_index, position);
 }
-uint64_t cds_atomic_fetch_xor64(void* addr, int atomic_index, uint64_t val) {
-       _ATOMIC_RMW_( ^=, 64, addr, atomic_index, val);
+uint64_t cds_atomic_fetch_xor64(void* addr, uint64_t val, int atomic_index, const char * position) {
+       _ATOMIC_RMW_( ^= , 64, addr, val, atomic_index, position);
 }
 
 // cds atomic compare and exchange
-// In order to accomodate the LLVM PASS, the return values are not true or false.
+// In order to accomodate the LLVM PASS, the return values are not true or false. 
 
 #define _ATOMIC_CMPSWP_WEAK_ _ATOMIC_CMPSWP_
-#define _ATOMIC_CMPSWP_(size, addr, expected, desired, atomic_index)                            \
-       ({                                                                                              \
-               uint ## size ## _t _desired = desired;                                                            \
-               uint ## size ## _t _expected = expected;                                                          \
-               uint ## size ## _t _old = model_rmwr_action_helper(addr, atomic_index);                           \
-               if (_old == _expected  ) {                                                                    \
-                       model_rmw_action_helper(addr, atomic_index, (uint64_t) _desired ); return _expected; }      \
-               else {                                                                                        \
-                       model_rmwc_action_helper(addr, atomic_index); _expected = _old; return _old; }              \
-       })
-
-// expected is supposed to be a pointer to an address, but the CmpOperand
-// extracted from LLVM IR is an integer type.
-
-uint8_t cds_atomic_compare_exchange8(void* addr, uint8_t expected,
-                                                                                                                                                uint8_t desired, int atomic_index_succ, int atomic_index_fail ) {
-       _ATOMIC_CMPSWP_(8, addr, expected, desired, atomic_index_succ );
-}
-uint16_t cds_atomic_compare_exchange16(void* addr, uint16_t expected,
-                                                                                                                                                        uint16_t desired, int atomic_index_succ, int atomic_index_fail ) {
-       _ATOMIC_CMPSWP_(16, addr, expected, desired, atomic_index_succ );
-}
-uint32_t cds_atomic_compare_exchange32(void* addr, uint32_t expected,
-                                                                                                                                                        uint32_t desired, int atomic_index_succ, int atomic_index_fail ) {
-       _ATOMIC_CMPSWP_(32, addr, expected, desired, atomic_index_succ );
-}
-uint64_t cds_atomic_compare_exchange64(void* addr, uint64_t expected,
-                                                                                                                                                        uint64_t desired, int atomic_index_succ, int atomic_index_fail ) {
-       _ATOMIC_CMPSWP_(64, addr, expected, desired, atomic_index_succ );
+#define _ATOMIC_CMPSWP_(size, addr, expected, desired, atomic_index, position)                            \
+({                                                                                              \
+  uint##size##_t _desired = desired;                                                            \
+  uint##size##_t _expected = expected;                                                          \
+  uint##size##_t _old = model_rmwr_action_helper(addr, atomic_index, position);                           \
+  if (_old == _expected) {                                                                    \
+    model_rmw_action_helper(addr, (uint64_t) _desired, atomic_index, position); return _expected; }      \
+  else {                                                                                        \
+    model_rmwc_action_helper(addr, atomic_index, position); _expected = _old; return _old; }              \
+})
+
+// atomic_compare_exchange version 1: the CmpOperand (corresponds to expected)
+// extracted from LLVM IR is an integer type. 
+
+uint8_t cds_atomic_compare_exchange8_v1(void* addr, uint8_t expected, uint8_t desired, 
+                       int atomic_index_succ, int atomic_index_fail, const char *position )
+{
+       _ATOMIC_CMPSWP_(8, addr, expected, desired, 
+                               atomic_index_succ, position);
+}
+uint16_t cds_atomic_compare_exchange16_v1(void* addr, uint16_t expected, uint16_t desired, 
+                       int atomic_index_succ, int atomic_index_fail, const char *position)
+{
+       _ATOMIC_CMPSWP_(16, addr, expected, desired, 
+                               atomic_index_succ, position);
+}
+uint32_t cds_atomic_compare_exchange32_v1(void* addr, uint32_t expected, uint32_t desired, 
+                       int atomic_index_succ, int atomic_index_fail, const char *position)
+{
+       _ATOMIC_CMPSWP_(32, addr, expected, desired, 
+                               atomic_index_succ, position);
+}
+uint64_t cds_atomic_compare_exchange64_v1(void* addr, uint64_t expected, uint64_t desired, 
+                       int atomic_index_succ, int atomic_index_fail, const char *position)
+{
+       _ATOMIC_CMPSWP_(64, addr, expected, desired, 
+                               atomic_index_succ, position);
+}
+
+// atomic_compare_exchange version 2
+bool cds_atomic_compare_exchange8_v2(void* addr, uint8_t* expected, uint8_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position )
+{
+       uint8_t ret = cds_atomic_compare_exchange8_v1(addr, *expected,
+                       desired, atomic_index_succ, atomic_index_fail, position);
+       if (ret == *expected) return true;
+       else return false; 
+}
+bool cds_atomic_compare_exchange16_v2(void* addr, uint16_t* expected, uint16_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position)
+{
+       uint16_t ret = cds_atomic_compare_exchange16_v1(addr, *expected,
+                       desired, atomic_index_succ, atomic_index_fail, position);
+       if (ret == *expected) return true;
+       else return false; 
+}
+bool cds_atomic_compare_exchange32_v2(void* addr, uint32_t* expected, uint32_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position)
+{
+       uint32_t ret = cds_atomic_compare_exchange32_v1(addr, *expected,
+                       desired, atomic_index_succ, atomic_index_fail, position);
+       if (ret == *expected) return true;
+       else return false; 
+}
+bool cds_atomic_compare_exchange64_v2(void* addr, uint64_t* expected, uint64_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position)
+{
+       uint64_t ret = cds_atomic_compare_exchange64_v1(addr, *expected,
+                       desired, atomic_index_succ, atomic_index_fail, position);
+       if (ret == *expected) return true;
+       else return false; 
 }
 
+
 // cds atomic thread fence
 
-void cds_atomic_thread_fence(int atomic_index) {
-       model->switch_to_master(new ModelAction(ATOMIC_FENCE, orders[atomic_index], FENCE_LOCATION));
+void cds_atomic_thread_fence(int atomic_index, const char * position) {
+       model->switch_to_master(
+               new ModelAction(ATOMIC_FENCE, position, orders[atomic_index], FENCE_LOCATION)
+       );
 }
 
 /*
- #define _ATOMIC_CMPSWP_( __a__, __e__, __m__, __x__ )                         \
+#define _ATOMIC_CMPSWP_( __a__, __e__, __m__, __x__ )                         \
         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
                 __typeof__(__e__) __q__ = (__e__);                            \
                 __typeof__(__m__) __v__ = (__m__);                            \
@@ -259,13 +340,13 @@ void cds_atomic_thread_fence(int atomic_index) {
                 else {  model_rmwc_action((void *)__p__, __x__); *__q__ = __t__;  __r__ = false;} \
                 __r__; })
 
- #define _ATOMIC_FENCE_( __x__ ) \
+#define _ATOMIC_FENCE_( __x__ ) \
         ({ model_fence_action(__x__);})
- */
+*/
 
 /*
 
- #define _ATOMIC_MODIFY_( __a__, __o__, __m__, __x__ )                         \
+#define _ATOMIC_MODIFY_( __a__, __o__, __m__, __x__ )                         \
         ({ volatile __typeof__((__a__)->__f__)* __p__ = & ((__a__)->__f__);   \
         __typeof__((__a__)->__f__) __old__=(__typeof__((__a__)->__f__)) model_rmwr_action((void *)__p__, __x__); \
         __typeof__(__m__) __v__ = (__m__);                                    \
@@ -273,5 +354,5 @@ void cds_atomic_thread_fence(int atomic_index) {
         __copy__ __o__ __v__;                                                 \
         model_rmw_action((void *)__p__, __x__, (uint64_t) __copy__);          \
         __old__ = __old__;  Silence clang (-Wunused-value)                    \
-         })
- */
+         })                           
+*/
index 213b260..4a351a9 100644 (file)
@@ -682,7 +682,7 @@ ModelAction * ModelExecution::check_current_action(ModelAction *curr)
        wake_up_sleeping_actions(curr);
 
        /* Add the action to lists before any other model-checking tasks */
-       if (!second_part_of_rmw)
+       if (!second_part_of_rmw && curr->get_type() != NOOP)
                add_action_to_lists(curr);
 
        SnapVector<ModelAction *> * rf_set = NULL;
@@ -1106,7 +1106,7 @@ bool ModelExecution::release_seq_heads(const ModelAction *rf, rel_heads_list_t *
  * @see ModelExecution::release_seq_heads
  */
 void ModelExecution::get_release_seq_heads(ModelAction *acquire,
-                                                                                                                                                                        ModelAction *read, rel_heads_list_t *release_heads)
+                ModelAction *read, rel_heads_list_t *release_heads)
 {
        const ModelAction *rf = read->get_reads_from();
 
index d5a0486..0355a47 100644 (file)
@@ -21,68 +21,81 @@ void model_rmw_action(void *obj, memory_order ord, uint64_t val);
 void model_rmwc_action(void *obj, memory_order ord);
 void model_fence_action(memory_order ord);
 
-// void model_init_action_helper(void * obj, uint64_t val);
-uint64_t model_rmwr_action_helper(void *obj, int atomic_index);
-void model_rmw_action_helper(void *obj, int atomic_index, uint64_t val);
-void model_rmwc_action_helper(void *obj, int atomic_index);
-void model_fence_action_helper(int atomic_index);
+uint64_t model_rmwr_action_helper(void *obj, int atomic_index, const char *position);
+void model_rmw_action_helper(void *obj, uint64_t val, int atomic_index, const char *position);
+void model_rmwc_action_helper(void *obj, int atomic_index, const char *position);
+// void model_fence_action_helper(int atomic_index);
 
-// WL
-uint8_t  cds_atomic_load8(void * obj, int atomic_index);
-uint16_t cds_atomic_load16(void * obj, int atomic_index);
-uint32_t cds_atomic_load32(void * obj, int atomic_index);
-uint64_t cds_atomic_load64(void * obj, int atomic_index);
+/* the following functions are used by llvm pass */
 
-void cds_atomic_store8(void * obj, int atomic_index, uint8_t val);
-void cds_atomic_store16(void * obj, int atomic_index, uint16_t val);
-void cds_atomic_store32(void * obj, int atomic_index, uint32_t val);
-void cds_atomic_store64(void * obj, int atomic_index, uint64_t val);
+void cds_atomic_init8(void * obj, uint8_t val, const char * position);
+void cds_atomic_init16(void * obj, uint16_t val, const char * position);
+void cds_atomic_init32(void * obj, uint32_t val, const char * position);
+void cds_atomic_init64(void * obj, uint64_t val, const char * position);
+
+uint8_t  cds_atomic_load8(void * obj, int atomic_index, const char * position);
+uint16_t cds_atomic_load16(void * obj, int atomic_index, const char * position);
+uint32_t cds_atomic_load32(void * obj, int atomic_index, const char * position);
+uint64_t cds_atomic_load64(void * obj, int atomic_index, const char * position);
+
+void cds_atomic_store8(void * obj, uint8_t val, int atomic_index, const char * position);
+void cds_atomic_store16(void * obj, uint16_t val, int atomic_index, const char * position);
+void cds_atomic_store32(void * obj, uint32_t val, int atomic_index, const char * position);
+void cds_atomic_store64(void * obj, uint64_t val, int atomic_index, const char * position);
 
 
 // cds atomic exchange
-uint8_t cds_atomic_exchange8(void* addr, int atomic_index, uint8_t val);
-uint16_t cds_atomic_exchange16(void* addr, int atomic_index, uint16_t val);
-uint32_t cds_atomic_exchange32(void* addr, int atomic_index, uint32_t val);
-uint64_t cds_atomic_exchange64(void* addr, int atomic_index, uint64_t val);
+uint8_t cds_atomic_exchange8(void* addr, uint8_t val, int atomic_index, const char * position);
+uint16_t cds_atomic_exchange16(void* addr, uint16_t val, int atomic_index, const char * position);
+uint32_t cds_atomic_exchange32(void* addr, uint32_t val, int atomic_index, const char * position);
+uint64_t cds_atomic_exchange64(void* addr, uint64_t val, int atomic_index, const char * position);
 // cds atomic fetch add
-uint8_t  cds_atomic_fetch_add8(void* addr, int atomic_index, uint8_t val);
-uint16_t cds_atomic_fetch_add16(void* addr, int atomic_index, uint16_t val);
-uint32_t cds_atomic_fetch_add32(void* addr, int atomic_index, uint32_t val);
-uint64_t cds_atomic_fetch_add64(void* addr, int atomic_index, uint64_t val);
+uint8_t  cds_atomic_fetch_add8(void* addr, uint8_t val, int atomic_index, const char * position);
+uint16_t cds_atomic_fetch_add16(void* addr, uint16_t val, int atomic_index, const char * position);
+uint32_t cds_atomic_fetch_add32(void* addr, uint32_t val, int atomic_index, const char * position);
+uint64_t cds_atomic_fetch_add64(void* addr, uint64_t val, int atomic_index, const char * position);
 // cds atomic fetch sub
-uint8_t  cds_atomic_fetch_sub8(void* addr, int atomic_index, uint8_t val);
-uint16_t cds_atomic_fetch_sub16(void* addr, int atomic_index, uint16_t val);
-uint32_t cds_atomic_fetch_sub32(void* addr, int atomic_index, uint32_t val);
-uint64_t cds_atomic_fetch_sub64(void* addr, int atomic_index, uint64_t val);
+uint8_t  cds_atomic_fetch_sub8(void* addr, uint8_t val, int atomic_index, const char * position);
+uint16_t cds_atomic_fetch_sub16(void* addr, uint16_t val, int atomic_index, const char * position);
+uint32_t cds_atomic_fetch_sub32(void* addr, uint32_t val, int atomic_index, const char * position);
+uint64_t cds_atomic_fetch_sub64(void* addr, uint64_t val, int atomic_index, const char * position);
 // cds atomic fetch and
-uint8_t cds_atomic_fetch_and8(void* addr, int atomic_index, uint8_t val);
-uint16_t cds_atomic_fetch_and16(void* addr, int atomic_index, uint16_t val);
-uint32_t cds_atomic_fetch_and32(void* addr, int atomic_index, uint32_t val);
-uint64_t cds_atomic_fetch_and64(void* addr, int atomic_index, uint64_t val);
+uint8_t cds_atomic_fetch_and8(void* addr, uint8_t val, int atomic_index, const char * position);
+uint16_t cds_atomic_fetch_and16(void* addr, uint16_t val, int atomic_index, const char * position);
+uint32_t cds_atomic_fetch_and32(void* addr, uint32_t val, int atomic_index, const char * position);
+uint64_t cds_atomic_fetch_and64(void* addr, uint64_t val, int atomic_index, const char * position);
 // cds atomic fetch or
-uint8_t cds_atomic_fetch_or8(void* addr, int atomic_index, uint8_t val);
-uint16_t cds_atomic_fetch_or16(void* addr, int atomic_index, uint16_t val);
-uint32_t cds_atomic_fetch_or32(void* addr, int atomic_index, uint32_t val);
-uint64_t cds_atomic_fetch_or64(void* addr, int atomic_index, uint64_t val);
+uint8_t cds_atomic_fetch_or8(void* addr, uint8_t val, int atomic_index, const char * position);
+uint16_t cds_atomic_fetch_or16(void* addr, uint16_t val, int atomic_index, const char * position);
+uint32_t cds_atomic_fetch_or32(void* addr, uint32_t val, int atomic_index, const char * position);
+uint64_t cds_atomic_fetch_or64(void* addr, uint64_t val, int atomic_index, const char * position);
 // cds atomic fetch xor
-uint8_t cds_atomic_fetch_xor8(void* addr, int atomic_index, uint8_t val);
-uint16_t cds_atomic_fetch_xor16(void* addr, int atomic_index, uint16_t val);
-uint32_t cds_atomic_fetch_xor32(void* addr, int atomic_index, uint32_t val);
-uint64_t cds_atomic_fetch_xor64(void* addr, int atomic_index, uint64_t val);
+uint8_t cds_atomic_fetch_xor8(void* addr, uint8_t val, int atomic_index, const char * position);
+uint16_t cds_atomic_fetch_xor16(void* addr, uint16_t val, int atomic_index, const char * position);
+uint32_t cds_atomic_fetch_xor32(void* addr, uint32_t val, int atomic_index, const char * position);
+uint64_t cds_atomic_fetch_xor64(void* addr, uint64_t val, int atomic_index, const char * position);
 
 // cds atomic compare and exchange (strong)
+uint8_t cds_atomic_compare_exchange8_v1(void* addr, uint8_t expected, uint8_t desire, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
+uint16_t cds_atomic_compare_exchange16_v1(void* addr, uint16_t expected, uint16_t desire, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
+uint32_t cds_atomic_compare_exchange32_v1(void* addr, uint32_t expected, uint32_t desire, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
+uint64_t cds_atomic_compare_exchange64_v1(void* addr, uint64_t expected, uint64_t desire, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
 
-uint8_t cds_atomic_compare_exchange8(void* addr, uint8_t expected, 
-                  uint8_t desire, int atomic_index_succ, int atomic_index_fail );
-uint16_t cds_atomic_compare_exchange16(void* addr, uint16_t expected,
-                  uint16_t desire, int atomic_index_succ, int atomic_index_fail );
-uint32_t cds_atomic_compare_exchange32(void* addr, uint32_t expected, 
-                  uint32_t desire, int atomic_index_succ, int atomic_index_fail );
-uint64_t cds_atomic_compare_exchange64(void* addr, uint64_t expected, 
-                  uint64_t desire, int atomic_index_succ, int atomic_index_fail );
+bool cds_atomic_compare_exchange8_v2(void* addr, uint8_t* expected, uint8_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
+bool cds_atomic_compare_exchange16_v2(void* addr, uint16_t* expected, uint16_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
+bool cds_atomic_compare_exchange32_v2(void* addr, uint32_t* expected, uint32_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
+bool cds_atomic_compare_exchange64_v2(void* addr, uint64_t* expected, uint64_t desired, 
+               int atomic_index_succ, int atomic_index_fail, const char *position);
 
 // cds atomic thread fence
-void cds_atomic_thread_fence(int atomic_index);
+void cds_atomic_thread_fence(int atomic_index, const char * position);
 
 #if __cplusplus
 }
index b697bde..ad92d24 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <threads.h>
 #include <sched.h>
-//#include <bits/pthreadtypes.h>
+#include <bits/pthreadtypes.h>
 #include <pthread.h>
 
 typedef void *(*pthread_start_t)(void *);
@@ -18,27 +18,8 @@ struct pthread_params {
 };
 
 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**);
 
 // --- not implemented yet ---
diff --git a/libcdsTest/ms-queue/.intrusive_msqueue_hp.cc b/libcdsTest/ms-queue/.intrusive_msqueue_hp.cc
new file mode 100644 (file)
index 0000000..877f545
--- /dev/null
@@ -0,0 +1,125 @@
+#include "test_intrusive_msqueue.h"
+
+#include <stdio.h>
+#include <cds/init.h>
+#include <cds/gc/hp.h>
+#include <cds/intrusive/msqueue.h>
+#include <vector>
+
+namespace ci = cds::intrusive;
+typedef cds::gc::HP gc_type;
+
+typedef cds_test::intrusive_msqueue base_class;
+typedef typename base_class::base_hook_item< ci::msqueue::node<gc_type>> base_item_type;
+typedef typename base_class::member_hook_item< ci::msqueue::node<gc_type>> member_item_type;
+
+typedef cds_test::intrusive_msqueue::mock_disposer mock_disposer;
+
+template <typename Queue, typename Data>
+void test( Queue& q, Data& arr )
+{
+    typedef typename Queue::value_type value_type;
+    size_t nSize = arr.size();
+
+    value_type * pv;
+    for ( size_t i = 0; i < nSize; ++i )
+       arr[i].nVal = static_cast<int>(i);
+
+    assert(q.empty());
+    assert(q.size() == 0);
+
+    // pop from empty queue
+    pv = q.pop();
+    assert( pv == nullptr );
+    assert( q.empty());
+    assert(q.size() == 0);
+
+    pv =q.dequeue();
+    assert( pv == nullptr );
+    assert( q.empty());
+    assert(q.size() == 0);
+
+    // push/pop test
+    for ( size_t i = 0; i < nSize; ++i ) {
+       if ( i & 1 )
+           q.push( arr[i] );
+       else
+           q.enqueue( arr[i] );
+       assert( !q.empty());
+       assert(q.size() == i+1);
+    }
+
+    for ( size_t i = 0; i < nSize; ++i ) {
+       assert( !q.empty());
+       assert( q.size() == nSize - i );
+       if ( i & 1 )
+           pv = q.pop();
+       else
+           pv = q.dequeue();
+       assert( pv != nullptr );
+       assert( pv->nVal == i);
+    }
+    assert( q.empty());
+    assert( q.size() == 0 );
+
+    Queue::gc::scan();
+    --nSize; // last element of array is in queue yet as a dummy item
+    for ( size_t i = 0; i < nSize; ++i ) {
+       assert( arr[i].nDisposeCount == 1 );
+    }
+    assert( arr[nSize].nDisposeCount == 0 );
+
+    // clear test
+    for ( size_t i = 0; i < nSize; ++i )
+       q.push( arr[i] );
+
+    assert( !q.empty());
+    assert( q.size() == nSize );
+
+    q.clear();
+    assert( q.empty());
+    assert( q.size() == 0 );
+
+    Queue::gc::scan();
+    for ( size_t i = 0; i < nSize - 1; ++i ) {
+       printf("nDisCount (2): %d, (i) %lu\n",  arr[i].nDisposeCount, i );
+    }
+    printf("nDisCount: (1) %d\n",  arr[nSize - 1].nDisposeCount ); // this element is in the queue yet
+    assert( arr[nSize].nDisposeCount == 1 );
+}
+
+int main () {
+       cds::Initialize();
+
+       {
+               typedef ci::MSQueue< gc_type, base_item_type > queue_type;      
+               cds::gc::hp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount, 1, 16 );
+               cds::threading::Manager::attachThread();
+
+               {
+                       typedef cds::intrusive::MSQueue< gc_type, base_item_type,
+                           typename ci::msqueue::make_traits<
+                               ci::opt::disposer< mock_disposer >
+                               , cds::opt::item_counter< cds::atomicity::item_counter >
+                               , ci::opt::hook< ci::msqueue::base_hook< ci::opt::gc<gc_type>>>
+                           >::type
+                       > test_queue;
+
+                       std::vector<base_item_type> arr;
+                       arr.resize(5);
+                       printf("test start\n");
+                       {
+                               test_queue q;
+                               test(q, arr);
+                       }
+                       printf("test end\n");
+
+//                     gc_type::scan();
+//                     check_array( arr );
+
+               }
+
+       }
+
+       cds::Terminate();
+}
diff --git a/libcdsTest/ms-queue/Makefile b/libcdsTest/ms-queue/Makefile
new file mode 100644 (file)
index 0000000..8df2ca5
--- /dev/null
@@ -0,0 +1,15 @@
+all: intrusive_msqueue_hp.o
+
+#%.o : %.cc 
+#      $(CXX) -c $@
+
+CFLAGS=-I. -I /scratch/benchmarks/libcds -std=c++11
+
+CDSDIR=/scratch/benchmarks/libcds/build-release/bin
+CDSLIB=-lcds_d -lpthread
+
+intrusive_msqueue_hp.o: intrusive_msqueue_hp.cc
+       $(CXX) -o msqueue intrusive_msqueue_hp.cc $(CFLAGS) -L $(CDSDIR) $(CDSLIB)
+
+clean:
+       rm -f *.o
diff --git a/libcdsTest/ms-queue/intrusive_msqueue_hp.cc b/libcdsTest/ms-queue/intrusive_msqueue_hp.cc
new file mode 100644 (file)
index 0000000..176ba50
--- /dev/null
@@ -0,0 +1,174 @@
+#include "test_intrusive_msqueue.h"
+
+#include <stdio.h>
+#include <cds/init.h>
+#include <cds/gc/hp.h>
+#include <cds/intrusive/msqueue.h>
+#include <vector>
+
+#define NDEBUG         // disable assert()
+#include <assert.h>
+#include <atomic>
+
+namespace ci = cds::intrusive;
+typedef cds::gc::HP gc_type;
+
+typedef cds_test::intrusive_msqueue base_class;
+typedef typename base_class::base_hook_item< ci::msqueue::node<gc_type>> base_item_type;
+typedef typename base_class::member_hook_item< ci::msqueue::node<gc_type>> member_item_type;
+
+typedef cds_test::intrusive_msqueue::mock_disposer mock_disposer;
+
+template <typename Queue, typename Data>
+void test_enqueue( Queue& q, Data& arr )
+{
+    typedef typename Queue::value_type value_type;
+    size_t nSize = arr.size();
+
+    value_type * pv;
+    for ( size_t i = 0; i < nSize; ++i )
+       arr[i].nVal = static_cast<int>(i);
+
+    assert(q.empty());
+    assert(q.size() == 0);
+
+    // pop from empty queue
+//    pv = q.pop();
+    assert( pv == nullptr );
+    assert( q.empty());
+    assert(q.size() == 0);
+
+//    pv = q.dequeue();
+    assert( pv == nullptr );
+    assert( q.empty());
+    assert(q.size() == 0);
+
+    for ( size_t i = 0; i < nSize; ++i ) {
+       if ( i & 1 )
+           q.push( arr[i] );
+       else
+           q.enqueue( arr[i] );
+       assert( !q.empty());
+       assert(q.size() == i+1);
+    }
+}
+
+
+template <typename Queue, typename Data>
+void test_dequeue( Queue& q, Data& arr )
+{
+    typedef typename Queue::value_type value_type;
+    size_t nSize = arr.size();
+
+    value_type * pv;
+/*
+    for ( size_t i = 0; i < nSize; ++i )
+       arr[i].nVal = static_cast<int>(i);
+
+    assert(q.empty());
+    assert(q.size() == 0);
+
+    // pop from empty queue
+    pv = q.pop();
+    assert( pv == nullptr );
+    assert( q.empty());
+    assert(q.size() == 0);
+
+    pv = q.dequeue();
+    assert( pv == nullptr );
+    assert( q.empty());
+    assert(q.size() == 0);
+
+    // push/pop test
+    for ( size_t i = 0; i < nSize; ++i ) {
+       if ( i & 1 )
+           q.push( arr[i] );
+       else
+           q.enqueue( arr[i] );
+       assert( !q.empty());
+       assert(q.size() == i+1);
+    }
+*/
+
+    for ( size_t i = 0; i < nSize; ++i ) {
+       assert( !q.empty());
+       assert( q.size() == nSize - i );
+       if ( i & 1 )
+           pv = q.pop();
+       else
+           pv = q.dequeue();
+       assert( pv != nullptr );
+       assert( pv->nVal == i);
+    }
+    assert( q.empty());
+    assert( q.size() == 0 );
+
+/*
+    Queue::gc::scan();
+    --nSize; // last element of array is in queue yet as a dummy item
+    for ( size_t i = 0; i < nSize; ++i ) {
+       assert( arr[i].nDisposeCount == 1 );
+    }
+    assert( arr[nSize].nDisposeCount == 0 );
+
+    // clear test
+    for ( size_t i = 0; i < nSize; ++i )
+       q.push( arr[i] );
+
+    assert( !q.empty());
+    assert( q.size() == nSize );
+
+    q.clear();
+    assert( q.empty());
+    assert( q.size() == 0 );
+
+    Queue::gc::scan();
+    for ( size_t i = 0; i < nSize - 1; ++i ) {
+       printf("nDisCount (2): %d, (i) %lu\n",  arr[i].nDisposeCount, i );
+    }
+    printf("nDisCount: (1) %d\n",  arr[nSize - 1].nDisposeCount ); // this element is in the queue yet
+    assert( arr[nSize].nDisposeCount == 1 );
+*/
+
+}
+
+int main () {
+       cds::Initialize();
+
+       {
+               typedef ci::MSQueue< gc_type, base_item_type > queue_type;      
+               cds::gc::hp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount, 1, 16 );
+               cds::threading::Manager::attachThread();
+
+               {
+                       typedef cds::intrusive::MSQueue< gc_type, base_item_type,
+                           typename ci::msqueue::make_traits<
+                               ci::opt::disposer< mock_disposer >
+                               , cds::opt::item_counter< cds::atomicity::item_counter >
+                               , ci::opt::hook< ci::msqueue::base_hook< ci::opt::gc<gc_type>>>
+                           >::type
+                       > test_queue;
+
+                       std::vector<base_item_type> arr;
+                       arr.resize(5);
+                       printf("test start\n");
+                       {
+                               std::atomic<int> x;
+                               atomic_store_explicit(&x, 0xaaa, std::memory_order_seq_cst);
+                               test_queue q;
+                               test_enqueue(q, arr);
+                               atomic_store_explicit(&x, 0xccc, std::memory_order_seq_cst);
+                               test_dequeue(q, arr);
+                               atomic_store_explicit(&x, 0xbbb, std::memory_order_seq_cst);
+                       }
+                       printf("test end\n");
+
+//                     gc_type::scan();
+//                     check_array( arr );
+
+               }
+
+       }
+
+       cds::Terminate();
+}
diff --git a/libcdsTest/ms-queue/msqueue b/libcdsTest/ms-queue/msqueue
new file mode 100755 (executable)
index 0000000..ebafe1e
Binary files /dev/null and b/libcdsTest/ms-queue/msqueue differ
diff --git a/libcdsTest/ms-queue/msqueue2 b/libcdsTest/ms-queue/msqueue2
new file mode 100755 (executable)
index 0000000..ded5d2a
Binary files /dev/null and b/libcdsTest/ms-queue/msqueue2 differ
diff --git a/libcdsTest/ms-queue/other b/libcdsTest/ms-queue/other
new file mode 100755 (executable)
index 0000000..e6da92d
Binary files /dev/null and b/libcdsTest/ms-queue/other differ
diff --git a/libcdsTest/ms-queue/script.sh b/libcdsTest/ms-queue/script.sh
new file mode 100755 (executable)
index 0000000..9aa7253
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+clang++ -o msqueue2 -Xclang -load -Xclang /scratch/llvm/build/lib/libCDSPass.so  intrusive_msqueue_hp.cc -I. -I /scratch/benchmarks/libcds -g -std=c++11 -L /scratch/random-fuzzer -lmodel -L /scratch/benchmarks/libcds/build-release/bin -lcds_d -lpthread
diff --git a/libcdsTest/ms-queue/test_intrusive_msqueue.h b/libcdsTest/ms-queue/test_intrusive_msqueue.h
new file mode 100644 (file)
index 0000000..8890cd3
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (c) 2006-2018 Maxim Khizhinsky
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef CDSUNIT_QUEUE_TEST_INTRUSIVE_MSQUEUE_H
+#define CDSUNIT_QUEUE_TEST_INTRUSIVE_MSQUEUE_H
+
+namespace cds_test {
+
+    class intrusive_msqueue
+    {
+    public:
+        template <typename Base>
+        struct base_hook_item : public Base
+        {
+            int nVal;
+            int nDisposeCount;
+
+            base_hook_item()
+                : nDisposeCount( 0 )
+            {}
+
+            base_hook_item( base_hook_item const& s)
+                : nVal( s.nVal )
+                , nDisposeCount( s.nDisposeCount )
+            {}
+        };
+
+        template <typename Member>
+        struct member_hook_item
+        {
+            int nVal;
+            int nDisposeCount;
+            Member hMember;
+
+            member_hook_item()
+                : nDisposeCount( 0 )
+            {}
+
+            member_hook_item( member_hook_item const& s )
+                : nVal( s.nVal )
+                , nDisposeCount( s.nDisposeCount )
+            {}
+        };
+
+        struct mock_disposer
+        {
+            template <typename T>
+            void operator ()( T * p )
+            {
+                ++p->nDisposeCount;
+            }
+        };
+
+    };
+
+} // namespace cds_test
+
+#endif // CDSUNIT_QUEUE_TEST_INTRUSIVE_MSQUEUE_H
diff --git a/libcdsTest/ms-queue/tmp b/libcdsTest/ms-queue/tmp
new file mode 100644 (file)
index 0000000..1dacb27
--- /dev/null
@@ -0,0 +1,242 @@
+key_delete is called
+has write to location: 0x60c1e0 values: 1 
+has write to location: 0x1a82928 values: 1a82a10 1a82a20 1a82a30 1a82a40 1a82a50 
+has write to location: 0x1a82980 values: 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 
+has write to location: 0x1a829e0 values: 7f74888ecf28 0 1a82b10 0 1a82b20 0 1a82b30 0 1a82b40 0 7f74888ecf28 0 1a82b20 0 1a82b20 0 1a82b40 0 1a82b40 0 0 0 
+has write to location: 0x1a829f0 values: 1a82b10 0 1a82b10 0 1a82b30 0 1a82b30 0 1a82b50 0 1a82b50 0 
+has write to location: 0x1a82b10 values: 0 1a82b20 
+has write to location: 0x1a82b20 values: 0 1a82b30 
+has write to location: 0x1a82b30 values: 0 1a82b40 
+has write to location: 0x1a82b40 values: 0 1a82b50 
+has write to location: 0x1a82b50 values: 0 
+has write to location: 0x7f74888ecea8 values: 1a82b10 1a82b20 1a82b30 1a82b40 1a82b50 0 
+has write to location: 0x7f74888ecee8 values: 1a82b10 1a82b20 1a82b30 1a82b40 1a82b50 0 
+has write to location: 0x7f74888ecf28 values: 0 1a82b10 
+has write to location: 0x7f74888ecf68 values: 1 2 3 4 5 4 3 2 1 0 
+has write to location: 0x7f74888ecf78 values: aaa ccc bbb 
+-----------------------------------------
+location: 0x60c1e0: 
+0    0    uninitialized   relaxed        0x60c1e0   0                       ( 0)
+location: 0x7f74888ecee8: 
+0    0    uninitialized   relaxed  0x7f74888ecee8   0x7f74888ecf28          ( 0)
+location: 0x1a82980: 
+0    0    uninitialized   relaxed       0x1a82980   0                       ( 0)
+location: 0x7f74888ecee8: 
+0    0    uninitialized   relaxed  0x7f74888ecee8   0x7f74888ecf28          ( 0)
+location: 0x7f74888ecf28: 
+9    1    atomic write    release  0x7f74888ecf28   0                       ( 0,  9)
+location: 0x7f74888ecf28: 
+9    1    atomic write    release  0x7f74888ecf28   0                       ( 0,  9)
+location: 0x7f74888ecf68: 
+0    0    uninitialized   relaxed  0x7f74888ecf68   0                       ( 0)
+location: 0x7f74888ecee8: 
+0    0    uninitialized   relaxed  0x7f74888ecee8   0x7f74888ecf28          ( 0)
+location: 0x7f74888ecee8: 
+17   1    atomic rmw      release  0x7f74888ecee8   0x7f74888ecf28      0   ( 0, 17)
+location: 0x1a82980: 
+12   1    atomic rmw      acq_rel       0x1a82980   0                   0   ( 0, 12)
+location: 0x7f74888ecee8: 
+17   1    atomic rmw      release  0x7f74888ecee8   0x7f74888ecf28      0   ( 0, 17)
+location: 0x1a82b10: 
+3    1    atomic write    release       0x1a82b10   0                       ( 0,  3)
+location: 0x1a82b10: 
+3    1    atomic write    release       0x1a82b10   0                       ( 0,  3)
+location: 0x7f74888ecf68: 
+16   1    atomic rmw      relaxed  0x7f74888ecf68   0                   0   ( 0, 16)
+location: 0x7f74888ecee8: 
+17   1    atomic rmw      release  0x7f74888ecee8   0x7f74888ecf28      0   ( 0, 17)
+location: 0x7f74888ecee8: 
+26   1    atomic rmw      release  0x7f74888ecee8   0x1a82b10           17  ( 0, 26)
+location: 0x1a82980: 
+21   1    atomic rmw      acq_rel       0x1a82980   0x1                 12  ( 0, 21)
+location: 0x7f74888ecee8: 
+26   1    atomic rmw      release  0x7f74888ecee8   0x1a82b10           17  ( 0, 26)
+location: 0x1a82b20: 
+4    1    atomic write    release       0x1a82b20   0                       ( 0,  4)
+location: 0x1a82b20: 
+4    1    atomic write    release       0x1a82b20   0                       ( 0,  4)
+location: 0x7f74888ecf68: 
+25   1    atomic rmw      relaxed  0x7f74888ecf68   0x1                 16  ( 0, 25)
+location: 0x7f74888ecee8: 
+26   1    atomic rmw      release  0x7f74888ecee8   0x1a82b10           17  ( 0, 26)
+location: 0x7f74888ecee8: 
+35   1    atomic rmw      release  0x7f74888ecee8   0x1a82b20           26  ( 0, 35)
+location: 0x1a82980: 
+30   1    atomic rmw      acq_rel       0x1a82980   0x2                 21  ( 0, 30)
+location: 0x7f74888ecee8: 
+35   1    atomic rmw      release  0x7f74888ecee8   0x1a82b20           26  ( 0, 35)
+location: 0x1a82b30: 
+5    1    atomic write    release       0x1a82b30   0                       ( 0,  5)
+location: 0x1a82b30: 
+5    1    atomic write    release       0x1a82b30   0                       ( 0,  5)
+location: 0x7f74888ecf68: 
+34   1    atomic rmw      relaxed  0x7f74888ecf68   0x2                 25  ( 0, 34)
+location: 0x7f74888ecee8: 
+35   1    atomic rmw      release  0x7f74888ecee8   0x1a82b20           26  ( 0, 35)
+location: 0x7f74888ecee8: 
+44   1    atomic rmw      release  0x7f74888ecee8   0x1a82b30           35  ( 0, 44)
+location: 0x1a82980: 
+39   1    atomic rmw      acq_rel       0x1a82980   0x3                 30  ( 0, 39)
+location: 0x7f74888ecee8: 
+44   1    atomic rmw      release  0x7f74888ecee8   0x1a82b30           35  ( 0, 44)
+location: 0x1a82b40: 
+6    1    atomic write    release       0x1a82b40   0                       ( 0,  6)
+location: 0x1a82b40: 
+6    1    atomic write    release       0x1a82b40   0                       ( 0,  6)
+location: 0x7f74888ecf68: 
+43   1    atomic rmw      relaxed  0x7f74888ecf68   0x3                 34  ( 0, 43)
+location: 0x7f74888ecee8: 
+44   1    atomic rmw      release  0x7f74888ecee8   0x1a82b30           35  ( 0, 44)
+location: 0x7f74888ecea8: 
+0    0    uninitialized   relaxed  0x7f74888ecea8   0x7f74888ecf28          ( 0)
+location: 0x1a82980: 
+48   1    atomic rmw      acq_rel       0x1a82980   0x4                 39  ( 0, 48)
+location: 0x7f74888ecea8: 
+0    0    uninitialized   relaxed  0x7f74888ecea8   0x7f74888ecf28          ( 0)
+location: 0x7f74888ecf28: 
+15   1    atomic rmw      release  0x7f74888ecf28   0                   9   ( 0, 15)
+location: 0x1a82980: 
+58   1    atomic rmw      acq_rel       0x1a82980   0x5                 48  ( 0, 58)
+location: 0x7f74888ecf28: 
+15   1    atomic rmw      release  0x7f74888ecf28   0                   9   ( 0, 15)
+location: 0x7f74888ecea8: 
+0    0    uninitialized   relaxed  0x7f74888ecea8   0x7f74888ecf28          ( 0)
+location: 0x7f74888ecee8: 
+53   1    atomic rmw      release  0x7f74888ecee8   0x1a82b40           44  ( 0, 53)
+location: 0x7f74888ecea8: 
+0    0    uninitialized   relaxed  0x7f74888ecea8   0x7f74888ecf28          ( 0)
+location: 0x7f74888ecf68: 
+52   1    atomic rmw      relaxed  0x7f74888ecf68   0x4                 43  ( 0, 52)
+location: 0x7f74888ecea8: 
+66   1    atomic rmw      acquire  0x7f74888ecea8   0x7f74888ecf28      0   ( 0, 66)
+location: 0x1a82980: 
+62   1    atomic rmw      acq_rel       0x1a82980   0x6                 58  ( 0, 62)
+location: 0x7f74888ecea8: 
+66   1    atomic rmw      acquire  0x7f74888ecea8   0x7f74888ecf28      0   ( 0, 66)
+location: 0x1a82b10: 
+24   1    atomic rmw      release       0x1a82b10   0                   3   ( 0, 24)
+location: 0x1a82980: 
+72   1    atomic rmw      acq_rel       0x1a82980   0x7                 62  ( 0, 72)
+location: 0x1a82b10: 
+24   1    atomic rmw      release       0x1a82b10   0                   3   ( 0, 24)
+location: 0x7f74888ecea8: 
+66   1    atomic rmw      acquire  0x7f74888ecea8   0x7f74888ecf28      0   ( 0, 66)
+location: 0x7f74888ecee8: 
+53   1    atomic rmw      release  0x7f74888ecee8   0x1a82b40           44  ( 0, 53)
+location: 0x7f74888ecea8: 
+66   1    atomic rmw      acquire  0x7f74888ecea8   0x7f74888ecf28      0   ( 0, 66)
+location: 0x7f74888ecf68: 
+67   1    atomic rmw      relaxed  0x7f74888ecf68   0x5                 52  ( 0, 67)
+location: 0x1a82928: 
+0    0    uninitialized   relaxed       0x1a82928   0x1a82a00               ( 0)
+location: 0x7f74888ecea8: 
+80   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b10           66  ( 0, 80)
+location: 0x1a82980: 
+76   1    atomic rmw      acq_rel       0x1a82980   0x8                 72  ( 0, 76)
+location: 0x7f74888ecea8: 
+80   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b10           66  ( 0, 80)
+location: 0x1a82b20: 
+33   1    atomic rmw      release       0x1a82b20   0                   4   ( 0, 33)
+location: 0x1a82980: 
+88   1    atomic rmw      acq_rel       0x1a82980   0x9                 76  ( 0, 88)
+location: 0x1a82b20: 
+33   1    atomic rmw      release       0x1a82b20   0                   4   ( 0, 33)
+location: 0x7f74888ecea8: 
+80   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b10           66  ( 0, 80)
+location: 0x7f74888ecee8: 
+53   1    atomic rmw      release  0x7f74888ecee8   0x1a82b40           44  ( 0, 53)
+location: 0x7f74888ecea8: 
+80   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b10           66  ( 0, 80)
+location: 0x7f74888ecf68: 
+81   1    atomic rmw      relaxed  0x7f74888ecf68   0x4                 67  ( 0, 81)
+location: 0x1a82928: 
+83   1    atomic write    relaxed       0x1a82928   0x1a82a10               ( 0, 83)
+location: 0x7f74888ecea8: 
+96   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b20           80  ( 0, 96)
+location: 0x1a82980: 
+92   1    atomic rmw      acq_rel       0x1a82980   0xa                 88  ( 0, 92)
+location: 0x7f74888ecea8: 
+96   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b20           80  ( 0, 96)
+location: 0x1a82b30: 
+42   1    atomic rmw      release       0x1a82b30   0                   5   ( 0, 42)
+location: 0x1a82980: 
+104  1    atomic rmw      acq_rel       0x1a82980   0xb                 92  ( 0, 104)
+location: 0x1a82b30: 
+42   1    atomic rmw      release       0x1a82b30   0                   5   ( 0, 42)
+location: 0x7f74888ecea8: 
+96   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b20           80  ( 0, 96)
+location: 0x7f74888ecee8: 
+53   1    atomic rmw      release  0x7f74888ecee8   0x1a82b40           44  ( 0, 53)
+location: 0x7f74888ecea8: 
+96   1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b20           80  ( 0, 96)
+location: 0x7f74888ecf68: 
+97   1    atomic rmw      relaxed  0x7f74888ecf68   0x3                 81  ( 0, 97)
+location: 0x1a82928: 
+99   1    atomic write    relaxed       0x1a82928   0x1a82a20               ( 0, 99)
+location: 0x7f74888ecea8: 
+112  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b30           96  ( 0, 112)
+location: 0x1a82980: 
+108  1    atomic rmw      acq_rel       0x1a82980   0xc                 104 ( 0, 108)
+location: 0x7f74888ecea8: 
+112  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b30           96  ( 0, 112)
+location: 0x1a82b40: 
+51   1    atomic rmw      release       0x1a82b40   0                   6   ( 0, 51)
+location: 0x1a82980: 
+120  1    atomic rmw      acq_rel       0x1a82980   0xd                 108 ( 0, 120)
+location: 0x1a82b40: 
+51   1    atomic rmw      release       0x1a82b40   0                   6   ( 0, 51)
+location: 0x7f74888ecea8: 
+112  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b30           96  ( 0, 112)
+location: 0x7f74888ecee8: 
+53   1    atomic rmw      release  0x7f74888ecee8   0x1a82b40           44  ( 0, 53)
+location: 0x7f74888ecea8: 
+112  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b30           96  ( 0, 112)
+location: 0x7f74888ecf68: 
+113  1    atomic rmw      relaxed  0x7f74888ecf68   0x2                 97  ( 0, 113)
+location: 0x1a82928: 
+115  1    atomic write    relaxed       0x1a82928   0x1a82a30               ( 0, 115)
+location: 0x7f74888ecea8: 
+128  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b40           112 ( 0, 128)
+location: 0x1a82980: 
+124  1    atomic rmw      acq_rel       0x1a82980   0xe                 120 ( 0, 124)
+location: 0x7f74888ecea8: 
+128  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b40           112 ( 0, 128)
+location: 0x1a82b50: 
+7    1    atomic write    release       0x1a82b50   0                       ( 0,  7)
+location: 0x1a82980: 
+137  1    atomic rmw      acq_rel       0x1a82980   0xf                 124 ( 0, 137)
+location: 0x1a82b50: 
+7    1    atomic write    release       0x1a82b50   0                       ( 0,  7)
+location: 0x7f74888ecea8: 
+128  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b40           112 ( 0, 128)
+location: 0x7f74888ecea8: 
+128  1    atomic rmw      acquire  0x7f74888ecea8   0x1a82b40           112 ( 0, 128)
+location: 0x7f74888ecee8: 
+53   1    atomic rmw      release  0x7f74888ecee8   0x1a82b40           44  ( 0, 53)
+location: 0x1a82928: 
+131  1    atomic write    relaxed       0x1a82928   0x1a82a40               ( 0, 131)
+Program output from execution 1:
+---- BEGIN PROGRAM OUTPUT ----
+test start
+libcds - enqueue node m_pTail loc: 0x7f74888ecee8
+libcds - enqueue node m_pTail loc: 0x7f74888ecee8
+libcds - enqueue node m_pTail loc: 0x7f74888ecee8
+libcds - enqueue node m_pTail loc: 0x7f74888ecee8
+libcds - enqueue node m_pTail loc: 0x7f74888ecee8
+libcds - do_dequeue hode m_pHead loc: 0x7f74888ecea8
+libcds - do_dequeue hode m_pTail loc: 0x7f74888ecee8
+libcds - do_dequeue hode m_pHead loc: 0x7f74888ecea8
+libcds - do_dequeue hode m_pTail loc: 0x7f74888ecee8
+libcds - do_dequeue hode m_pHead loc: 0x7f74888ecea8
+libcds - do_dequeue hode m_pTail loc: 0x7f74888ecee8
+libcds - do_dequeue hode m_pHead loc: 0x7f74888ecea8
+libcds - do_dequeue hode m_pTail loc: 0x7f74888ecee8
+libcds - do_dequeue hode m_pHead loc: 0x7f74888ecea8
+libcds - do_dequeue hode m_pTail loc: 0x7f74888ecee8
+libcds - do_dequeue hode m_pHead loc: 0x7f74888ecea8
+libcds - do_dequeue hode m_pTail loc: 0x7f74888ecee8
+test end
+---- END PROGRAM OUTPUT   ----
+
+ecee8: ecf28, 1a82b10, 1a82b20, 1a82b30, 1a82b40, 1a82b50
+
diff --git a/pthread_test/CDSPass/addr-satcycle.cc b/pthread_test/CDSPass/addr-satcycle.cc
new file mode 100755 (executable)
index 0000000..84aa83d
Binary files /dev/null and b/pthread_test/CDSPass/addr-satcycle.cc differ
diff --git a/pthread_test/CDSPass/bug1.cc b/pthread_test/CDSPass/bug1.cc
new file mode 100755 (executable)
index 0000000..fe715a6
Binary files /dev/null and b/pthread_test/CDSPass/bug1.cc differ
diff --git a/pthread_test/CDSPass/compile.sh b/pthread_test/CDSPass/compile.sh
new file mode 100755 (executable)
index 0000000..56e324e
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# C test cases
+# clang -Xclang -load -Xclang /scratch/llvm/build/lib/libCDSPass.so -c -I/scratch/random-fuzzer/include/  /scratch/random-fuzzer/test/userprog.c
+
+# gcc -o userprog userprog.o -L/scratch/random-fuzzer -lmodel
+
+
+DIR=/scratch/random-fuzzer/pthread_test/CDSPass/dummy
+
+export LD_LIBRARY_PATH=/scratch/random-fuzzer
+
+# compile with CDSPass 
+if [ "$2" != "" ]; then # C++
+  clang++ -Xclang -load -Xclang /scratch/llvm/build/lib/libCDSPass.so -g -o $DIR/$1.o -I /scratch/random-fuzzer/include -L/scratch/random-fuzzer -lmodel $1
+else # C
+  clang -Xclang -load -Xclang /scratch/llvm/build/lib/libCDSPass.so -o $DIR/$1.o -I/scratch/random-fuzzer/include/ -L/scratch/random-fuzzer -lmodel $1
+fi
diff --git a/pthread_test/CDSPass/condvar.cc b/pthread_test/CDSPass/condvar.cc
new file mode 100755 (executable)
index 0000000..f4f111b
Binary files /dev/null and b/pthread_test/CDSPass/condvar.cc differ
diff --git a/pthread_test/CDSPass/deadlock.cc b/pthread_test/CDSPass/deadlock.cc
new file mode 100755 (executable)
index 0000000..76a9376
Binary files /dev/null and b/pthread_test/CDSPass/deadlock.cc differ
diff --git a/pthread_test/CDSPass/insanesync.cc b/pthread_test/CDSPass/insanesync.cc
new file mode 100755 (executable)
index 0000000..00bb40d
Binary files /dev/null and b/pthread_test/CDSPass/insanesync.cc differ
diff --git a/pthread_test/CDSPass/iriw.cc b/pthread_test/CDSPass/iriw.cc
new file mode 100755 (executable)
index 0000000..8042a13
Binary files /dev/null and b/pthread_test/CDSPass/iriw.cc differ
diff --git a/pthread_test/CDSPass/iriw_wildcard.cc b/pthread_test/CDSPass/iriw_wildcard.cc
new file mode 100755 (executable)
index 0000000..1b17a2a
Binary files /dev/null and b/pthread_test/CDSPass/iriw_wildcard.cc differ
diff --git a/pthread_test/CDSPass/mo-satcycle.cc b/pthread_test/CDSPass/mo-satcycle.cc
new file mode 100755 (executable)
index 0000000..8093885
Binary files /dev/null and b/pthread_test/CDSPass/mo-satcycle.cc differ
diff --git a/pthread_test/CDSPass/mutex_test.cc b/pthread_test/CDSPass/mutex_test.cc
new file mode 100755 (executable)
index 0000000..2c605c0
Binary files /dev/null and b/pthread_test/CDSPass/mutex_test.cc differ
diff --git a/pthread_test/CDSPass/pthread_mutex_test.cc b/pthread_test/CDSPass/pthread_mutex_test.cc
new file mode 100755 (executable)
index 0000000..ebda328
Binary files /dev/null and b/pthread_test/CDSPass/pthread_mutex_test.cc differ
diff --git a/pthread_test/CDSPass/uninit b/pthread_test/CDSPass/uninit
new file mode 100755 (executable)
index 0000000..f6b682f
Binary files /dev/null and b/pthread_test/CDSPass/uninit differ
diff --git a/pthread_test/CDSPass/uninit.cc b/pthread_test/CDSPass/uninit.cc
new file mode 100755 (executable)
index 0000000..f6b682f
Binary files /dev/null and b/pthread_test/CDSPass/uninit.cc differ
diff --git a/pthread_test/addr-satcycle.cc b/pthread_test/addr-satcycle.cc
new file mode 100644 (file)
index 0000000..a3d970b
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * @file addr-satcycle.cc
+ * @brief Address-based satisfaction cycle test
+ *
+ * This program has a peculiar behavior which is technically legal under the
+ * current C++ memory model but which is a result of a type of satisfaction
+ * cycle. We use this as justification for part of our modifications to the
+ * memory model when proving our model-checker's correctness.
+ */
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+
+#include "model-assert.h"
+
+using namespace std;
+
+atomic_int x[2], idx, y;
+
+int r1, r2, r3; /* "local" variables */
+
+static void *a(void *obj)
+{
+       r1 = idx.load(memory_order_relaxed);
+       x[r1].store(0, memory_order_relaxed);
+
+       /* Key point: can we guarantee that &x[0] == &x[r1]? */
+       r2 = x[0].load(memory_order_relaxed);
+       y.store(r2);
+       return NULL;
+}
+
+static void *b(void *obj)
+{
+       r3 = y.load(memory_order_relaxed);
+       idx.store(r3, memory_order_relaxed);
+       return NULL;
+}
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2;
+
+       atomic_init(&x[0], 1);
+       atomic_init(&idx, 0);
+       atomic_init(&y, 0);
+
+       printf("Main thread: creating 2 threads\n");
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       printf("Main thread is finished\n");
+
+       printf("r1 = %d\n", r1);
+       printf("r2 = %d\n", r2);
+       printf("r3 = %d\n", r3);
+
+       /*
+        * This condition should not be hit because it only occurs under a
+        * satisfaction cycle
+        */
+       bool cycle = (r1 == 1 && r2 == 1 && r3 == 1);
+       MODEL_ASSERT(!cycle);
+
+       return 0;
+}
diff --git a/pthread_test/bug1.cc b/pthread_test/bug1.cc
new file mode 100644 (file)
index 0000000..16d2b59
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * @file iriw.cc
+ * @brief Independent read and independent write test
+ */
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+
+#define N 14
+//#include "wildcard.h"
+//#include "model-assert.h"
+
+using namespace std;
+
+std::atomic_int x, y;
+int r1, r2, r3, r4; /* "local" variables */
+
+static void *a(void *obj)
+{
+//     x.store(1, memory_order_seq_cst);
+       return NULL;
+}
+
+
+static void *b(void *obj)
+{
+       y.store(1, memory_order_seq_cst);
+       return NULL;
+}
+
+static void *c(void *obj)
+{
+       r1 = x.load(memory_order_acquire);
+       r2 = y.load(memory_order_seq_cst);
+       return NULL;
+}
+
+static void *d(void *obj)
+{
+       r3 = y.load(memory_order_acquire);
+       r4 = x.load(memory_order_seq_cst);
+       return NULL;
+}
+
+
+int user_main(int argc, char **argv)
+{
+       pthread_t threads[20];
+
+       atomic_init(&x, 0);
+       atomic_init(&y, 0);
+
+       printf("Main thread: creating %d threads\n", N);
+
+       for (int i = 0; i< N; i++)
+               pthread_create(&threads[i],NULL, &a, NULL);
+
+       for (int i=0; i<N; i++)
+               printf("thread id: %ld\n", threads[i]);
+
+       for (int i = 0; i< N; i++)
+               pthread_join( threads[i],NULL);
+
+       printf("Main thread is finished\n");
+
+       /*
+        * This condition should not be hit if the execution is SC */
+//     bool sc = (r1 == 1 && r2 == 0 && r3 == 1 && r4 == 0);
+//     printf("r1 = %d, r2 = %d, r3 = %d and r4 = %d\n", r1, r2, r3, r4);
+//     MODEL_ASSERT(!sc);
+
+       return 0;
+}
diff --git a/pthread_test/condvar.cc b/pthread_test/condvar.cc
new file mode 100644 (file)
index 0000000..aae622b
--- /dev/null
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+#include "pthread.h"
+#include "librace.h"
+#include "stdatomic.h"
+#include "mutex.h"
+#include <condition_variable>
+
+cdsc::mutex * m;
+cdsc::condition_variable *v;
+int shareddata;
+
+static void *a(void *obj)
+{
+       m->lock();
+       while(load_32(&shareddata)==0)
+               v->wait(*m);
+       m->unlock();
+       return NULL;
+}
+
+static void *b(void *obj)
+{
+       m->lock();
+       store_32(&shareddata, (unsigned int) 1);
+       v->notify_all();
+       m->unlock();
+       return NULL;
+}
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2;
+       store_32(&shareddata, (unsigned int) 0);
+       m=new cdsc::mutex();
+       v=new cdsc::condition_variable();
+
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       return 0;
+}
diff --git a/pthread_test/deadlock.cc b/pthread_test/deadlock.cc
new file mode 100644 (file)
index 0000000..4382819
--- /dev/null
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <pthread.h>
+
+#include "librace.h"
+
+pthread_mutex_t x;
+pthread_mutex_t y;
+uint32_t shared = 0;
+
+static void *a(void *obj)
+{
+       pthread_mutex_lock(&x);
+       pthread_mutex_lock(&y);
+       printf("shared = %u\n", load_32(&shared));
+       pthread_mutex_unlock(&y);
+       pthread_mutex_unlock(&x);
+       return NULL;
+}
+
+static void *b(void *obj)
+{
+       pthread_mutex_lock(&y);
+       pthread_mutex_lock(&x);
+       store_32(&shared, 16);
+       printf("write shared = 16\n");
+       pthread_mutex_unlock(&x);
+       pthread_mutex_unlock(&y);
+       return NULL;
+}
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2;
+
+       pthread_mutex_init(&x, NULL);
+       pthread_mutex_init(&y, NULL);
+
+       printf("Main thread: creating 2 threads\n");
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       printf("Main thread is finished\n");
+
+       return 0;
+}
diff --git a/pthread_test/insanesync.cc b/pthread_test/insanesync.cc
new file mode 100644 (file)
index 0000000..bcc34ad
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <atomic>
+
+#include "librace.h"
+#include "model-assert.h"
+
+using namespace std;
+
+atomic_int x, y;
+atomic_intptr_t z, z2;
+
+int r1, r2, r3; /* "local" variables */
+
+/**
+               This example illustrates a self-satisfying cycle involving
+               synchronization.  A failed synchronization creates the store that
+               causes the synchronization to fail.
+
+               The C++11 memory model nominally allows r1=0, r2=1, r3=5.
+
+               This example is insane, we don't support that behavior.
+*/
+
+
+static void *a(void *obj)
+{
+       z.store((intptr_t)&y, memory_order_relaxed);
+       r1 = y.fetch_add(1, memory_order_release);
+       z.store((intptr_t)&x, memory_order_relaxed);
+       r2 = y.fetch_add(1, memory_order_release);
+       return NULL;
+}
+
+
+static void *b(void *obj)
+{
+       r3 = y.fetch_add(1, memory_order_acquire);
+       intptr_t ptr = z.load(memory_order_relaxed);
+       z2.store(ptr, memory_order_relaxed);
+       return NULL;
+}
+
+static void *c(void *obj)
+{
+       atomic_int *ptr2 = (atomic_int *)z2.load(memory_order_relaxed);
+       (*ptr2).store(5, memory_order_relaxed);
+       return NULL;
+}
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2, t3;
+
+       atomic_init(&x, 0);
+       atomic_init(&y, 0);
+       atomic_init(&z, (intptr_t) &x);
+       atomic_init(&z2, (intptr_t) &x);
+
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+       pthread_create(&t3,NULL, &c, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       pthread_join(t3,NULL);
+
+       printf("r1=%d, r2=%d, r3=%d\n", r1, r2, r3);
+
+       return 0;
+}
diff --git a/pthread_test/iriw.cc b/pthread_test/iriw.cc
new file mode 100644 (file)
index 0000000..42ba936
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * @file iriw.cc
+ * @brief Independent read and independent write test
+ */
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+
+#include "wildcard.h"
+#include "model-assert.h"
+
+using namespace std;
+
+atomic_int x, y;
+int r1, r2, r3, r4; /* "local" variables */
+
+static void *a(void *obj)
+{
+       x.store(1, memory_order_seq_cst);
+       return new int(1);
+}
+
+static void *b(void *obj)
+{
+       y.store(1, memory_order_seq_cst);
+       return new int(2);
+}
+
+static void *c(void *obj)
+{
+       r1 = x.load(memory_order_acquire);
+       r2 = y.load(memory_order_seq_cst);
+       return new int(3);
+}
+
+static void *d(void *obj)
+{
+       r3 = y.load(memory_order_acquire);
+       r4 = x.load(memory_order_seq_cst);
+       return new int(4);
+}
+
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2, t3, t4;
+
+       atomic_init(&x, 0);
+       atomic_init(&y, 0);
+
+       printf("Main thread: creating 4 threads\n");
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+       pthread_create(&t3,NULL, &c, NULL);
+       pthread_create(&t4,NULL, &d, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       pthread_join(t3,NULL);
+       pthread_join(t4,NULL);
+       printf("Main thread is finished\n");
+
+       /*
+        * This condition should not be hit if the execution is SC */
+       bool sc = (r1 == 1 && r2 == 0 && r3 == 1 && r4 == 0);
+       printf("r1 = %d, r2 = %d, r3 = %d and r4 = %d\n", r1, r2, r3, r4);
+       MODEL_ASSERT(!sc);
+
+       return 0;
+}
diff --git a/pthread_test/iriw_wildcard.cc b/pthread_test/iriw_wildcard.cc
new file mode 100644 (file)
index 0000000..adea420
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * @file iriw.cc
+ * @brief Independent read and independent write test
+ */
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+
+#include "wildcard.h"
+#include "model-assert.h"
+
+using namespace std;
+
+atomic_int x, y;
+int r1, r2, r3, r4; /* "local" variables */
+
+static void *a(void *obj)
+{
+       x.store(1, wildcard(1));
+       return NULL;
+}
+
+static void *b(void *obj)
+{
+       y.store(1, wildcard(2));
+       return NULL;
+}
+
+static void *c(void *obj)
+{
+       r1 = x.load(wildcard(3));
+       r2 = y.load(wildcard(4));
+       return NULL;
+}
+
+static void *d(void *obj)
+{
+       r3 = y.load(wildcard(5));
+       r4 = x.load(wildcard(6));
+       return NULL;
+}
+
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2, t3, t4;
+
+       atomic_init(&x, 0);
+       atomic_init(&y, 0);
+
+       printf("Main thread: creating 4 threads\n");
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+       pthread_create(&t3,NULL, &c, NULL);
+       pthread_create(&t4,NULL, &d, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       pthread_join(t3,NULL);
+       pthread_join(t4,NULL);
+       printf("Main thread is finished\n");
+
+       /*
+        * This condition should not be hit if the execution is SC */
+       bool sc = (r1 == 1 && r2 == 0 && r3 == 1 && r4 == 0);
+       //MODEL_ASSERT(!sc);
+
+       return 0;
+}
diff --git a/pthread_test/mo-satcycle.cc b/pthread_test/mo-satcycle.cc
new file mode 100644 (file)
index 0000000..d0a6055
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * @file mo-satcycle.cc
+ * @brief MO satisfaction cycle test
+ *
+ * This program has a peculiar behavior which is technically legal under the
+ * current C++ memory model but which is a result of a type of satisfaction
+ * cycle. We use this as justification for part of our modifications to the
+ * memory model when proving our model-checker's correctness.
+ */
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+
+#include "model-assert.h"
+
+using namespace std;
+
+atomic_int x, y;
+int r0, r1, r2, r3; /* "local" variables */
+
+static void *a(void *obj)
+{
+       y.store(10, memory_order_relaxed);
+       x.store(1, memory_order_release);
+       return NULL;
+}
+
+static void *b(void *obj)
+{
+       r0 = x.load(memory_order_relaxed);
+       r1 = x.load(memory_order_acquire);
+       y.store(11, memory_order_relaxed);
+       return NULL;
+}
+
+static void *c(void *obj)
+{
+       r2 = y.load(memory_order_relaxed);
+       r3 = y.load(memory_order_relaxed);
+       if (r2 == 11 && r3 == 10)
+               x.store(0, memory_order_relaxed);
+       return NULL;
+}
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2, t3;
+
+       atomic_init(&x, 0);
+       atomic_init(&y, 0);
+
+       printf("Main thread: creating 3 threads\n");
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+       pthread_create(&t3,NULL, &c, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       pthread_join(t3,NULL);
+       printf("Main thread is finished\n");
+
+       /*
+        * This condition should not be hit because it only occurs under a
+        * satisfaction cycle
+        */
+       bool cycle = (r0 == 1 && r1 == 0 && r2 == 11 && r3 == 10);
+       MODEL_ASSERT(!cycle);
+
+       return 0;
+}
diff --git a/pthread_test/normal_compile.sh b/pthread_test/normal_compile.sh
new file mode 100755 (executable)
index 0000000..56cba5a
--- /dev/null
@@ -0,0 +1,9 @@
+#g++ -o test.o test.cc -Wall -g -O3 -I.. -I../include -L.. -lmodel
+
+export LD_LIBRARY_PATH=/scratch/random-fuzzer
+
+if [ "$2" != "" ]; then
+  g++ -o "$1.o" $1 -Wall -g -O3 -I.. -I../include -L.. -lmodel
+else
+  gcc -o "$1.o" $1 -Wall -g -O3 -I.. -I../include -L.. -lmodel
+fi
diff --git a/pthread_test/protect/mutex_test.cc b/pthread_test/protect/mutex_test.cc
new file mode 100644 (file)
index 0000000..9a84b1d
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdio.h> 
+#include "threads.h" 
+#include "librace.h" 
+#include "stdatomic.h" 
+#include <pthread.h>
+
+int shareddata;  
+pthread_mutex_t m;
+
+static void* a(void *obj) 
+{ 
+        int i; 
+        for(i=0;i<2;i++) { 
+                if ((i%2)==0) { 
+                        pthread_mutex_lock(&m);
+                        store_32(&shareddata,(unsigned int)i); 
+                       printf("shareddata: %d\n", shareddata);
+                        pthread_mutex_unlock(&m);
+                } else { 
+                        while(!pthread_mutex_trylock(&m))
+                                thrd_yield(); 
+                        store_32(&shareddata,(unsigned int)i); 
+                       printf("shareddata: %d\n", shareddata);
+                        pthread_mutex_unlock(&m);
+                } 
+        } 
+} 
+int user_main(int argc, char **argv) 
+{ 
+        thrd_t t1, t2; 
+       pthread_mutex_init(&m, NULL);
+
+        thrd_create(&t1, (thrd_start_t)&a, NULL);
+        thrd_create(&t2, (thrd_start_t)&a, NULL);
+
+        thrd_join(t1); 
+        thrd_join(t2); 
+        return 0; 
+}
diff --git a/pthread_test/pthread_mutex_test.cc b/pthread_test/pthread_mutex_test.cc
new file mode 100644 (file)
index 0000000..55bea22
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <pthread.h>
+#define NTHREADS 2
+void *thread_function(void *);
+//pthread_mutex_t mutex1; 
+
+int counter=0;
+
+class Box {
+public:
+//     int counter;
+
+       static Box& getInstance() {
+               static Box instance;
+               return instance;
+       }
+
+       void addone() {
+               pthread_mutex_lock(&pool_mutex);
+               counter++;
+               pthread_mutex_unlock(&pool_mutex);
+       }
+
+private:
+       Box() { 
+               pthread_mutex_init(&pool_mutex, NULL); 
+               counter = 0;
+       }
+       pthread_mutex_t pool_mutex;
+};
+
+int user_main(int argv, char **argc)
+{
+//   void *dummy = NULL;
+//   pthread_mutex_init(&mutex1, NULL); /* PTHREAD_MUTEX_INITIALIZER;*/
+
+//   pthread_t thread_id[NTHREADS];
+//   int i, j;
+
+   Box::getInstance().addone();
+
+/*   for(i=0; i < NTHREADS; i++)
+   {
+      pthread_create( &thread_id[i], NULL, &thread_function, NULL );
+   }
+
+   for(j=0; j < NTHREADS; j++)
+   {
+      pthread_join( thread_id[j], NULL); 
+   }
+*/
+   printf("Final counter value: %d\n", counter);
+   /*
+   for (i=0;i<NTHREADS; i++) {
+      printf("id %ld\n", thread_id[i]);
+   }*/
+   return 0;
+}
+
+void *thread_function(void *dummyPtr)
+{
+//   printf("Thread number %ld\n", pthread_self());
+   Box::getInstance().addone();
+//   pthread_mutex_lock( &mutex1 );
+//   Box::getInstance().counter++;
+//   pthread_mutex_unlock( &mutex1 );
+   return NULL;
+}
diff --git a/pthread_test/test.cc b/pthread_test/test.cc
new file mode 100644 (file)
index 0000000..f5b0857
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * @file iriw.cc
+ * @brief Independent read and independent write test
+ */
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+#include <iostream>
+
+#define N 4
+//#include "wildcard.h"
+//#include "model-assert.h"
+
+using namespace std;
+
+atomic<int> x(1);
+atomic<int> y(1);
+
+int r1, r2, r3, r4; /* "local" variables */
+
+static void *a(void *obj)
+{
+       x.store(1, memory_order_relaxed);
+       y.store(1, memory_order_relaxed);
+
+       return new int(1);
+}
+
+
+static void *b(void *obj)
+{
+       y.store(1, memory_order_relaxed);
+       
+       return new int(2);
+}
+
+static void *c(void *obj)
+{
+       r1 = x.load(memory_order_acquire);
+       r2 = y.load(memory_order_relaxed);
+
+       return new int(3);
+}
+
+static void *d(void *obj)
+{
+       r3 = y.load(memory_order_acquire);
+       r4 = x.load(memory_order_relaxed);
+
+       return new int(4);
+}
+
+
+int main(int argc, char **argv)
+{
+       printf("Main thread starts\n");
+
+       x.store(2, memory_order_relaxed);
+       y.store(2, memory_order_relaxed);
+
+       r1 = x.load(memory_order_relaxed);
+       printf("%d\n", r1);
+
+//     x.compare_exchange_strong(r1, r2);
+//     r3 = x.load(memory_order_relaxed);
+
+//     printf("%d\n", r3);
+
+       printf("Main thread is finished\n");
+
+       return 0;
+}
diff --git a/pthread_test/uninit.cc b/pthread_test/uninit.cc
new file mode 100644 (file)
index 0000000..075e2ac
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * @file uninit.cc
+ * @brief Uninitialized loads test
+ *
+ * This is a test of the "uninitialized loads" code. While we don't explicitly
+ * initialize y, this example's synchronization pattern should guarantee we
+ * never see it uninitialized.
+ */
+#include <stdio.h>
+#include <pthread.h>
+#include <atomic>
+
+//#include "librace.h"
+
+std::atomic_int x;
+std::atomic_int y;
+
+static void *a(void *obj)
+{
+       int flag = x.load(std::memory_order_acquire);
+       printf("flag: %d\n", flag);
+       if (flag == 2)
+               printf("Load: %d\n", y.load(std::memory_order_relaxed));
+       return NULL;
+}
+
+static void *b(void *obj)
+{
+       printf("fetch_add: %d\n", x.fetch_add(1, std::memory_order_relaxed));
+       return NULL;
+}
+
+static void *c(void *obj)
+{
+       y.store(3, std::memory_order_relaxed);
+       x.store(1, std::memory_order_release);
+       return NULL;
+}
+
+int user_main(int argc, char **argv)
+{
+       pthread_t t1, t2, t3;
+
+       std::atomic_init(&x, 0);
+
+       printf("Main thread: creating 3 threads\n");
+       pthread_create(&t1,NULL, &a, NULL);
+       pthread_create(&t2,NULL, &b, NULL);
+       pthread_create(&t3,NULL, &c, NULL);
+
+       pthread_join(t1,NULL);
+       pthread_join(t2,NULL);
+       pthread_join(t3,NULL);
+       printf("Main thread is finished\n");
+
+       return 0;
+}
diff --git a/sleeps.cc b/sleeps.cc
new file mode 100644 (file)
index 0000000..0528374
--- /dev/null
+++ b/sleeps.cc
@@ -0,0 +1,26 @@
+#include <time.h>
+#include <unistd.h>
+
+#include "action.h"
+#include "model.h"
+
+unsigned int __sleep (unsigned int seconds)
+{
+       model->switch_to_master(
+               new ModelAction(NOOP, std::memory_order_seq_cst, NULL)
+       );
+       return 0;
+}
+
+unsigned int sleep(unsigned int seconds)
+{
+       return __sleep(seconds);
+}
+
+int usleep (useconds_t useconds)
+{
+       model->switch_to_master(
+               new ModelAction(NOOP, std::memory_order_seq_cst, NULL)
+       );
+       return 0;
+}