Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use references for parameters of type std::function.
[simgrid.git] / src / kernel / context / Context.cpp
1 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved.          */
2
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. */
5
6 #include "mc/mc.h"
7
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"
13
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
15
16
17 namespace simgrid {
18 namespace kernel {
19 namespace context {
20
21 ContextFactoryInitializer factory_initializer = nullptr;
22
23 ContextFactory::~ContextFactory() = default;
24
25 static thread_local smx_context_t smx_current_context = nullptr;
26 Context* Context::self()
27 {
28   return smx_current_context;
29 }
30 void Context::set_current(Context* self)
31 {
32   smx_current_context = self;
33 }
34
35 void Context::declare_context(std::size_t size)
36 {
37 #if SIMGRID_HAVE_MC
38   /* Store the address of the stack in heap to compare it apart of heap comparison */
39   if(MC_is_active())
40     MC_ignore_heap(this, size);
41 #endif
42 }
43
44 Context* ContextFactory::attach(smx_actor_t)
45 {
46   xbt_die("Cannot attach with this ContextFactory.\n"
47     "Try using --cfg=contexts/factory:thread instead.\n");
48 }
49
50 Context* ContextFactory::create_maestro(std::function<void()>&&, smx_actor_t)
51 {
52   xbt_die("Cannot create_maestro with this ContextFactory.\n"
53     "Try using --cfg=contexts/factory:thread instead.\n");
54 }
55
56 Context::Context(std::function<void()>&& code, smx_actor_t actor) : code_(std::move(code)), actor_(actor)
57 {
58   /* If no function was provided, this is the context for maestro
59    * and we should set it as the current context */
60   if (not has_code())
61     set_current(this);
62 }
63
64 Context::~Context()
65 {
66   if (self() == this)
67     set_current(nullptr);
68 }
69
70 void Context::stop()
71 {
72   actor_->finished_ = true;
73
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());
78   }
79
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);
86   }
87
88   /* cancel non-blocking activities */
89   for (auto activity : actor_->comms)
90     boost::static_pointer_cast<activity::CommImpl>(activity)->cancel();
91   actor_->comms.clear();
92
93   XBT_DEBUG("%s@%s(%ld) should not run anymore", actor_->get_cname(), actor_->iface()->get_host()->get_cname(),
94             actor_->get_pid());
95
96   this->actor_->cleanup();
97
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());
101
102     /* Unregister from the kill timer if any */
103     if (actor_->kill_timer != nullptr) {
104       actor_->kill_timer->remove();
105       actor_->kill_timer = nullptr;
106     }
107
108     actor_->cleanup();
109   });
110   this->iwannadie = true;
111 }
112
113 AttachContext::~AttachContext() = default;
114
115 }}}
116
117 /** @brief Executes all the processes to run (in parallel if possible). */
118 void SIMIX_context_runall()
119 {
120   simix_global->context_factory->run_all();
121 }