Use simple_action_list for conditionvariable waiters
authorweiyu <weiyuluo1232@gmail.com>
Wed, 8 Apr 2020 22:41:58 +0000 (15:41 -0700)
committerweiyu <weiyuluo1232@gmail.com>
Wed, 8 Apr 2020 22:41:58 +0000 (15:41 -0700)
16 files changed:
Makefile
action.cc
action.h
actionlist.cc [new file with mode: 0644]
actionlist.h [new file with mode: 0644]
classlist.h
config.h
execution.cc
execution.h
fuzzer.cc
fuzzer.h
model.h
newfuzzer.h
stl-model.h
threads-model.h
threads.cc

index 4f83cd99a12883b2954d075a72e1f52353891730..adb080de5d44871596ee201fb659666684645bbc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ OBJECTS := libthreads.o schedule.o model.o threads.o librace.o action.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 \
           sleeps.o history.o funcnode.o funcinst.o predicate.o printf.o newfuzzer.o \
-          concretepredicate.o waitobj.o hashfunction.o pipe.o
+          concretepredicate.o waitobj.o hashfunction.o pipe.o actionlist.o
 
 CPPFLAGS += -Iinclude -I.
 LDFLAGS := -ldl -lrt -rdynamic -lpthread
index d65695446486e58a929196335660d8c3172cb94d..d90a94ee48211ddb17e9a3f26cafcb4e56ca9e55 100644 (file)
--- a/action.cc
+++ b/action.cc
@@ -38,9 +38,6 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
        last_fence_release(NULL),
        cv(NULL),
        rf_cv(NULL),
-       trace_ref(NULL),
-       thrdmap_ref(NULL),
-       action_ref(NULL),
        value(value),
        type(type),
        order(order),
@@ -72,9 +69,6 @@ ModelAction::ModelAction(action_type_t type, memory_order order, uint64_t value,
        last_fence_release(NULL),
        cv(NULL),
        rf_cv(NULL),
-       trace_ref(NULL),
-       thrdmap_ref(NULL),
-       action_ref(NULL),
        value(value),
        type(type),
        order(order),
@@ -105,9 +99,6 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc,
        last_fence_release(NULL),
        cv(NULL),
        rf_cv(NULL),
-       trace_ref(NULL),
-       thrdmap_ref(NULL),
-       action_ref(NULL),
        value(value),
        type(type),
        order(order),
@@ -142,9 +133,6 @@ ModelAction::ModelAction(action_type_t type, const char * position, memory_order
        last_fence_release(NULL),
        cv(NULL),
        rf_cv(NULL),
-       trace_ref(NULL),
-       thrdmap_ref(NULL),
-       action_ref(NULL),
        value(value),
        type(type),
        order(order),
@@ -180,9 +168,6 @@ ModelAction::ModelAction(action_type_t type, const char * position, memory_order
        last_fence_release(NULL),
        cv(NULL),
        rf_cv(NULL),
-       trace_ref(NULL),
-       thrdmap_ref(NULL),
-       action_ref(NULL),
        value(value),
        type(type),
        order(order),
index 35368ef7fff3ca0bea12de7b375260e331cbded1..c5ba6d7dda9f9593a315a26c3d1da336a50b5a0f 100644 (file)
--- a/action.h
+++ b/action.h
@@ -192,12 +192,6 @@ public:
        /* to accomodate pthread create and join */
        Thread * thread_operand;
        void set_thread_operand(Thread *th) { thread_operand = th; }
-       void setTraceRef(sllnode<ModelAction *> *ref) { trace_ref = ref; }
-       void setThrdMapRef(sllnode<ModelAction *> *ref) { thrdmap_ref = ref; }
-       void setActionRef(sllnode<ModelAction *> *ref) { action_ref = ref; }
-       sllnode<ModelAction *> * getTraceRef() { return trace_ref; }
-       sllnode<ModelAction *> * getThrdMapRef() { return thrdmap_ref; }
-       sllnode<ModelAction *> * getActionRef() { return action_ref; }
 
        SNAPSHOTALLOC
 private:
@@ -233,9 +227,6 @@ private:
         */
        ClockVector *cv;
        ClockVector *rf_cv;
-       sllnode<ModelAction *> * trace_ref;
-       sllnode<ModelAction *> * thrdmap_ref;
-       sllnode<ModelAction *> * action_ref;
 
        /** @brief The value written (for write or RMW; undefined for read) */
        uint64_t value;
diff --git a/actionlist.cc b/actionlist.cc
new file mode 100644 (file)
index 0000000..e76f5ae
--- /dev/null
@@ -0,0 +1,255 @@
+#include "actionlist.h"
+#include "action.h"
+#include <string.h>
+#include "stl-model.h"
+#include <limits.h>
+
+actionlist::actionlist() :
+       head(NULL),
+       tail(NULL),
+       _size(0)
+{
+       root.parent = NULL;
+}
+
+actionlist::~actionlist() {
+}
+
+allnode::allnode() :
+       count(0) {
+       bzero(children, sizeof(children));
+}
+
+allnode::~allnode() {
+       if (count != 0)
+               for(int i=0;i<ALLNODESIZE;i++) {
+                       if (children[i] != NULL && !(((uintptr_t) children[i]) & ISACT))
+                               delete children[i];
+               }
+}
+
+sllnode<ModelAction *> * allnode::findPrev(modelclock_t index) {
+       allnode * ptr = this;
+       modelclock_t increment = 1;
+       modelclock_t mask = ALLMASK;
+       int totalshift = 0;
+       index -= increment;
+
+       while(1) {
+               modelclock_t shiftclock = index >> totalshift;
+               modelclock_t currindex = shiftclock & ALLMASK;
+
+               //See if we went negative...
+               if (currindex != ALLMASK) {
+                       if (ptr->children[currindex] == NULL) {
+                               //need to keep searching at this level
+                               index -= increment;
+                               continue;
+                       } else {
+                               //found non-null...
+                               if (totalshift == 0)
+                                       return reinterpret_cast<sllnode<ModelAction *> *>(((uintptr_t)ptr->children[currindex])& ACTMASK);
+                               //need to increment here...
+                               ptr = ptr->children[currindex];
+                               increment = increment >> ALLBITS;
+                               mask = mask >> ALLBITS;
+                               totalshift -= ALLBITS;
+                               break;
+                       }
+               }
+               //If we get here, we already did the decrement earlier...no need to decrement again
+               ptr = ptr->parent;
+               increment = increment << ALLBITS;
+               mask = mask << ALLBITS;
+               totalshift += ALLBITS;
+
+               if (ptr == NULL) {
+                       return NULL;
+               }
+       }
+
+       while(1) {
+               while(1) {
+                       modelclock_t shiftclock = index >> totalshift;
+                       modelclock_t currindex = shiftclock & ALLMASK;
+                       if (ptr->children[currindex] != NULL) {
+                               if (totalshift != 0) {
+                                       ptr = ptr->children[currindex];
+                                       break;
+                               } else {
+                                       allnode * act = ptr->children[currindex];
+                                       sllnode<ModelAction *> * node = reinterpret_cast<sllnode<ModelAction *>*>(((uintptr_t)act) & ACTMASK);
+                                       return node;
+                               }
+                       }
+                       index -= increment;
+               }
+
+               increment = increment >> ALLBITS;
+               mask = mask >> ALLBITS;
+               totalshift -= ALLBITS;
+       }
+}
+
+void actionlist::addAction(ModelAction * act) {
+       _size++;
+       int shiftbits = MODELCLOCKBITS - ALLBITS;
+       modelclock_t clock = act->get_seq_number();
+
+       allnode * ptr = &root;
+       do {
+               int index = (clock >> shiftbits) & ALLMASK;
+               allnode * tmp = ptr->children[index];
+               if (shiftbits == 0) {
+                       sllnode<ModelAction *> * llnode = new sllnode<ModelAction *>();
+                       llnode->val = act;
+                       if (tmp == NULL) {
+                               sllnode<ModelAction *> * llnodeprev = ptr->findPrev(clock);
+                               if (llnodeprev != NULL) {
+                                       llnode->next = llnodeprev->next;
+                                       llnode->prev = llnodeprev;
+
+                                       //see if we are the new tail
+                                       if (llnode->next != NULL)
+                                               llnode->next->prev = llnode;
+                                       else
+                                               tail = llnode;
+                                       llnodeprev->next = llnode;
+                               } else {
+                                       //We are the begining
+                                       llnode->next = head;
+                                       llnode->prev = NULL;
+                                       if (head != NULL) {
+                                               head->prev = llnode;
+                                       } else {
+                                               //we are the first node
+                                               tail = llnode;
+                                       }
+
+                                       head = llnode;
+                               }
+                               ptr->children[index] = reinterpret_cast<allnode *>(((uintptr_t) llnode) | ISACT);
+
+                               //need to find next link
+                               ptr->count++;
+                       } else {
+                               //handle case where something else is here
+
+                               sllnode<ModelAction *> * llnodeprev = reinterpret_cast<sllnode<ModelAction *>*>(((uintptr_t) tmp) & ACTMASK);
+                               llnode->next = llnodeprev->next;
+                               llnode->prev = llnodeprev;
+                               if (llnode->next != NULL)
+                                       llnode->next->prev = llnode;
+                               else
+                                       tail = llnode;
+                               llnodeprev->next = llnode;
+                               ptr->children[index] = reinterpret_cast<allnode *>(((uintptr_t) llnode) | ISACT);
+                       }
+                       return;
+               } else if (tmp == NULL) {
+                       tmp = new allnode();
+                       ptr->children[index] = tmp;
+                       tmp->parent=ptr;
+                       ptr->count++;
+               }
+               shiftbits -= ALLBITS;
+               ptr = tmp;
+       } while(1);
+
+}
+
+void decrementCount(allnode * ptr) {
+       ptr->count--;
+       if (ptr->count == 0) {
+               if (ptr->parent != NULL) {
+                       for(uint i=0;i<ALLNODESIZE;i++) {
+                               if (ptr->parent->children[i]==ptr) {
+                                       ptr->parent->children[i] = NULL;
+                                       decrementCount(ptr->parent);
+                               }
+                       }
+                       delete ptr;
+               }
+       }
+}
+
+void actionlist::removeAction(ModelAction * act) {
+       int shiftbits = MODELCLOCKBITS - ALLBITS;
+       modelclock_t clock = act->get_seq_number();
+       allnode * ptr = &root;
+       do {
+               int index = (clock >> shiftbits) & ALLMASK;
+               allnode * tmp = ptr->children[index];
+               if (shiftbits == 0) {
+                       if (tmp == NULL) {
+                               //not found
+                               return;
+                       } else {
+                               sllnode<ModelAction *> * llnode = reinterpret_cast<sllnode<ModelAction *> *>(((uintptr_t) tmp) & ACTMASK);
+                               bool first = true;
+                               do {
+                                       if (llnode->val == act) {
+                                               //found node to remove
+                                               sllnode<ModelAction *> * llnodeprev = llnode->prev;
+                                               sllnode<ModelAction *> * llnodenext = llnode->next;
+                                               if (llnodeprev != NULL) {
+                                                       llnodeprev->next = llnodenext;
+                                               } else {
+                                                       head = llnodenext;
+                                               }
+                                               if (llnodenext != NULL) {
+                                                       llnodenext->prev = llnodeprev;
+                                               } else {
+                                                       tail = llnodeprev;
+                                               }
+                                               if (first) {
+                                                       //see if previous node has same clock as us...
+                                                       if (llnodeprev != NULL && llnodeprev->val->get_seq_number() == clock) {
+                                                               ptr->children[index] = reinterpret_cast<allnode *>(((uintptr_t)llnodeprev) | ISACT);
+                                                       } else {
+                                                               //remove ourselves and go up tree
+                                                               ptr->children[index] = NULL;
+                                                               decrementCount(ptr);
+                                                       }
+                                               }
+                                               delete llnode;
+                                               _size--;
+                                               return;
+                                       }
+                                       llnode = llnode->prev;
+                                       first = false;
+                               } while(llnode != NULL && llnode->val->get_seq_number() == clock);
+                               //node not found in list... no deletion
+                               return;
+                       }
+               } else if (tmp == NULL) {
+                       //not found
+                       return;
+               }
+               shiftbits -= ALLBITS;
+               ptr = tmp;
+       } while(1);
+}
+
+void actionlist::clear() {
+       for(uint i = 0;i < ALLNODESIZE;i++) {
+               if (root.children[i] != NULL) {
+                       delete root.children[i];
+                       root.children[i] = NULL;
+               }
+       }
+
+       while(head != NULL) {
+               sllnode<ModelAction *> *tmp=head->next;
+               delete head;
+               head = tmp;
+       }
+       tail=NULL;
+
+       root.count = 0;
+       _size = 0;
+}
+
+bool actionlist::isEmpty() {
+       return root.count == 0;
+}
diff --git a/actionlist.h b/actionlist.h
new file mode 100644 (file)
index 0000000..20f93fc
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef ACTIONLIST_H
+#define ACTIONLIST_H
+
+#include "classlist.h"
+#include "stl-model.h"
+
+#define ISACT ((uintptr_t) 1ULL)
+#define ACTMASK (~ISACT)
+
+#define ALLBITS 4
+#define ALLNODESIZE (1 << ALLBITS)
+#define ALLMASK ((1 << ALLBITS)-1)
+#define MODELCLOCKBITS 32
+
+class allnode;
+void decrementCount(allnode *);
+
+class allnode {
+public:
+       allnode();
+       ~allnode();
+       SNAPSHOTALLOC;
+
+private:
+       allnode * parent;
+       allnode * children[ALLNODESIZE];
+       int count;
+       sllnode<ModelAction *> * findPrev(modelclock_t index);
+       friend class actionlist;
+       friend void decrementCount(allnode *);
+};
+
+class actionlist {
+public:
+       actionlist();
+       ~actionlist();
+       void addAction(ModelAction * act);
+       void removeAction(ModelAction * act);
+       void clear();
+       bool isEmpty();
+       uint size() {return _size;}
+       sllnode<ModelAction *> * begin() {return head;}
+       sllnode<ModelAction *> * end() {return tail;}
+
+       SNAPSHOTALLOC;
+
+private:
+       allnode root;
+       sllnode<ModelAction *> * head;
+       sllnode<ModelAction* > * tail;
+
+       uint _size;
+};
+#endif
index ccbbbb1418a9ca785394e41df2480f24f22a923d..e74ebcf64bdbb5aace60103095d47dcf09bfd395 100644 (file)
@@ -22,11 +22,15 @@ class FuncInst;
 class Predicate;
 class ConcretePredicate;
 class WaitObj;
+class actionlist;
+
+#include "actionlist.h"
 
 struct model_snapshot_members;
 struct bug_message;
 
-typedef SnapList<ModelAction *> action_list_t;
+typedef SnapList<ModelAction *> simple_action_list_t;
+typedef actionlist action_list_t;
 typedef SnapList<uint32_t> func_id_list_t;
 typedef SnapList<FuncInst *> func_inst_list_t;
 
index 74c0c3516bfdb7367ef2daedb81798c7be58a74d..f86275a725a15344507dfbc46598e28fc95ba339 100644 (file)
--- a/config.h
+++ b/config.h
@@ -54,7 +54,7 @@
 #define FORK_HANDLER_HACK
 
 /** Enable smart fuzzer */
-#define NEWFUZZER
+//#define NEWFUZZER
 
 /** Define semantics of volatile memory operations. */
 #define memory_order_volatile_load memory_order_acquire
index 48c73cfbeca2db10dd19148062bded4bfd9858e7..9c3b4afa2986fac9ecce604e9de9394ebca6f3eb 100644 (file)
@@ -118,6 +118,16 @@ static SnapVector<action_list_t> * get_safe_ptr_vect_action(HashTable<const void
        return tmp;
 }
 
+static simple_action_list_t * get_safe_ptr_action(HashTable<const void *, simple_action_list_t *, uintptr_t, 2> * hash, void * ptr)
+{
+       simple_action_list_t *tmp = hash->get(ptr);
+       if (tmp == NULL) {
+               tmp = new simple_action_list_t();
+               hash->put(ptr, tmp);
+       }
+       return tmp;
+}
+
 /** @return a thread ID for a new Thread */
 thread_id_t ModelExecution::get_next_id()
 {
@@ -329,6 +339,10 @@ bool ModelExecution::process_read(ModelAction *curr, SnapVector<ModelAction *> *
                        read_from(curr, rf);
                        get_thread(curr)->set_return_value(curr->get_return_value());
                        delete priorset;
+                       //Update acquire fence clock vector
+                       ClockVector * hbcv = get_hb_from_write(curr->get_reads_from());
+                       if (hbcv != NULL)
+                               get_thread(curr)->get_acq_fence_cv()->merge(hbcv);
                        return canprune && (curr->get_type() == ATOMIC_READ);
                }
                priorset->clear();
@@ -402,7 +416,7 @@ bool ModelExecution::process_mutex(ModelAction *curr)
                        state->locked = NULL;
 
                        /* remove old wait action and disable this thread */
-                       action_list_t * waiters = get_safe_ptr_action(&condvar_waiters_map, curr->get_location());
+                       simple_action_list_t * waiters = get_safe_ptr_action(&condvar_waiters_map, curr->get_location());
                        for (sllnode<ModelAction *> * it = waiters->begin(); it != NULL; it = it->getNext()) {
                                ModelAction * wait = it->getVal();
                                if (wait->get_tid() == curr->get_tid()) {
@@ -442,7 +456,7 @@ bool ModelExecution::process_mutex(ModelAction *curr)
                break;
        }
        case ATOMIC_NOTIFY_ALL: {
-               action_list_t *waiters = get_safe_ptr_action(&condvar_waiters_map, curr->get_location());
+               simple_action_list_t *waiters = get_safe_ptr_action(&condvar_waiters_map, curr->get_location());
                //activate all the waiting threads
                for (sllnode<ModelAction *> * rit = waiters->begin();rit != NULL;rit=rit->getNext()) {
                        scheduler->wake(get_thread(rit->getVal()));
@@ -451,7 +465,7 @@ bool ModelExecution::process_mutex(ModelAction *curr)
                break;
        }
        case ATOMIC_NOTIFY_ONE: {
-               action_list_t *waiters = get_safe_ptr_action(&condvar_waiters_map, curr->get_location());
+               simple_action_list_t *waiters = get_safe_ptr_action(&condvar_waiters_map, curr->get_location());
                if (waiters->size() != 0) {
                        Thread * thread = fuzzer->selectNotify(waiters);
                        scheduler->wake(thread);
@@ -481,7 +495,7 @@ void ModelExecution::process_write(ModelAction *curr)
  * @param curr The ModelAction to process
  * @return True if synchronization was updated
  */
-bool ModelExecution::process_fence(ModelAction *curr)
+void ModelExecution::process_fence(ModelAction *curr)
 {
        /*
         * fence-relaxed: no-op
@@ -491,36 +505,9 @@ bool ModelExecution::process_fence(ModelAction *curr)
         *   sequences
         * fence-seq-cst: MO constraints formed in {r,w}_modification_order
         */
-       bool updated = false;
        if (curr->is_acquire()) {
-               action_list_t *list = &action_trace;
-               sllnode<ModelAction *> * rit;
-               /* Find X : is_read(X) && X --sb-> curr */
-               for (rit = list->end();rit != NULL;rit=rit->getPrev()) {
-                       ModelAction *act = rit->getVal();
-                       if (act == curr)
-                               continue;
-                       if (act->get_tid() != curr->get_tid())
-                               continue;
-                       /* Stop at the beginning of the thread */
-                       if (act->is_thread_start())
-                               break;
-                       /* Stop once we reach a prior fence-acquire */
-                       if (act->is_fence() && act->is_acquire())
-                               break;
-                       if (!act->is_read())
-                               continue;
-                       /* read-acquire will find its own release sequences */
-                       if (act->is_acquire())
-                               continue;
-
-                       /* Establish hypothetical release sequences */
-                       ClockVector *cv = get_hb_from_write(act->get_reads_from());
-                       if (cv != NULL && curr->get_cv()->merge(cv))
-                               updated = true;
-               }
+               curr->get_cv()->merge(get_thread(curr)->get_acq_fence_cv());
        }
-       return updated;
 }
 
 /**
@@ -1148,11 +1135,11 @@ void ModelExecution::add_action_to_lists(ModelAction *act, bool canprune)
        int tid = id_to_int(act->get_tid());
        if ((act->is_fence() && act->is_seqcst()) || act->is_unlock()) {
                action_list_t *list = get_safe_ptr_action(&obj_map, act->get_location());
-               act->setActionRef(list->add_back(act));
+               list->addAction(act);
        }
 
        // Update action trace, a total order of all actions
-       act->setTraceRef(action_trace.add_back(act));
+       action_trace.addAction(act);
 
 
        // Update obj_thrd_map, a per location, per thread, order of actions
@@ -1164,7 +1151,7 @@ void ModelExecution::add_action_to_lists(ModelAction *act, bool canprune)
                        new (&(*vec)[i]) action_list_t();
        }
        if (!canprune && (act->is_read() || act->is_write()))
-               act->setThrdMapRef((*vec)[tid].add_back(act));
+               (*vec)[tid].addAction(act);
 
        // Update thrd_last_action, the last action taken by each thread
        if ((int)thrd_last_action.size() <= tid)
@@ -1180,43 +1167,17 @@ void ModelExecution::add_action_to_lists(ModelAction *act, bool canprune)
 
        if (act->is_wait()) {
                void *mutex_loc = (void *) act->get_value();
-               act->setActionRef(get_safe_ptr_action(&obj_map, mutex_loc)->add_back(act));
+               get_safe_ptr_action(&obj_map, mutex_loc)->addAction(act);
        }
 }
 
-sllnode<ModelAction *>* insertIntoActionList(action_list_t *list, ModelAction *act) {
-       sllnode<ModelAction*> * rit = list->end();
-       modelclock_t next_seq = act->get_seq_number();
-       if (rit == NULL || (rit->getVal()->get_seq_number() <= next_seq))
-               return list->add_back(act);
-       else {
-               for(;rit != NULL;rit=rit->getPrev()) {
-                       if (rit->getVal()->get_seq_number() <= next_seq) {
-                               return list->insertAfter(rit, act);
-                       }
-               }
-               return list->add_front(act);
-       }
+void insertIntoActionList(action_list_t *list, ModelAction *act) {
+       list->addAction(act);
 }
 
-sllnode<ModelAction *>* insertIntoActionListAndSetCV(action_list_t *list, ModelAction *act) {
-       sllnode<ModelAction*> * rit = list->end();
-       modelclock_t next_seq = act->get_seq_number();
-       if (rit == NULL) {
-               act->create_cv(NULL);
-               return list->add_back(act);
-       } else if (rit->getVal()->get_seq_number() <= next_seq) {
-               act->create_cv(rit->getVal());
-               return list->add_back(act);
-       } else {
-               for(;rit != NULL;rit=rit->getPrev()) {
-                       if (rit->getVal()->get_seq_number() <= next_seq) {
-                               act->create_cv(rit->getVal());
-                               return list->insertAfter(rit, act);
-                       }
-               }
-               return list->add_front(act);
-       }
+void insertIntoActionListAndSetCV(action_list_t *list, ModelAction *act) {
+       act->create_cv(NULL);
+       list->addAction(act);
 }
 
 /**
@@ -1230,7 +1191,7 @@ sllnode<ModelAction *>* insertIntoActionListAndSetCV(action_list_t *list, ModelA
 void ModelExecution::add_normal_write_to_lists(ModelAction *act)
 {
        int tid = id_to_int(act->get_tid());
-       act->setTraceRef(insertIntoActionListAndSetCV(&action_trace, act));
+       insertIntoActionListAndSetCV(&action_trace, act);
 
        // Update obj_thrd_map, a per location, per thread, order of actions
        SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_thrd_map, act->get_location());
@@ -1240,7 +1201,7 @@ void ModelExecution::add_normal_write_to_lists(ModelAction *act)
                for(uint i=oldsize;i<priv->next_thread_id;i++)
                        new (&(*vec)[i]) action_list_t();
        }
-       act->setThrdMapRef(insertIntoActionList(&(*vec)[tid],act));
+       insertIntoActionList(&(*vec)[tid],act);
 
        ModelAction * lastact = thrd_last_action[tid];
        // Update thrd_last_action, the last action taken by each thrad
@@ -1258,7 +1219,7 @@ void ModelExecution::add_write_to_lists(ModelAction *write) {
                for(uint i=oldsize;i<priv->next_thread_id;i++)
                        new (&(*vec)[i]) action_list_t();
        }
-       write->setActionRef((*vec)[tid].add_back(write));
+       (*vec)[tid].addAction(write);
 }
 
 /**
@@ -1561,7 +1522,7 @@ void ModelExecution::print_tail()
        int length = 25;
        int counter = 0;
        SnapList<ModelAction *> list;
-       for (it = action_trace.end(); it != NULL; it = it->getPrev()) {
+       for (it = action_trace.end();it != NULL;it = it->getPrev()) {
                if (counter > length)
                        break;
 
@@ -1716,36 +1677,22 @@ Thread * ModelExecution::take_step(ModelAction *curr)
 
 void ModelExecution::removeAction(ModelAction *act) {
        {
-               sllnode<ModelAction *> * listref = act->getTraceRef();
-               if (listref != NULL) {
-                       action_trace.erase(listref);
-               }
+               action_trace.removeAction(act);
        }
        {
-               sllnode<ModelAction *> * listref = act->getThrdMapRef();
-               if (listref != NULL) {
-                       SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_thrd_map, act->get_location());
-                       (*vec)[act->get_tid()].erase(listref);
-               }
+               SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_thrd_map, act->get_location());
+               (*vec)[act->get_tid()].removeAction(act);
        }
        if ((act->is_fence() && act->is_seqcst()) || act->is_unlock()) {
-               sllnode<ModelAction *> * listref = act->getActionRef();
-               if (listref != NULL) {
-                       action_list_t *list = get_safe_ptr_action(&obj_map, act->get_location());
-                       list->erase(listref);
-               }
+               action_list_t *list = get_safe_ptr_action(&obj_map, act->get_location());
+               list->removeAction(act);
        } else if (act->is_wait()) {
-               sllnode<ModelAction *> * listref = act->getActionRef();
-               if (listref != NULL) {
-                       void *mutex_loc = (void *) act->get_value();
-                       get_safe_ptr_action(&obj_map, mutex_loc)->erase(listref);
-               }
+               void *mutex_loc = (void *) act->get_value();
+               get_safe_ptr_action(&obj_map, mutex_loc)->removeAction(act);
        } else if (act->is_free()) {
-               sllnode<ModelAction *> * listref = act->getActionRef();
-               if (listref != NULL) {
-                       SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_wr_thrd_map, act->get_location());
-                       (*vec)[act->get_tid()].erase(listref);
-               }
+               SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_wr_thrd_map, act->get_location());
+               (*vec)[act->get_tid()].removeAction(act);
+
                //Clear it from last_sc_map
                if (obj_last_sc_map.get(act->get_location()) == act) {
                        obj_last_sc_map.remove(act->get_location());
index 722b864723a40f8d902c5ed2920575d43b837b01..0c401b19b59084609a2fe12b1cbb565a736cfbac 100644 (file)
@@ -19,8 +19,6 @@
 #include <condition_variable>
 #include "classlist.h"
 
-typedef SnapList<ModelAction *> action_list_t;
-
 struct PendingFutureValue {
        PendingFutureValue(ModelAction *writer, ModelAction *reader) :
                writer(writer), reader(reader)
@@ -105,7 +103,7 @@ private:
        bool initialize_curr_action(ModelAction **curr);
        bool process_read(ModelAction *curr, SnapVector<ModelAction *> * rf_set);
        void process_write(ModelAction *curr);
-       bool process_fence(ModelAction *curr);
+       void process_fence(ModelAction *curr);
        bool process_mutex(ModelAction *curr);
        void process_thread_action(ModelAction *curr);
        void read_from(ModelAction *act, ModelAction *rf);
@@ -152,7 +150,7 @@ private:
 
        /** Per-object list of actions. Maps an object (i.e., memory location)
         * to a trace of all actions performed on the object. */
-       HashTable<const void *, action_list_t *, uintptr_t, 2> condvar_waiters_map;
+       HashTable<const void *, simple_action_list_t *, uintptr_t, 2> condvar_waiters_map;
 
        /** Per-object list of actions that each thread performed. */
        HashTable<const void *, SnapVector<action_list_t> *, uintptr_t, 2> obj_thrd_map;
index 371838dcb1977c912a346a7a995e4e9cc3083425..e102d9c34431a13dea089d9437857640e2691cfd 100644 (file)
--- a/fuzzer.cc
+++ b/fuzzer.cc
@@ -16,7 +16,7 @@ Thread * Fuzzer::selectThread(int * threadlist, int numthreads) {
        return model->get_thread(curr_tid);
 }
 
-Thread * Fuzzer::selectNotify(action_list_t * waiters) {
+Thread * Fuzzer::selectNotify(simple_action_list_t * waiters) {
        int numwaiters = waiters->size();
        int random_index = random() % numwaiters;
        sllnode<ModelAction*> * it = waiters->begin();
@@ -41,5 +41,5 @@ bool Fuzzer::shouldWake(const ModelAction *sleep) {
 
 bool Fuzzer::shouldWait(const ModelAction * act)
 {
-       return random() & 1;
+       return true;
 }
index 14dff6e023ddbbf174f1a129378bee7a55b72f55..0fcfb51f67e66ff9ee439f9b48c1bd860838cbfa 100644 (file)
--- a/fuzzer.h
+++ b/fuzzer.h
@@ -12,7 +12,7 @@ public:
        virtual bool has_paused_threads() { return false; }
        virtual Thread * selectThread(int * threadlist, int numthreads);
 
-       Thread * selectNotify(action_list_t * waiters);
+       Thread * selectNotify(simple_action_list_t * waiters);
        bool shouldSleep(const ModelAction *sleep);
        bool shouldWake(const ModelAction *sleep);
        virtual bool shouldWait(const ModelAction *wait);
diff --git a/model.h b/model.h
index 62b227e4bcdce915125e9c8b7f9a877c94ee9529..634748130ce51713d014c07903f10edf4d3a8fe1 100644 (file)
--- a/model.h
+++ b/model.h
@@ -18,8 +18,6 @@
 #include "classlist.h"
 #include "snapshot-interface.h"
 
-typedef SnapList<ModelAction *> action_list_t;
-
 /** @brief Model checker execution stats */
 struct execution_stats {
        int num_total;  /**< @brief Total number of executions */
index 45a7e8bbe91f44f867e22958502491ffb64b4fa6..26fab3f6c2fff4e0ed995e4d68a8dd7733ecb5f5 100644 (file)
@@ -29,7 +29,7 @@ public:
        void notify_paused_thread(Thread * thread);
 
        Thread * selectThread(int * threadlist, int numthreads);
-       Thread * selectNotify(action_list_t * waiters);
+       Thread * selectNotify(simple_action_list_t * waiters);
        bool shouldSleep(const ModelAction * sleep);
        bool shouldWake(const ModelAction * sleep);
        bool shouldWait(const ModelAction * wait);
index d787a2d7951d1cb0589f219a2678a7a4060f7ccd..611520fc70515fa745239df32b4248d1db8068d6 100644 (file)
@@ -5,7 +5,6 @@
 #include "mymemory.h"
 typedef unsigned int uint;
 
-
 template<typename _Tp>
 class mllnode {
 public:
@@ -165,6 +164,8 @@ private:
        uint _size;
 };
 
+class actionlist;
+
 template<typename _Tp>
 class sllnode {
 public:
@@ -179,6 +180,7 @@ private:
        _Tp val;
        template<typename T>
        friend class SnapList;
+       friend class actionlist;
 };
 
 template<typename _Tp>
@@ -537,6 +539,15 @@ public:
                array[index] = item;
        }
 
+       void remove(type item) {
+               for(uint i = 0;i < _size;i++) {
+                       if (at(i) == item) {
+                               removeAt(i);
+                               return;
+                       }
+               }
+       }
+
        void removeAt(uint index) {
                for (uint i = index;(i + 1) < _size;i++) {
                        set(i, at(i + 1));
index e159697d9d54ce10c3cfb1fe204352a9e0bd7435..f0b88bb25fea3abd10f8048ac55251460b99dca5 100644 (file)
@@ -102,6 +102,7 @@ public:
        bool is_model_thread() const { return model_thread; }
 
        void * get_stack_addr() { return stack; }
+       ClockVector * get_acq_fence_cv() { return acq_fence_cv; }
 
        friend void thread_startup();
 #ifdef TLS
@@ -137,6 +138,9 @@ private:
        /** @brief The parent Thread which created this Thread */
        Thread * const parent;
 
+       /** @brief Acquire fence cv */
+       ClockVector *acq_fence_cv;
+
        /** @brief The THREAD_CREATE ModelAction which created this Thread */
        ModelAction *creation;
 
index ee0df19ca338bd20e2a3dc0e4bd85b00ab059354..a576697f561087fe2c09c607e44ef02bb0c6fa8c 100644 (file)
@@ -14,6 +14,7 @@
 #include "model.h"
 #include "execution.h"
 #include "schedule.h"
+#include "clockvector.h"
 
 #ifdef TLS
 #include <dlfcn.h>
@@ -359,6 +360,7 @@ void Thread::complete()
  */
 Thread::Thread(thread_id_t tid) :
        parent(NULL),
+       acq_fence_cv(new ClockVector()),
        creation(NULL),
        pending(NULL),
        start_routine(NULL),
@@ -384,6 +386,7 @@ Thread::Thread(thread_id_t tid) :
  */
 Thread::Thread(thread_id_t tid, thrd_t *t, void (*func)(void *), void *a, Thread *parent) :
        parent(parent),
+       acq_fence_cv(new ClockVector()),
        creation(NULL),
        pending(NULL),
        start_routine(func),
@@ -416,6 +419,7 @@ Thread::Thread(thread_id_t tid, thrd_t *t, void (*func)(void *), void *a, Thread
  */
 Thread::Thread(thread_id_t tid, thrd_t *t, void *(*func)(void *), void *a, Thread *parent) :
        parent(parent),
+       acq_fence_cv(new ClockVector()),
        creation(NULL),
        pending(NULL),
        start_routine(NULL),
@@ -444,6 +448,8 @@ Thread::~Thread()
 {
        if (!is_complete())
                complete();
+
+       delete acq_fence_cv;
 }
 
 /** @return The thread_id_t corresponding to this Thread object. */