From: Brian Demsky Date: Mon, 16 Dec 2019 20:44:19 +0000 (-0800) Subject: More code towards freeing old actions X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=98e8ab95688324f8d0c0e77392c375c89c562c08;p=c11tester.git More code towards freeing old actions --- diff --git a/action.cc b/action.cc index 4c1630f4..814c7fb1 100644 --- 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(); diff --git a/action.h b/action.h index b7e6f479..95167c43 100644 --- 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; diff --git a/execution.cc b/execution.cc index 1590d1c0..5aaabbcf 100644 --- a/execution.cc +++ b/execution.cc @@ -1697,7 +1697,7 @@ void ModelExecution::collectActions() { //Compute minimal clock vector for all live threads ClockVector *cvmin = computeMinimalCV(); SnapVector * queue = new SnapVector(); - //walk action trace... When we hit an action ,see if it is + //walk action trace... When we hit an action, see 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* 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;