1 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include "simgrid/s4u/Host.hpp"
9 #include "src/kernel/activity/CommImpl.hpp"
10 #include "src/kernel/context/Context.hpp"
11 #include "src/simix/smx_private.hpp"
12 #include "src/surf/surf_interface.hpp"
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
21 ContextFactoryInitializer factory_initializer = nullptr;
23 ContextFactory::~ContextFactory() = default;
25 static thread_local smx_context_t smx_current_context = nullptr;
26 Context* Context::self()
28 return smx_current_context;
30 void Context::set_current(Context* self)
32 smx_current_context = self;
35 void Context::declare_context(std::size_t size)
38 /* Store the address of the stack in heap to compare it apart of heap comparison */
40 MC_ignore_heap(this, size);
44 Context* ContextFactory::attach(smx_actor_t)
46 xbt_die("Cannot attach with this ContextFactory.\n"
47 "Try using --cfg=contexts/factory:thread instead.\n");
50 Context* ContextFactory::create_maestro(std::function<void()>, smx_actor_t)
52 xbt_die("Cannot create_maestro with this ContextFactory.\n"
53 "Try using --cfg=contexts/factory:thread instead.\n");
56 Context::Context(std::function<void()> code, smx_actor_t actor) : code_(std::move(code)), actor_(actor)
58 /* If no function was provided, this is the context for maestro
59 * and we should set it as the current context */
72 actor_->finished_ = true;
74 if (actor_->has_to_auto_restart() && not actor_->get_host()->is_on()) {
75 XBT_DEBUG("Insert host %s to watched_hosts because it's off and %s needs to restart",
76 actor_->get_host()->get_cname(), actor_->get_cname());
77 watched_hosts.insert(actor_->get_host()->get_name());
80 // Execute the termination callbacks
81 smx_process_exit_status_t exit_status = (actor_->context_->iwannadie) ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
82 while (not actor_->on_exit.empty()) {
83 s_smx_process_exit_fun_t exit_fun = actor_->on_exit.back();
84 actor_->on_exit.pop_back();
85 (exit_fun.fun)(exit_status, exit_fun.arg);
88 /* cancel non-blocking activities */
89 for (auto activity : actor_->comms)
90 boost::static_pointer_cast<activity::CommImpl>(activity)->cancel();
91 actor_->comms.clear();
93 XBT_DEBUG("%s@%s(%ld) should not run anymore", actor_->get_cname(), actor_->iface()->get_host()->get_cname(),
96 this->actor_->cleanup();
98 this->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), because that's me
99 simgrid::simix::simcall([this] {
100 simgrid::s4u::Actor::on_destruction(actor_->iface());
102 /* Unregister from the kill timer if any */
103 if (actor_->kill_timer != nullptr) {
104 SIMIX_timer_remove(actor_->kill_timer);
105 actor_->kill_timer = nullptr;
110 this->iwannadie = true;
113 AttachContext::~AttachContext() = default;
115 StopRequest::~StopRequest() = default;
117 void StopRequest::do_throw()
122 bool StopRequest::try_n_catch(std::function<void(void)> try_block)
128 } catch (StopRequest const&) {
129 XBT_DEBUG("Caught a StopRequest");
136 /** @brief Executes all the processes to run (in parallel if possible). */
137 void SIMIX_context_runall()
139 simix_global->context_factory->run_all();