From d0a8cb4f92bd372f091430671bd30f4422674d76 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Thu, 2 Nov 2023 01:06:57 +0100 Subject: [PATCH] MC: add an observer to sleep simcalls --- MANIFEST.in | 4 +-- src/kernel/actor/SimcallObserver.cpp | 9 +++++++ src/kernel/actor/SimcallObserver.hpp | 8 ++++++ .../explo/odpor/ReversibleRaceCalculator.hpp | 2 +- src/mc/remote/AppSide.cpp | 3 +++ src/mc/transition/Transition.cpp | 4 ++- src/mc/transition/Transition.hpp | 25 +++++++++++++------ ...itionActorJoin.cpp => TransitionActor.cpp} | 17 ++++++++++++- ...itionActorJoin.hpp => TransitionActor.hpp} | 14 +++++++++-- src/s4u/s4u_Actor.cpp | 22 +++++++++------- tools/cmake/DefinePackages.cmake | 4 +-- 11 files changed, 86 insertions(+), 26 deletions(-) rename src/mc/transition/{TransitionActorJoin.cpp => TransitionActor.cpp} (74%) rename src/mc/transition/{TransitionActorJoin.hpp => TransitionActor.hpp} (69%) diff --git a/MANIFEST.in b/MANIFEST.in index 3f03f8bb5a..b6d6b978bb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2320,8 +2320,8 @@ include src/mc/sosp/Snapshot.hpp include src/mc/sosp/Snapshot_test.cpp include src/mc/transition/Transition.cpp include src/mc/transition/Transition.hpp -include src/mc/transition/TransitionActorJoin.cpp -include src/mc/transition/TransitionActorJoin.hpp +include src/mc/transition/TransitionActor.cpp +include src/mc/transition/TransitionActor.hpp include src/mc/transition/TransitionAny.cpp include src/mc/transition/TransitionAny.hpp include src/mc/transition/TransitionComm.cpp diff --git a/src/kernel/actor/SimcallObserver.cpp b/src/kernel/actor/SimcallObserver.cpp index 2d2cf8827e..3bd6ab97f1 100644 --- a/src/kernel/actor/SimcallObserver.cpp +++ b/src/kernel/actor/SimcallObserver.cpp @@ -73,6 +73,15 @@ std::string ActorJoinSimcall::to_string() const { return "ActorJoin(pid:" + std::to_string(other_->get_pid()) + ")"; } +void ActorSleepSimcall::serialize(std::stringstream& stream) const +{ + stream << (short)mc::Transition::Type::ACTOR_SLEEP; +} + +std::string ActorSleepSimcall::to_string() const +{ + return "ActorSleep()"; +} void ObjectAccessSimcallObserver::serialize(std::stringstream& stream) const { diff --git a/src/kernel/actor/SimcallObserver.hpp b/src/kernel/actor/SimcallObserver.hpp index 4cb7f22c3c..d43ac00ead 100644 --- a/src/kernel/actor/SimcallObserver.hpp +++ b/src/kernel/actor/SimcallObserver.hpp @@ -127,6 +127,14 @@ public: double get_timeout() const { return timeout_; } }; +class ActorSleepSimcall final : public SimcallObserver { + +public: + ActorSleepSimcall(ActorImpl* actor) : SimcallObserver(actor) {} + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; +}; + class ObjectAccessSimcallObserver final : public SimcallObserver { ObjectAccessSimcallItem* const object_; diff --git a/src/mc/explo/odpor/ReversibleRaceCalculator.hpp b/src/mc/explo/odpor/ReversibleRaceCalculator.hpp index 283b7c9dcc..88c6839bb0 100644 --- a/src/mc/explo/odpor/ReversibleRaceCalculator.hpp +++ b/src/mc/explo/odpor/ReversibleRaceCalculator.hpp @@ -9,7 +9,7 @@ #include "src/mc/explo/odpor/Execution.hpp" #include "src/mc/explo/odpor/odpor_forward.hpp" #include "src/mc/transition/Transition.hpp" -#include "src/mc/transition/TransitionActorJoin.hpp" +#include "src/mc/transition/TransitionActor.hpp" #include "src/mc/transition/TransitionAny.hpp" #include "src/mc/transition/TransitionComm.hpp" #include "src/mc/transition/TransitionObjectAccess.hpp" diff --git a/src/mc/remote/AppSide.cpp b/src/mc/remote/AppSide.cpp index 5d00307aa9..a74b1260d9 100644 --- a/src/mc/remote/AppSide.cpp +++ b/src/mc/remote/AppSide.cpp @@ -225,6 +225,9 @@ void AppSide::handle_actors_status() const std::vector status; for (auto const& [aid, actor] : actor_list) { + xbt_assert(actor); + xbt_assert(actor->simcall_.observer_, "simcall %s in actor %s has no observer.", actor->simcall_.get_cname(), + actor->get_cname()); s_mc_message_actors_status_one_t one = {}; one.type = MessageType::ACTORS_STATUS_REPLY_TRANSITION; one.aid = aid; diff --git a/src/mc/transition/Transition.cpp b/src/mc/transition/Transition.cpp index 84ad991fd5..fc3a5e2309 100644 --- a/src/mc/transition/Transition.cpp +++ b/src/mc/transition/Transition.cpp @@ -11,7 +11,7 @@ #if SIMGRID_HAVE_MC #include "src/mc/explo/Exploration.hpp" -#include "src/mc/transition/TransitionActorJoin.hpp" +#include "src/mc/transition/TransitionActor.hpp" #include "src/mc/transition/TransitionAny.hpp" #include "src/mc/transition/TransitionComm.hpp" #include "src/mc/transition/TransitionObjectAccess.hpp" @@ -95,6 +95,8 @@ Transition* deserialize_transition(aid_t issuer, int times_considered, std::stri case Transition::Type::ACTOR_JOIN: return new ActorJoinTransition(issuer, times_considered, stream); + case Transition::Type::ACTOR_SLEEP: + return new ActorSleepTransition(issuer, times_considered, stream); case Transition::Type::OBJECT_ACCESS: return new ObjectAccessTransition(issuer, times_considered, stream); diff --git a/src/mc/transition/Transition.hpp b/src/mc/transition/Transition.hpp index 4bdf7d262b..9a840246c4 100644 --- a/src/mc/transition/Transition.hpp +++ b/src/mc/transition/Transition.hpp @@ -31,14 +31,23 @@ class Transition { public: /* Ordering is important here. depends() implementations only consider subsequent types in this ordering */ - XBT_DECLARE_ENUM_CLASS(Type, RANDOM, ACTOR_JOIN, /* First because indep with anybody including themselves */ - OBJECT_ACCESS, /* high priority because indep with almost everybody */ - TESTANY, WAITANY, /* high priority because they can rewrite themselves to *_WAIT */ - BARRIER_ASYNC_LOCK, BARRIER_WAIT, /* BARRIER transitions sorted alphabetically */ - COMM_ASYNC_RECV, COMM_ASYNC_SEND, COMM_TEST, COMM_WAIT, /* Alphabetical ordering of COMM_* */ - MUTEX_ASYNC_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, /* alphabetical */ - SEM_ASYNC_LOCK, SEM_UNLOCK, SEM_WAIT, /* alphabetical ordering of SEM transitions */ - /* UNKNOWN must be last */ UNKNOWN); + XBT_DECLARE_ENUM_CLASS(Type, + /* First because indep with anybody including themselves */ + RANDOM, ACTOR_JOIN, ACTOR_SLEEP, + /* high priority because indep with almost everybody */ + OBJECT_ACCESS, + /* high priority because they can rewrite themselves to *_WAIT */ + TESTANY, WAITANY, + /* BARRIER transitions sorted alphabetically */ + BARRIER_ASYNC_LOCK, BARRIER_WAIT, + /* Alphabetical ordering of COMM_* */ + COMM_ASYNC_RECV, COMM_ASYNC_SEND, COMM_TEST, COMM_WAIT, + /* alphabetical */ + MUTEX_ASYNC_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, + /* alphabetical ordering of SEM transitions */ + SEM_ASYNC_LOCK, SEM_UNLOCK, SEM_WAIT, + /* UNKNOWN must be last */ + UNKNOWN); Type type_ = Type::UNKNOWN; aid_t aid_ = 0; diff --git a/src/mc/transition/TransitionActorJoin.cpp b/src/mc/transition/TransitionActor.cpp similarity index 74% rename from src/mc/transition/TransitionActorJoin.cpp rename to src/mc/transition/TransitionActor.cpp index 463bfcbc6a..c0d04d1162 100644 --- a/src/mc/transition/TransitionActorJoin.cpp +++ b/src/mc/transition/TransitionActor.cpp @@ -3,7 +3,7 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/mc/transition/TransitionActorJoin.hpp" +#include "src/mc/transition/TransitionActor.hpp" #include "simgrid/config.h" #include "xbt/asserts.h" #include "xbt/string.hpp" @@ -43,4 +43,19 @@ bool ActorJoinTransition::depends(const Transition* other) const return false; } +ActorSleepTransition::ActorSleepTransition(aid_t issuer, int times_considered, std::stringstream& stream) + : Transition(Type::ACTOR_SLEEP, issuer, times_considered) +{ + XBT_DEBUG("ActorSleepTransition()"); +} +std::string ActorSleepTransition::to_string(bool verbose) const +{ + return xbt::string_printf("ActorSleep()"); +} +bool ActorSleepTransition::depends(const Transition* other) const +{ + // Sleeping is indep with any other transitions: always enabled, not impacted by any transition + return false; +} + } // namespace simgrid::mc diff --git a/src/mc/transition/TransitionActorJoin.hpp b/src/mc/transition/TransitionActor.hpp similarity index 69% rename from src/mc/transition/TransitionActorJoin.hpp rename to src/mc/transition/TransitionActor.hpp index 78bc7659e5..f86df61fb9 100644 --- a/src/mc/transition/TransitionActorJoin.hpp +++ b/src/mc/transition/TransitionActor.hpp @@ -3,8 +3,8 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SIMGRID_MC_TRANSITION_ACTOR_JOIN_HPP -#define SIMGRID_MC_TRANSITION_ACTOR_JOIN_HPP +#ifndef SIMGRID_MC_TRANSITION_ACTOR_HPP +#define SIMGRID_MC_TRANSITION_ACTOR_HPP #include "src/kernel/actor/SimcallObserver.hpp" #include "src/mc/transition/Transition.hpp" @@ -29,6 +29,16 @@ public: aid_t get_target() const { return target_; } }; +class ActorSleepTransition : public Transition { + bool timeout_; + aid_t target_; + +public: + ActorSleepTransition(aid_t issuer, int times_considered, std::stringstream& stream); + std::string to_string(bool verbose) const override; + bool depends(const Transition* other) const override; +}; + } // namespace simgrid::mc #endif diff --git a/src/s4u/s4u_Actor.cpp b/src/s4u/s4u_Actor.cpp index e60f73d5fa..268576eba3 100644 --- a/src/s4u/s4u_Actor.cpp +++ b/src/s4u/s4u_Actor.cpp @@ -328,18 +328,22 @@ void sleep_for(double duration) } kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); + kernel::actor::ActorSleepSimcall observer(issuer); + Actor::on_sleep(*issuer->get_ciface()); issuer->get_ciface()->on_this_sleep(*issuer->get_ciface()); - kernel::actor::simcall_blocking([issuer, duration]() { - if (MC_is_active() || MC_record_replay_is_active()) { - MC_process_clock_add(issuer, duration); - issuer->simcall_answer(); - return; - } - kernel::activity::ActivityImplPtr sync = issuer->sleep(duration); - sync->register_simcall(&issuer->simcall_); - }); + kernel::actor::simcall_blocking( + [issuer, duration]() { + if (MC_is_active() || MC_record_replay_is_active()) { + MC_process_clock_add(issuer, duration); + issuer->simcall_answer(); + return; + } + kernel::activity::ActivityImplPtr sync = issuer->sleep(duration); + sync->register_simcall(&issuer->simcall_); + }, + &observer); Actor::on_wake_up(*issuer->get_ciface()); issuer->get_ciface()->on_this_wake_up(*issuer->get_ciface()); diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 133bbd920d..f0b0d87b43 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -564,8 +564,8 @@ set(MC_SRC_STATELESS src/mc/remote/mc_protocol.h src/mc/transition/Transition.hpp - src/mc/transition/TransitionActorJoin.cpp - src/mc/transition/TransitionActorJoin.hpp + src/mc/transition/TransitionActor.cpp + src/mc/transition/TransitionActor.hpp src/mc/transition/TransitionAny.cpp src/mc/transition/TransitionAny.hpp src/mc/transition/TransitionComm.cpp -- 2.20.1