From 46ba75719670be2ba9d68a6338bb6a91930d1838 Mon Sep 17 00:00:00 2001 From: Maxwell Pirtle Date: Tue, 30 May 2023 13:46:37 +0200 Subject: [PATCH] Mark transitions run by the same actor as dependent This commit adds a missing component to a number of transition classes. Transitions that are executed by the same actor are inherently dependent; but only the RandomTransition actually checked for this case! This caused ODPOR to search traces incorrectly under the assumption that transitions which were actually dependent were independent --- src/mc/transition/TransitionActorJoin.cpp | 4 ++++ src/mc/transition/TransitionAny.cpp | 7 +++++++ src/mc/transition/TransitionComm.cpp | 16 ++++++++++++++++ src/mc/transition/TransitionObjectAccess.cpp | 4 ++++ src/mc/transition/TransitionSynchro.cpp | 4 ++++ 5 files changed, 35 insertions(+) diff --git a/src/mc/transition/TransitionActorJoin.cpp b/src/mc/transition/TransitionActorJoin.cpp index 41eb681eee..463bfcbc6a 100644 --- a/src/mc/transition/TransitionActorJoin.cpp +++ b/src/mc/transition/TransitionActorJoin.cpp @@ -33,6 +33,10 @@ bool ActorJoinTransition::depends(const Transition* other) const return true; } + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + // Otherwise, joining is indep with any other transitions: // - It is only enabled once the target ends, and after this point it's enabled no matter what // - Other joins don't affect it, and it does not impact on the enabledness of any other transition diff --git a/src/mc/transition/TransitionAny.cpp b/src/mc/transition/TransitionAny.cpp index 4813a00ff8..f532369d28 100644 --- a/src/mc/transition/TransitionAny.cpp +++ b/src/mc/transition/TransitionAny.cpp @@ -35,6 +35,10 @@ std::string TestAnyTransition::to_string(bool verbose) const } bool TestAnyTransition::depends(const Transition* other) const { + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + return transitions_[times_considered_]->depends(other); } WaitAnyTransition::WaitAnyTransition(aid_t issuer, int times_considered, std::stringstream& stream) @@ -57,6 +61,9 @@ std::string WaitAnyTransition::to_string(bool verbose) const } bool WaitAnyTransition::depends(const Transition* other) const { + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; return transitions_[times_considered_]->depends(other); } diff --git a/src/mc/transition/TransitionComm.cpp b/src/mc/transition/TransitionComm.cpp index b374f193dc..029548dd63 100644 --- a/src/mc/transition/TransitionComm.cpp +++ b/src/mc/transition/TransitionComm.cpp @@ -42,6 +42,10 @@ bool CommWaitTransition::depends(const Transition* other) const if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (const auto* wait = dynamic_cast(other)) { if (timeout_ || wait->timeout_) return true; // Timeouts are not considered by the independence theorem, thus assumed dependent @@ -80,6 +84,10 @@ bool CommTestTransition::depends(const Transition* other) const if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (dynamic_cast(other) != nullptr) return false; // Test & Test are independent @@ -112,6 +120,10 @@ bool CommRecvTransition::depends(const Transition* other) const if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (const auto* recv = dynamic_cast(other)) return mbox_ == recv->mbox_; @@ -164,6 +176,10 @@ bool CommSendTransition::depends(const Transition* other) const if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (const auto* other_isend = dynamic_cast(other)) return mbox_ == other_isend->mbox_; diff --git a/src/mc/transition/TransitionObjectAccess.cpp b/src/mc/transition/TransitionObjectAccess.cpp index 12f315ec9f..0936359886 100644 --- a/src/mc/transition/TransitionObjectAccess.cpp +++ b/src/mc/transition/TransitionObjectAccess.cpp @@ -37,6 +37,10 @@ bool ObjectAccessTransition::depends(const Transition* o) const if (o->type_ < type_) return o->depends(this); + // Actions executed by the same actor are always dependent + if (o->aid_ == aid_) + return true; + if (const auto* other = dynamic_cast(o)) return objaddr_ == other->objaddr_; // dependent only if it's an access to the same object return false; diff --git a/src/mc/transition/TransitionSynchro.cpp b/src/mc/transition/TransitionSynchro.cpp index a93e27b5cf..dbd39a5de7 100644 --- a/src/mc/transition/TransitionSynchro.cpp +++ b/src/mc/transition/TransitionSynchro.cpp @@ -63,6 +63,10 @@ bool MutexTransition::depends(const Transition* o) const if (o->type_ < type_) return o->depends(this); + // Actions executed by the same actor are always dependent + if (o->aid_ == aid_) + return true; + // type_ <= other->type_ in MUTEX_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, if (auto* other = dynamic_cast(o)) { -- 2.20.1