- See also "A Flow-Level Wi-Fi Model for Large Scale Network Simulation"
https://hal.archives-ouvertes.fr/hal-03777726
+sthread:
+ - Implement pthread_join in MC mode.
+
Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests)
(FG: issues on Framagit; GH: issues on GitHub)
- FG!118: Wi-Fi callback mechanism
namespace simgrid::kernel::actor {
-void SimcallObserver::serialize(std::stringstream& stream) const
-{
- stream << (short)mc::Transition::Type::UNKNOWN;
-}
void RandomSimcall::serialize(std::stringstream& stream) const
{
stream << (short)mc::Transition::Type::RANDOM << ' ';
}
return true;
}
+void ConditionWaitSimcall::serialize(std::stringstream& stream) const
+{
+ THROW_UNIMPLEMENTED;
+}
+
+ActorJoinSimcall::ActorJoinSimcall(ActorImpl* actor, ActorImpl* other, double timeout)
+ : SimcallObserver(actor), other_(s4u::ActorPtr(other->get_iface())), timeout_(timeout)
+{
+}
+bool ActorJoinSimcall::is_enabled()
+{
+ return other_->get_impl()->wannadie();
+}
+void ActorJoinSimcall::serialize(std::stringstream& stream) const
+{
+ stream << (short)mc::Transition::Type::ACTOR_JOIN << ' ';
+ stream << other_->get_pid() << ' ' << static_cast<bool>(timeout_ > 0);
+}
} // namespace simgrid::kernel::actor
}
/** Serialize to the given string buffer */
- virtual void serialize(std::stringstream& stream) const;
+ virtual void serialize(std::stringstream& stream) const = 0;
- /** Some simcalls may only be observable under some conditions.
- * Most simcalls are not visible from the MC because they don't have an observer at all. */
+ /** Whether the MC should see this simcall.
+ * Simcall that don't have an observer (ie, most of them) are not visible from the MC, but if there is an observer,
+ * they are observable by default. */
virtual bool is_visible() const { return true; }
};
: ResultingSimcall(actor, false), cond_(cond), mutex_(mutex), timeout_(timeout)
{
}
+ void serialize(std::stringstream& stream) const override;
bool is_enabled() override;
- bool is_visible() const override { return false; }
activity::ConditionVariableImpl* get_cond() const { return cond_; }
activity::MutexImpl* get_mutex() const { return mutex_; }
double get_timeout() const { return timeout_; }
};
+class ActorJoinSimcall final : public SimcallObserver {
+ s4u::ActorPtr const other_; // We need a Ptr to ensure access to the actor after its end, but Ptr requires s4u
+ const double timeout_;
+
+public:
+ ActorJoinSimcall(ActorImpl* actor, ActorImpl* other, double timeout = -1.0);
+ void serialize(std::stringstream& stream) const override;
+ bool is_enabled() override;
+
+ s4u::ActorPtr get_other_actor() const { return other_; }
+ double get_timeout() const { return timeout_; }
+};
} // namespace simgrid::kernel::actor
#endif
{
auto const& actor_list = kernel::EngineImpl::get_instance()->get_actor_list();
int count = actor_list.size();
+ XBT_DEBUG("Serialize the actors to answer ACTORS_STATUS from the checker. %d actors to go.", count);
struct s_mc_message_actors_status_answer_t answer {
MessageType::ACTORS_STATUS_REPLY, count
#if SIMGRID_HAVE_MC
#include "src/mc/ModelChecker.hpp"
+#include "src/mc/transition/TransitionActorJoin.hpp"
#include "src/mc/transition/TransitionAny.hpp"
#include "src/mc/transition/TransitionComm.hpp"
#include "src/mc/transition/TransitionRandom.hpp"
case Transition::Type::SEM_WAIT:
return new SemaphoreTransition(issuer, times_considered, simcall, stream);
+ case Transition::Type::ACTOR_JOIN:
+ return new ActorJoinTransition(issuer, times_considered, stream);
+
case Transition::Type::UNKNOWN:
return new Transition(Transition::Type::UNKNOWN, issuer, times_considered);
default:
break;
}
- xbt_die("Invalid transition type %d received", type);
+ xbt_die("Invalid transition type %d received. Did you implement a new observer in the app without implementing the "
+ "corresponding transition in the checker?",
+ type);
#else
xbt_die("Deserializing transitions is only interesting in MC mode.");
#endif
COMM_RECV, COMM_SEND, COMM_TEST, COMM_WAIT, /* Alphabetical ordering of COMM_* */
MUTEX_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, /* alphabetical */
SEM_LOCK, SEM_UNLOCK, SEM_WAIT, /* alphabetical ordering of SEM transitions */
+ ACTOR_JOIN,
/* UNKNOWN must be last */ UNKNOWN);
Type type_ = Type::UNKNOWN;
--- /dev/null
+/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */
+
+/* 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 "xbt/asserts.h"
+#include <simgrid/config.h>
+#if SIMGRID_HAVE_MC
+#include "src/mc/ModelChecker.hpp"
+#include "src/mc/api/RemoteApp.hpp"
+#include "src/mc/api/State.hpp"
+#endif
+
+#include <sstream>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_actorlifecycle, mc_transition,
+ "Logging specific to MC transitions about actors' lifecycle: joining, ending");
+
+namespace simgrid::mc {
+
+ActorJoinTransition::ActorJoinTransition(aid_t issuer, int times_considered, std::stringstream& stream)
+ : Transition(Type::ACTOR_JOIN, issuer, times_considered)
+{
+ xbt_assert(stream >> target_ >> timeout_);
+ XBT_DEBUG("ActorJoinTransition target:%ld, %s ", target_, (timeout_ ? "timeout" : "no-timeout"));
+}
+std::string ActorJoinTransition::to_string(bool verbose) const
+{
+ return xbt::string_printf("ActorJoin(target %ld, %s)", target_, (timeout_ ? "timeout" : "no timeout"));
+}
+bool ActorJoinTransition::depends(const Transition* other) const
+{
+ // 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
+ return false;
+}
+
+} // namespace simgrid::mc
--- /dev/null
+/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */
+
+/* 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
+
+#include "src/kernel/actor/SimcallObserver.hpp"
+#include "src/mc/transition/Transition.hpp"
+
+#include <cstdint>
+#include <sstream>
+#include <string>
+
+namespace simgrid::mc {
+
+class ActorJoinTransition : public Transition {
+ bool timeout_;
+ aid_t target_;
+
+public:
+ ActorJoinTransition(aid_t issuer, int times_considered, std::stringstream& stream);
+ std::string to_string(bool verbose) const override;
+ bool depends(const Transition* other) const override;
+
+ bool get_timeout() const { return timeout_; }
+ /** Target ID */
+ aid_t get_target() const { return target_; }
+};
+
+} // namespace simgrid::mc
+
+#endif
void Actor::join(double timeout) const
{
- xbt_assert(not(MC_is_active() || MC_record_replay_is_active()),
- "Actor::join() is not usable in MC yet. Please report this bug.");
-
kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
const kernel::actor::ActorImpl* target = pimpl_;
- kernel::actor::simcall_blocking([issuer, target, timeout] {
- if (target->wannadie()) {
- // The joined actor is already finished, just wake up the issuer right away
- issuer->simcall_answer();
- } else {
- kernel::activity::ActivityImplPtr sync = issuer->join(target, timeout);
- sync->register_simcall(&issuer->simcall_);
- }
- });
+ kernel::actor::ActorJoinSimcall observer{issuer, get_impl(), timeout};
+
+ kernel::actor::simcall_blocking(
+ [issuer, target, timeout] {
+ if (target->wannadie()) {
+ // The joined actor is already finished, just wake up the issuer right away
+ issuer->simcall_answer();
+ } else {
+ kernel::activity::ActivityImplPtr sync = issuer->join(target, timeout);
+ sync->register_simcall(&issuer->simcall_);
+ }
+ },
+ &observer);
}
Actor* Actor::set_auto_restart(bool autorestart)
{
if (raw_pthread_join == NULL)
intercepter_init();
-
if (sthread_inside_simgrid)
return raw_pthread_join(thread, retval);
/* Launch the user's main() on an actor */
sthread_enable();
- sg4::ActorPtr main_actor = sg4::Actor::create("tid 0", lilibeth, raw_main, argc, argv, envp);
+ sg4::ActorPtr main_actor = sg4::Actor::create("main thread", lilibeth, raw_main, argc, argv, envp);
XBT_INFO("Starting the simulation.");
sg4::Engine::get_instance()->run();
src/mc/sosp/Snapshot.hpp
src/mc/transition/Transition.hpp
+ src/mc/transition/TransitionActorJoin.cpp
+ src/mc/transition/TransitionActorJoin.hpp
src/mc/transition/TransitionAny.cpp
src/mc/transition/TransitionAny.hpp
src/mc/transition/TransitionComm.cpp