if: matrix.config.os == 'windows'
run: |
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
- scoop install gcc --global
+ scoop -RunAsAdmin install gcc --global
If ((Test-Path "C:\hostedtoolcache\windows\Boost") -eq $False){
# Use the boost-1.72.0-win32-msvc14.1-x86_64.tar.gz for Windows 2016
$url = "https://github.com/actions/boost-versions/releases/download/1.72.0-20200608.4/boost-1.72.0-win32-msvc14.2-x86_64.tar.gz"
static SemaphorePtr create(unsigned int initial_capacity);
void acquire();
+ /** Returns true if there was a timeout */
bool acquire_timeout(double timeout);
void release();
int get_capacity() const;
#include "JavaContext.hpp"
#include "jxbt_utilities.hpp"
#include "simgrid/Exception.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
#include <functional>
#include <utility>
return this->new_context<JavaContext>(std::move(code), actor);
}
-void JavaContextFactory::run_all()
+void JavaContextFactory::run_all(std::vector<actor::ActorImpl*> const& actors)
{
- SerialThreadContext::run_all();
+ SerialThreadContext::run_all(actors);
}
JavaContext::JavaContext(std::function<void()>&& code, smx_actor_t actor)
this->jenv_ = env;
}
-void JavaContext::stop_hook()
+void JavaContext::stop()
{
- JNIEnv* env = this->jenv_;
- env->DeleteGlobalRef(this->jprocess_);
- jint error = __java_vm->DetachCurrentThread();
- if (error != JNI_OK) {
- /* This is probably a Java thread, ie an actor not created from the XML (and thus from the C++),
- * but from Java with something like new Process().start().
- *
- * We should not even try to detach such threads. Instead, we throw a Java exception that will raise up
- * until run_jprocess(), IIUC.
- */
- jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed");
- XBT_DEBUG("Cannot detach the current thread");
- }
+ this->get_actor()->cleanup_from_self();
+
+ /* Unregister the thread from the JVM */
+ JNIEnv* env = this->jenv_;
+ env->DeleteGlobalRef(this->jprocess_);
+ jint error = __java_vm->DetachCurrentThread();
+ if (error != JNI_OK) {
+ /* This is probably a Java thread, ie an actor not created from the XML (and thus from the C++),
+ * but from Java with something like new Process().start().
+ *
+ * We should not even try to detach such threads. Instead, we throw a Java exception that will raise up
+ * until run_jprocess(), IIUC.
+ */
+ jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed");
+ XBT_DEBUG("Cannot detach the current thread");
+ }
+
+ throw ForcefulKillException(); // clean RAII variables with the dedicated exception
}
}}} // namespace simgrid::kernel::context
JavaContext(std::function<void()>&& code, actor::ActorImpl* actor);
void start_hook() override;
- void stop_hook() override;
+ void stop() override;
};
class JavaContextFactory : public ContextFactory {
JavaContextFactory();
~JavaContextFactory() override;
Context* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
- void run_all() override;
+ void run_all(std::vector<actor::ActorImpl*> const& actors) override;
};
XBT_PRIVATE ContextFactory* java_factory();
#include "simgrid/Exception.hpp"
#include "simgrid/s4u/Host.hpp"
-#include "src/kernel/context/Context.hpp"
#include "jmsg.hpp"
#include "jmsg_host.h"
#include "jxbt_utilities.hpp"
#include "simgrid/Exception.hpp"
#include "simgrid/plugins/live_migration.h"
-#include "src/kernel/context/Context.hpp"
#include "src/kernel/resource/VirtualMachineImpl.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java);
#include "simgrid/kernel/ProfileBuilder.hpp"
#include "simgrid/kernel/routing/NetPoint.hpp"
-#include "src/kernel/context/Context.hpp"
#include <simgrid/Exception.hpp>
#include <simgrid/s4u/Actor.hpp>
#include <simgrid/s4u/Comm.hpp>
*/
void EngineImpl::run_all_actors()
{
- instance_->get_context_factory()->run_all();
+ instance_->get_context_factory()->run_all(actors_to_run_);
for (auto const& actor : actors_to_run_)
- if (actor->context_->to_be_freed())
+ if (actor->to_be_freed())
actor->cleanup_from_kernel();
actors_to_run_.swap(actors_that_ran_);
#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/activity/MailboxImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
-#include "src/kernel/context/Context.hpp"
#include "src/kernel/resource/CpuImpl.hpp"
#include "src/kernel/resource/LinkImpl.hpp"
#include "src/kernel/resource/StandardLinkImpl.hpp"
case State::SRC_HOST_FAILURE:
if (issuer == src_actor_)
- issuer->context_->set_wannadie();
+ issuer->set_wannadie();
else {
set_state(State::FAILED);
issuer->exception_ = std::make_exception_ptr(NetworkFailureException(XBT_THROW_POINT, "Remote peer failed"));
case State::DST_HOST_FAILURE:
if (issuer == dst_actor_)
- issuer->context_->set_wannadie();
+ issuer->set_wannadie();
else {
set_state(State::FAILED);
issuer->exception_ = std::make_exception_ptr(NetworkFailureException(XBT_THROW_POINT, "Remote peer failed"));
/* Check out for errors */
if (not simcall->issuer_->get_host()->is_on()) {
- simcall->issuer_->context_->set_wannadie();
+ simcall->issuer_->set_wannadie();
} else {
// Do not answer to dying actors
- if (not simcall->issuer_->context_->wannadie()) {
+ if (not simcall->issuer_->wannadie()) {
set_exception(simcall->issuer_);
simcall->issuer_->simcall_answer();
}
if (issuer->get_host()->is_on())
issuer->exception_ = std::make_exception_ptr(HostFailureException(XBT_THROW_POINT, "Host failed"));
else /* else, the actor will be killed with no possibility to survive */
- issuer->context_->set_wannadie();
+ issuer->set_wannadie();
break;
case State::CANCELED:
if (simcall->issuer_->get_host()->is_on())
simcall->issuer_->simcall_answer();
else
- simcall->issuer_->context_->set_wannadie();
+ simcall->issuer_->set_wannadie();
}
}
#include "src/kernel/activity/IoImpl.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
-#include "src/kernel/context/Context.hpp"
#include "src/kernel/resource/CpuImpl.hpp"
#include "src/kernel/resource/DiskImpl.hpp"
#include "src/mc/mc_replay.hpp"
{
switch (get_state()) {
case State::FAILED:
- issuer->context_->set_wannadie();
+ issuer->set_wannadie();
static_cast<s4u::Io*>(get_iface())->complete(s4u::Activity::State::FAILED);
issuer->exception_ = std::make_exception_ptr(StorageFailureException(XBT_THROW_POINT, "Storage failed"));
break;
void MailboxImpl::set_receiver(s4u::ActorPtr actor)
{
if (this->permanent_receiver_) {
- std::vector<MailboxImpl*>& mboxes = this->permanent_receiver_->mailboxes;
+ std::vector<MailboxImpl*>& mboxes = this->permanent_receiver_->mailboxes_;
mboxes.erase(std::remove(mboxes.begin(), mboxes.end(), this), mboxes.end());
}
#include "src/kernel/activity/Synchro.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
-#include "src/kernel/context/Context.hpp"
#include "src/kernel/resource/CpuImpl.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_synchro, kernel,
void SynchroImpl::set_exception(actor::ActorImpl* issuer)
{
if (get_state() == State::FAILED) {
- issuer->context_->set_wannadie();
+ issuer->set_wannadie();
issuer->exception_ = std::make_exception_ptr(HostFailureException(XBT_THROW_POINT, "Host failed"));
} else {
xbt_assert(get_state() == State::SRC_TIMEOUT, "Internal error in SynchroImpl::finish() unexpected synchro state %s",
namespace kernel {
namespace actor {
+/*------------------------- [ ActorIDTrait ] -------------------------*/
static unsigned long maxpid = 0;
unsigned long get_maxpid()
{
{
return &maxpid;
}
-ActorImpl* ActorImpl::by_pid(aid_t pid)
-{
- return EngineImpl::get_instance()->get_actor_by_pid(pid);
-}
+ActorIDTrait::ActorIDTrait(std::string name, aid_t ppid) : name_(std::move(name)), pid_(maxpid++), ppid_(ppid) {}
ActorImpl* ActorImpl::self()
{
return (self_context != nullptr) ? self_context->get_actor() : nullptr;
}
-ActorImpl::ActorImpl(xbt::string name, s4u::Host* host) : host_(host), name_(std::move(name)), piface_(this)
+ActorImpl::ActorImpl(xbt::string name, s4u::Host* host, aid_t ppid)
+ : ActorIDTrait(std::move(name), ppid), host_(host), piface_(this)
{
- pid_ = maxpid++;
simcall_.issuer_ = this;
stacksize_ = context::stack_size;
}
throw HostFailureException(XBT_THROW_POINT, "Cannot attach actor on failed host.");
}
- auto* actor = new ActorImpl(xbt::string(name), host);
+ auto* actor = new ActorImpl(xbt::string(name), host, /*ppid*/ -1);
/* Actor data */
actor->piface_.set_data(data);
actor->code_ = nullptr;
get_cname());
auto* engine = EngineImpl::get_instance();
- engine->remove_actor(pid_);
+ engine->remove_actor(get_pid());
if (host_ && host_actor_list_hook.is_linked())
host_->get_impl()->remove_actor(this);
if (not kernel_destroy_list_hook.is_linked())
undaemonize();
- while (not mailboxes.empty())
- mailboxes.back()->set_receiver(nullptr);
+ while (not mailboxes_.empty())
+ mailboxes_.back()->set_receiver(nullptr);
}
/* Do all the cleanups from the actor context. Warning, the simcall mechanism was not reignited so doing simcalls in
void ActorImpl::cleanup_from_self()
{
xbt_assert(not ActorImpl::is_maestro(), "Cleanup_from_self called from maestro on '%s'", get_cname());
- context_->set_to_be_freed();
+ set_to_be_freed();
if (on_exit) {
// Execute the termination callbacks
- bool failed = context_->wannadie();
+ bool failed = wannadie();
for (auto exit_fun = on_exit->crbegin(); exit_fun != on_exit->crend(); ++exit_fun)
(*exit_fun)(failed);
on_exit.reset();
simcall_.timeout_cb_ = nullptr;
}
- context_->set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
+ set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
actor::simcall_answered([this] { s4u::Actor::on_termination(*get_ciface()); });
- context_->set_wannadie();
+ set_wannadie();
}
void ActorImpl::exit()
{
- context_->set_wannadie();
+ set_wannadie();
suspended_ = false;
exception_ = nullptr;
- /* destroy the blocking synchro if any */
if (waiting_synchro_ != nullptr) {
+ /* Take an extra reference on the activity object that may be unref by Comm::finish() or friends */
+ activity::ActivityImplPtr activity = waiting_synchro_;
+ activity->cancel();
+ activity->set_state(activity::State::FAILED);
+ activity->post();
+
activities_.remove(waiting_synchro_);
- waiting_synchro_->cancel();
- waiting_synchro_->set_state(activity::State::FAILED);
- waiting_synchro_->post();
waiting_synchro_ = nullptr;
}
for (auto const& activity : activities_)
activity->cancel();
activities_.clear();
- while (not mailboxes.empty())
- mailboxes.back()->set_receiver(nullptr);
-
// Forcefully kill the actor if its host is turned off. Not a HostFailureException because you should not survive that
this->throw_exception(std::make_exception_ptr(ForcefulKillException(host_->is_on() ? "exited" : "host failed")));
}
void ActorImpl::kill(ActorImpl* actor) const
{
xbt_assert(not actor->is_maestro(), "Killing maestro is a rather bad idea.");
- if (actor->context_->wannadie()) {
+ if (actor->wannadie()) {
XBT_DEBUG("Ignoring request to kill actor %s@%s that is already dead", actor->get_cname(),
actor->host_->get_cname());
return;
/* Ok, maestro returned control to us */
XBT_DEBUG("Control returned to me: '%s'", get_cname());
- if (context_->wannadie()) {
+ if (wannadie()) {
XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname());
context_->stop();
THROW_IMPOSSIBLE;
}
}
#if HAVE_SMPI
- if (not context_->wannadie())
+ if (not wannadie())
smpi_switch_data_segment(get_iface());
#endif
}
{
XBT_IN("actor = %p", this);
- if (context_->wannadie()) {
+ if (wannadie()) {
XBT_VERB("Ignoring request to resume an actor that is currently dying.");
return;
}
activity::ActivityImplPtr ActorImpl::join(const ActorImpl* actor, double timeout)
{
activity::ActivityImplPtr sleep = this->sleep(timeout);
- actor->on_exit->emplace_back([sleep](bool) {
+ if (actor->wannadie() || actor->to_be_freed()) {
if (sleep->surf_action_)
sleep->surf_action_->finish(resource::Action::State::FINISHED);
- });
+ } else {
+ actor->on_exit->emplace_back([sleep](bool) {
+ if (sleep->surf_action_)
+ sleep->surf_action_->finish(resource::Action::State::FINISHED);
+ });
+ }
return sleep;
}
ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host) const
{
- auto* actor = new ActorImpl(xbt::string(name), host);
- actor->set_ppid(this->pid_);
+ auto* actor = new ActorImpl(xbt::string(name), host, get_pid());
intrusive_ptr_add_ref(actor);
/* The on_creation() signal must be delayed until there, where the pid and everything is set */
auto* engine = EngineImpl::get_instance();
if (not host_->is_on()) {
- XBT_WARN("Cannot launch actor '%s' on failed host '%s'", name_.c_str(), host_->get_cname());
+ XBT_WARN("Cannot launch actor '%s' on failed host '%s'", get_cname(), host_->get_cname());
intrusive_ptr_release(this);
throw HostFailureException(XBT_THROW_POINT, "Cannot start actor on failed host.");
}
/* Add the actor to its host's actor list */
host_->get_impl()->add_actor(this);
- engine->add_actor(pid_, this);
+ engine->add_actor(get_pid(), this);
/* Now insert it in the global actor list and in the actor to run list */
engine->add_actor_to_run_list_no_check(this);
actor->daemonize();
return actor;
}
+void ActorImpl::set_wannadie(bool value)
+{
+ XBT_DEBUG("Actor %s gonna die.", get_cname());
+ iwannadie_ = value;
+}
void create_maestro(const std::function<void()>& code)
{
auto* engine = EngineImpl::get_instance();
/* Create maestro actor and initialize it */
- auto* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr);
+ auto* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr, /*ppid*/ -1);
if (not code) {
maestro->context_.reset(engine->get_context_factory()->create_context(ActorCode(), maestro));
namespace actor {
class ProcessArg;
+/*------------------------- [ ActorIDTrait ] -------------------------*/
+class XBT_PUBLIC ActorIDTrait {
+ xbt::string name_;
+ aid_t pid_ = 0;
+ aid_t ppid_ = -1;
+
+public:
+ explicit ActorIDTrait(std::string name, aid_t ppid);
+ const xbt::string& get_name() const { return name_; }
+ const char* get_cname() const { return name_.c_str(); }
+ aid_t get_pid() const { return pid_; }
+ aid_t get_ppid() const { return ppid_; }
+};
+XBT_PUBLIC unsigned long get_maxpid();
+XBT_PUBLIC unsigned long* get_maxpid_addr(); // In MC mode, the application sends this pointers to the MC
+
+/*------------------------- [ ActorRestartingTrait ] -------------------------*/
class XBT_PUBLIC ActorRestartingTrait {
bool auto_restart_ = false;
int restart_count_ = 0;
int get_restart_count() const { return restart_count_; }
};
-class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder, public ActorRestartingTrait {
+/*------------------------- [ ActorImpl ] -------------------------*/
+class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder, public ActorIDTrait, public ActorRestartingTrait {
s4u::Host* host_ = nullptr; /* the host on which the actor is running */
- xbt::string name_;
- aid_t pid_ = 0;
- aid_t ppid_ = -1;
bool daemon_ = false; /* Daemon actors are automatically killed when the last non-daemon leaves */
unsigned stacksize_; // set to default value in constructor
+ bool iwannadie_ = false; // True if we need to do some cleanups in actor mode.
+ bool to_be_freed_ = false; // True if cleanups in actor mode done, but cleanups in kernel mode pending
- std::vector<activity::MailboxImpl*> mailboxes;
+ std::vector<activity::MailboxImpl*> mailboxes_;
friend activity::MailboxImpl;
public:
- ActorImpl(xbt::string name, s4u::Host* host);
+ ActorImpl(xbt::string name, s4u::Host* host, aid_t ppid);
ActorImpl(const ActorImpl&) = delete;
ActorImpl& operator=(const ActorImpl&) = delete;
~ActorImpl();
- /** Retrieve the actor implementation from its PID (or nullptr if non-existent) */
- static ActorImpl* by_pid(aid_t pid);
-
static ActorImpl* self();
double get_kill_time() const;
void set_kill_time(double kill_time);
boost::intrusive::list_member_hook<> kernel_destroy_list_hook; /* EngineImpl actors_to_destroy */
boost::intrusive::list_member_hook<> smx_synchro_hook; /* {mutex,cond,sem}->sleeping */
- const xbt::string& get_name() const { return name_; }
- const char* get_cname() const { return name_.c_str(); }
+
+ // Life-cycle
+ bool wannadie() const { return iwannadie_; }
+ void set_wannadie(bool value = true);
+ bool to_be_freed() const { return to_be_freed_; }
+ void set_to_be_freed() { to_be_freed_ = true; }
// Accessors to private fields
s4u::Host* get_host() const { return host_; }
void set_host(s4u::Host* dest);
- aid_t get_pid() const { return pid_; }
- aid_t get_ppid() const { return ppid_; }
- void set_ppid(aid_t ppid) { ppid_ = ppid; }
- bool is_daemon() const { return daemon_; } /** Whether this actor has been daemonized */
bool is_maestro() const; /** Whether this actor is actually maestro (cheap call but may segfault before actor creation
/ after terminaison) */
void set_stacksize(unsigned stacksize) { stacksize_ = stacksize; }
unsigned get_stacksize() const { return stacksize_; }
+ // Daemonize
+ bool is_daemon() const { return daemon_; } /** Whether this actor has been daemonized */
+ void daemonize();
+ void undaemonize();
+
std::unique_ptr<context::Context> context_; /* the context (uctx/raw/thread) that executes the user function */
std::exception_ptr exception_;
private:
s4u::Actor piface_; // Our interface is part of ourselves
- void undaemonize();
public:
s4u::ActorPtr get_iface() { return s4u::ActorPtr(&piface_); }
void kill_all() const;
void yield();
- void daemonize();
bool is_suspended() const { return suspended_; }
s4u::Actor* restart();
void suspend();
&ActorImpl::smx_synchro_hook>>;
XBT_PUBLIC void create_maestro(const std::function<void()>& code);
-XBT_PUBLIC unsigned long get_maxpid();
-XBT_PUBLIC unsigned long* get_maxpid_addr(); // In MC mode, the application sends this pointers to the MC
} // namespace actor
} // namespace kernel
XBT_DEBUG("Handling simcall %p: %s", &simcall_, simcall_.get_cname());
if (simcall_.observer_ != nullptr)
simcall_.observer_->prepare(times_considered);
- if (context_->wannadie())
+ if (wannadie())
return;
xbt_assert(simcall_.call_ != Simcall::Type::NONE, "Asked to do the noop syscall on %s@%s", get_cname(),
#include "mc/mc.h"
+#include "simgrid/Exception.hpp"
#include "simgrid/s4u/Host.hpp"
#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/context/Context.hpp"
void Context::stop()
{
this->actor_->cleanup_from_self();
-}
-
-void Context::set_wannadie(bool value)
-{
- XBT_DEBUG("Actor %s gonna die.", actor_->get_cname());
- iwannadie_ = value;
+ throw ForcefulKillException(); // clean RAII variables with the dedicated exception
}
AttachContext::~AttachContext() = default;
/** Turn the current thread into maestro (the old maestro becomes a regular actor) */
virtual Context* create_maestro(std::function<void()>&& code, actor::ActorImpl* actor);
- virtual void run_all() = 0;
+ virtual void run_all(std::vector<actor::ActorImpl*> const& actors_list) = 0;
protected:
template <class T, class... Args> T* new_context(Args&&... args)
std::function<void()> code_;
actor::ActorImpl* actor_ = nullptr;
- bool iwannadie_ = false; // True if we need to do some cleanups in actor mode.
- bool to_be_freed_ = false; // True if cleanups in actor mode done, but cleanups in kernel mode pending
bool is_maestro_;
void declare_context(std::size_t size);
Context& operator=(const Context&) = delete;
virtual ~Context();
- bool wannadie() const { return iwannadie_; }
- void set_wannadie(bool value = true);
- bool to_be_freed() const { return to_be_freed_; }
- void set_to_be_freed() { to_be_freed_ = true; }
bool is_maestro() const { return is_maestro_; }
void operator()() const { code_(); }
bool has_code() const { return static_cast<bool>(code_); }
#include <xbt/parmap.hpp>
#include "src/internal_config.h"
-#include "src/kernel/context/Context.hpp"
#include "src/kernel/context/ContextSwapped.hpp"
namespace simgrid {
#endif
try {
(*context)();
- context->Context::stop();
+ context->stop();
} catch (simgrid::ForcefulKillException const&) {
XBT_DEBUG("Caught a ForcefulKillException");
} catch (simgrid::Exception const& e) {
#endif
}
-void SwappedContext::stop()
-{
- Context::stop();
- /* We must cut the actor execution using an exception to properly free the C++ RAII variables */
- throw ForcefulKillException();
-}
-
void SwappedContext::swap_into(SwappedContext* to)
{
#if HAVE_SANITIZER_ADDRESS_FIBER_SUPPORT
}
/** Maestro wants to run all ready actors */
-void SwappedContextFactory::run_all()
+void SwappedContextFactory::run_all(std::vector<actor::ActorImpl*> const& actors_list)
{
const auto* engine = EngineImpl::get_instance();
/* This function is called by maestro at the beginning of a scheduling round to get all working threads executing some
auto* context = static_cast<SwappedContext*>(actor->context_.get());
context->resume();
},
- engine->get_actors_to_run());
+ actors_list);
} else { // sequential execution
- if (not engine->has_actors_to_run())
+ if (actors_list.empty())
return;
/* maestro is already saved in the first slot of workers_context_ */
SwappedContextFactory() = default;
SwappedContextFactory(const SwappedContextFactory&) = delete;
SwappedContextFactory& operator=(const SwappedContextFactory&) = delete;
- void run_all() override;
+ void run_all(std::vector<actor::ActorImpl*> const& actors) override;
private:
/* For the sequential execution */
void suspend() override;
virtual void resume();
- XBT_ATTRIB_NORETURN void stop() override;
void swap_into(SwappedContext* to);
return this->new_context<SerialThreadContext>(std::move(code), actor, maestro);
}
-void ThreadContextFactory::run_all()
-{
- if (is_parallel()) {
- // Parallel execution
- ParallelThreadContext::run_all();
- } else {
- // Serial execution
- SerialThreadContext::run_all();
- }
+void ThreadContextFactory::run_all(std::vector<actor::ActorImpl*> const& actors_list)
+{
+ if (is_parallel())
+ ParallelThreadContext::run_all(actors_list);
+
+ else
+ SerialThreadContext::run_all(actors_list);
}
// ThreadContext
try {
(*context)();
- if (not context->is_maestro()) { // Just in case somebody detached maestro
- context->Context::stop();
- context->stop_hook();
- }
+ if (not context->is_maestro()) // Just in case somebody detached maestro
+ context->stop();
} catch (ForcefulKillException const&) {
XBT_DEBUG("Caught a ForcefulKillException in Thread::wrapper");
xbt_assert(not context->is_maestro(), "Maestro shall not receive ForcefulKillExceptions, even when detached.");
this->end_.release();
}
-void ThreadContext::stop()
-{
- Context::stop();
- stop_hook();
- throw ForcefulKillException();
-}
-
void ThreadContext::suspend()
{
this->yield();
// SerialThreadContext
-void SerialThreadContext::run_all()
+void SerialThreadContext::run_all(std::vector<actor::ActorImpl*> const& actors_list)
{
- const auto& to_run = EngineImpl::get_instance()->get_actors_to_run();
- for (smx_actor_t const& actor : to_run) {
+ for (smx_actor_t const& actor : actors_list) {
XBT_DEBUG("Handling %p", actor);
auto* context = static_cast<ThreadContext*>(actor->context_.get());
context->release();
thread_sem_ = nullptr;
}
-void ParallelThreadContext::run_all()
+void ParallelThreadContext::run_all(std::vector<actor::ActorImpl*> const& actors_list)
{
- const auto& to_release = EngineImpl::get_instance()->get_actors_to_run();
- for (smx_actor_t const& actor : to_release)
+ for (smx_actor_t const& actor : actors_list)
static_cast<ThreadContext*>(actor->context_.get())->release();
- const auto& to_wait = EngineImpl::get_instance()->get_actors_to_run();
- for (smx_actor_t const& actor : to_wait)
+
+ for (smx_actor_t const& actor : actors_list)
static_cast<ThreadContext*>(actor->context_.get())->wait();
}
ThreadContext(const ThreadContext&) = delete;
ThreadContext& operator=(const ThreadContext&) = delete;
~ThreadContext() override;
- XBT_ATTRIB_NORETURN void stop() override;
void suspend() override;
void attach_start() override;
void attach_stop() override;
void yield(); // match a call to yield()
virtual void start_hook() { /* empty placeholder, called after start(). Used in parallel mode and Java */}
virtual void yield_hook() { /* empty placeholder, called before yield(). Used in parallel mode */}
- virtual void stop_hook() { /* empty placeholder, called at stop(). Used in Java */}
static void wrapper(ThreadContext* context);
};
{
}
- static void run_all();
+ static void run_all(std::vector<actor::ActorImpl*> const& actors_list);
};
class ParallelThreadContext : public ThreadContext {
static void initialize();
static void finalize();
- static void run_all();
+ static void run_all(std::vector<actor::ActorImpl*> const& actors_list);
private:
static xbt::OsSemaphore* thread_sem_;
bool maestro = not code;
return create_context(std::move(code), actor, maestro);
}
- void run_all() override;
+ void run_all(std::vector<actor::ActorImpl*> const& actors) override;
// Optional methods:
ThreadContext* attach(actor::ActorImpl* actor) override
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/mc/mc_record.hpp"
+#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/activity/CommImpl.hpp"
-#include "src/kernel/context/Context.hpp"
#include "src/mc/mc_base.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/mc/transition/Transition.hpp"
XBT_DEBUG("Executing %ld$%i", transition->aid_, transition->times_considered_);
// Choose a request:
- kernel::actor::ActorImpl* actor = kernel::actor::ActorImpl::by_pid(transition->aid_);
+ kernel::actor::ActorImpl* actor = kernel::EngineImpl::get_instance()->get_actor_by_pid(transition->aid_);
xbt_assert(actor != nullptr, "Unexpected actor (id:%ld).", transition->aid_);
const kernel::actor::Simcall* simcall = &(actor->simcall_);
xbt_assert(simcall->call_ != kernel::actor::Simcall::Type::NONE, "No simcall for process %ld.", transition->aid_);
}
void AppSide::handle_simcall_execute(const s_mc_message_simcall_execute_t* message) const
{
- kernel::actor::ActorImpl* actor = kernel::actor::ActorImpl::by_pid(message->aid_);
+ kernel::actor::ActorImpl* actor = kernel::EngineImpl::get_instance()->get_actor_by_pid(message->aid_);
xbt_assert(actor != nullptr, "Invalid pid %ld", message->aid_);
// The client may send some messages to the server while processing the transition
void AppSide::handle_actor_enabled(const s_mc_message_actor_enabled_t* msg) const
{
- bool res = mc::actor_is_enabled(kernel::actor::ActorImpl::by_pid(msg->aid));
+ bool res = mc::actor_is_enabled(kernel::EngineImpl::get_instance()->get_actor_by_pid(msg->aid));
s_mc_message_int_t answer{MessageType::ACTOR_ENABLED_REPLY, res};
xbt_assert(channel_.send(answer) == 0, "Could not send ACTOR_ENABLED_REPLY");
}
#include "src/include/mc/mc.h"
#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
-#include "src/kernel/context/Context.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/surf/HostImpl.hpp"
kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
const kernel::actor::ActorImpl* target = pimpl_;
kernel::actor::simcall_blocking([issuer, target, timeout] {
- if (target->context_->wannadie()) {
+ if (target->wannadie()) {
// The joined actor is already finished, just wake up the issuer right away
issuer->simcall_answer();
} else {
ActorPtr Actor::by_pid(aid_t pid)
{
- kernel::actor::ActorImpl* actor = kernel::actor::ActorImpl::by_pid(pid);
+ kernel::actor::ActorImpl* actor = kernel::EngineImpl::get_instance()->get_actor_by_pid(pid);
if (actor != nullptr)
return actor->get_iface();
else
#include "simgrid/s4u/Engine.hpp"
#include "simgrid/s4u/Host.hpp"
#include "simgrid/version.h"
+#include "smpi_coll.hpp"
#include "smpi_comm.hpp"
#include "smpi_datatype_derived.hpp"
#include "smpi_status.hpp"
-#include "smpi_coll.hpp"
+#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/smpi/include/smpi_actor.hpp"
XBT_WARN("MPI_Abort was called, something went probably wrong in this simulation ! Killing all processes sharing the same MPI_COMM_WORLD");
auto myself = simgrid::kernel::actor::ActorImpl::self();
for (int i = 0; i < comm->size(); i++){
- auto actor = simgrid::kernel::actor::ActorImpl::by_pid(comm->group()->actor(i));
+ auto actor = simgrid::kernel::EngineImpl::get_instance()->get_actor_by_pid(comm->group()->actor(i));
if (actor != nullptr && actor != myself)
simgrid::kernel::actor::simcall_answered([actor] { actor->exit(); });
}
#include "smpi_datatype.hpp"
#include "smpi_host.hpp"
#include "smpi_op.hpp"
+#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
size_t payload_size_ = size_ + 16;//MPI enveloppe size (tag+dest+communicator)
kernel::actor::CommIsendSimcall observer{
- simgrid::kernel::actor::ActorImpl::by_pid(src_), mailbox->get_impl(), static_cast<double>(payload_size_), -1,
- static_cast<unsigned char*>(buf), real_size_, &match_send,
+ simgrid::kernel::EngineImpl::get_instance()->get_actor_by_pid(src_), mailbox->get_impl(),
+ static_cast<double>(payload_size_), -1, static_cast<unsigned char*>(buf), real_size_, &match_send,
&xbt_free_f, // how to free the userdata if a detached send fails
process->replaying() ? &smpi_comm_null_copy_buffer_callback : smpi_comm_copy_data_callback, this,
// detach if msg size < eager/rdv switch limit
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/Exception.hpp"
-#include "src/kernel/context/Context.hpp"
#include <xbt/config.hpp>
#include <xbt/log.hpp>
c1->wait();
end_time = sg4::Engine::get_clock();
XBT_INFO("Actual result: Sending 1B while computing 2 flops takes %.4f seconds.", end_time - start_time);
- XBT_INFO("\n");
}
int main(int argc, char** argv)
~SemStack()
{
for (auto* sem : to_release) {
+ XBT_INFO("Go release a semaphore");
sem->release();
XBT_INFO("Released a semaphore on exit. It's now %d", sem->get_capacity());
}
[](bool forcefully) { XBT_INFO("Producer dying %s.", forcefully ? "forcefully" : "peacefully"); });
while (todo > 0) {
- xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
- "Failed to exchange all tasks in less than %d seconds. Is this an infinite loop?", (int)cfg_deadline);
-
sg4::this_actor::sleep_for(1); // Give a chance to the monkey to kill this actor at this point
- while (buf.sem_empty->acquire_timeout(10))
+ while (buf.sem_empty->acquire_timeout(10)) {
XBT_INFO("Timeouted");
+ xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
+ "Failed to exchange all tasks in less than %d seconds. Is this an infinite loop?", (int)cfg_deadline);
+ }
to_release.push(buf.sem_empty);
XBT_INFO("sem_empty acquired");
int item;
do {
- xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
- "Failed to exchange all tasks in less than %d seconds. Is this an infinite loop?", (int)cfg_deadline);
-
sg4::this_actor::sleep_for(0.75); // Give a chance to the monkey to kill this actor at this point
- while (buf.sem_full->acquire_timeout(10))
+ while (buf.sem_full->acquire_timeout(10)) {
XBT_INFO("Timeouted");
+ xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
+ "Failed to exchange all tasks in less than %d seconds. Is this an infinite loop?", (int)cfg_deadline);
+ }
to_release.push(buf.sem_full);
sg4::this_actor::sleep_for(0.75); // Give a chance to the monkey to kill this actor at this point
printf("%d ", rb[i]);
printf("]\n");
- if (rank == 0 && status != MPI_SUCCESS) {
+ if (rank == 0 && status != MPI_SUCCESS)
printf("all_to_all returned %d\n", status);
- fflush(stdout);
- }
+ fflush(stdout);
xbt_free(sb);
xbt_free(rb);
MPI_Finalize();
MPI_Barrier(MPI_COMM_WORLD);
if (0 == rank) {
printf("Alltoallv TEST COMPLETE.\n");
+ fflush(stdout);
}
free(sdispls);
free(rdispls);
logs.append("(ignoring the output of <{cmd}> as requested)".format(cmd=cmd_name))
else:
stdouta = stdout_data.split("\n")
+ stdouta = self.remove_ignored_lines(stdouta)
while stdouta and stdouta[-1] == "":
del stdouta[-1]
- stdouta = self.remove_ignored_lines(stdouta)
stdcpy = stdouta[:]
# Mimic the "sort" bash command, which is case unsensitive.