More code towards freeing old actions
authorBrian Demsky <bdemsky@uci.edu>
Mon, 16 Dec 2019 20:44:19 +0000 (12:44 -0800)
committerBrian Demsky <bdemsky@uci.edu>
Mon, 16 Dec 2019 20:44:19 +0000 (12:44 -0800)
action.cc
action.h
execution.cc

index 4c1630f48d984ded88dc2b3015525a587a955420..814c7fb1be0f05df2e42725ef6fb7cd86c641b1c 100644 (file)
--- a/action.cc
+++ b/action.cc
@@ -305,6 +305,11 @@ bool ModelAction::is_write() const
        return type == ATOMIC_WRITE || type == ATOMIC_RMW || type == ATOMIC_INIT || type == NONATOMIC_WRITE;
 }
 
+bool ModelAction::is_free() const
+{
+       return type == READY_FREE;
+}
+
 bool ModelAction::could_be_write() const
 {
        return is_write() || is_rmwr();
index b7e6f4797c7b8094ccee993ed0b58547ed772f9e..95167c437a0ff91a6f05405ea6c810ad8d403f81 100644 (file)
--- a/action.h
+++ b/action.h
@@ -143,6 +143,7 @@ public:
        bool is_atomic_var() const;
        bool is_read() const;
        bool is_write() const;
+       bool is_free() const;
        bool is_yield() const;
        bool could_be_write() const;
        bool is_rmwr() const;
index 1590d1c03f59131ad27c72668881d35d1edc9fc2..5aaabbcf00060a1ffe55cb77ad11f049037d7648 100644 (file)
@@ -1697,7 +1697,7 @@ void ModelExecution::collectActions() {
        //Compute minimal clock vector for all live threads
        ClockVector *cvmin = computeMinimalCV();
        SnapVector<CycleNode *> * queue = new SnapVector<CycleNode *>();
-       //walk action trace...  When we hit an action ,see if it is
+       //walk action trace...  When we hit an actionsee if it is
        //invisible (e.g., earlier than the first before the minimum
        //clock for the thread...  if so erase it and all previous
        //actions in cyclegraph
@@ -1731,6 +1731,52 @@ void ModelExecution::collectActions() {
                        }
                }
        }
+       for (sllnode<ModelAction*>* it = action_trace.end();it != NULL;it=it->getPrev()) {
+               ModelAction *act = it->getVal();
+               if (act->is_free()) {
+                       removeAction(act);
+                       delete act;
+               } else if (act->is_read()) {
+                       if (act->get_reads_from()->is_free()) {
+                               removeAction(act);
+                               delete act;
+                       } else {
+                               const ModelAction *rel_fence =act->get_last_fence_release();
+                               if (rel_fence != NULL) {
+                                       modelclock_t relfenceseq = rel_fence->get_seq_number();
+                                       thread_id_t relfence_tid = rel_fence->get_tid();
+                                       modelclock_t tid_clock = cvmin->getClock(relfence_tid);
+                                       //Remove references to irrelevant release fences
+                                       if (relfenceseq <= tid_clock)
+                                               act->set_last_fence_release(NULL);
+                               }
+                       }
+               } else if (act->is_fence()) {
+                       //Note that acquire fences can always be safely
+                       //removed, but could incur extra overheads in
+                       //traversals.  Removing them before the cvmin seems
+                       //like a good compromise.
+
+                       //Release fences before the cvmin don't do anything
+                       //because everyone has already synchronized.
+
+                       //Sequentially fences before cvmin are redundant
+                       //because happens-before will enforce same
+                       //orderings.
+
+                       modelclock_t actseq = act->get_seq_number();
+                       thread_id_t act_tid = act->get_tid();
+                       modelclock_t tid_clock = cvmin->getClock(act_tid);
+                       if (actseq <= tid_clock) {
+                               removeAction(act);
+                               delete act;
+                       }
+               } else {
+                       //need to deal with lock, annotation, wait, notify, thread create, start, join, yield, finish
+                       //lock, notify thread create, thread finish, yield, finish are dead as soon as they are in the trace
+                       //need to keep most recent unlock/wait for each lock
+               }
+       }
 
        delete cvmin;
        delete queue;