Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'no_simix_global'
authorSUTER Frederic <frederic.suter@cc.in2p3.fr>
Fri, 17 Sep 2021 16:41:43 +0000 (18:41 +0200)
committerSUTER Frederic <frederic.suter@cc.in2p3.fr>
Fri, 17 Sep 2021 16:41:43 +0000 (18:41 +0200)
49 files changed:
MANIFEST.in
doc/doxygen/module-surf.doc
examples/cpp/maestro-set/s4u-maestro-set.cpp
include/simgrid/engine.h
include/simgrid/s4u/Engine.hpp
include/simgrid/simix.h
src/bindings/java/JavaContext.cpp
src/bindings/java/JavaContext.hpp
src/bindings/java/jmsg.cpp
src/bindings/java/jmsg_process.cpp
src/include/surf/surf.hpp
src/include/xbt/parmap.hpp
src/kernel/EngineImpl.cpp
src/kernel/EngineImpl.hpp
src/kernel/activity/ActivityImpl.cpp
src/kernel/activity/IoImpl.cpp
src/kernel/activity/SleepImpl.cpp
src/kernel/actor/ActorImpl.cpp
src/kernel/context/Context.cpp
src/kernel/context/Context.hpp
src/kernel/context/ContextBoost.cpp
src/kernel/context/ContextRaw.cpp
src/kernel/context/ContextSwapped.cpp
src/kernel/context/ContextThread.cpp
src/kernel/context/ContextUnix.cpp
src/mc/Session.cpp
src/mc/mc_base.cpp
src/mc/remote/RemotePtr.hpp
src/msg/msg_global.cpp
src/plugins/vm/s4u_VirtualMachine.cpp
src/s4u/s4u_Engine.cpp
src/simix/libsmx.cpp
src/simix/popping.cpp
src/simix/popping_bodies.cpp
src/simix/popping_generated.cpp
src/simix/simcalls.py
src/simix/smx_context.cpp
src/simix/smx_global.cpp
src/simix/smx_private.hpp [deleted file]
src/smpi/internals/smpi_actor.cpp
src/smpi/internals/smpi_config.cpp
src/smpi/internals/smpi_global.cpp
src/smpi/internals/smpi_utils.cpp
src/smpi/mpi/smpi_status.cpp
src/surf/sg_platf.cpp
src/surf/surf_interface.cpp
teshsuite/kernel/context-defaults/context-defaults.cpp
teshsuite/mc/dwarf/dwarf.cpp
tools/cmake/DefinePackages.cmake

index 6fe2661..fe26eda 100644 (file)
@@ -2444,7 +2444,6 @@ include src/simix/simcalls.in
 include src/simix/simcalls.py
 include src/simix/smx_context.cpp
 include src/simix/smx_global.cpp
-include src/simix/smx_private.hpp
 include src/smpi/bindings/smpi_f77.cpp
 include src/smpi/bindings/smpi_f77_coll.cpp
 include src/smpi/bindings/smpi_f77_comm.cpp
index 9dc285e..4cc3c6c 100644 (file)
@@ -1,4 +1,4 @@
-/** @addtogroup SURF_API
+/** @addtogroup SURF_API
   
   @section SURF_doc Surf documentation
    Surf is composed several components:
@@ -72,8 +72,6 @@
     extract them from @a surf_host_model->common_public->states.done_action_set.
     Depending on these results, you can schedule other tasks and call surf_solve() again.
 
-    When the simulation is over, just call surf_exit() to clean the memory.
-
     Have a look at the implementation of @ref MSG_API "MSG" and @ref SD_API "Simdag" to see how these module
     interact with SURF. But if you want to create a new API on top of SURF,
     we strongly recommend you to contact us before anyway.
index 81779a2..a0c1080 100644 (file)
@@ -64,7 +64,7 @@ int main(int argc, char* argv[])
 {
   /* Specify which code should be executed by maestro on another thread, once this current thread is affected to an
    * actor by the subsequent sg_actor_attach(). This must be done before the creation of the engine. */
-  SIMIX_set_maestro(maestro, nullptr);
+  simgrid_set_maestro(maestro, nullptr);
 
   simgrid::s4u::Engine e(&argc, argv);
 
index 1ffbe27..35c5be5 100644 (file)
@@ -41,6 +41,12 @@ XBT_PUBLIC void simgrid_register_function(const char* name, void (*code)(int, ch
 XBT_PUBLIC void simgrid_register_default(void (*code)(int, char**));
 /** Retrieve the simulation time (in seconds) */
 XBT_PUBLIC double simgrid_get_clock();
+/* Set some code to execute in the maestro (must be used before the engine creation)
+ *
+ * If no maestro code is registered (the default), the main thread
+ * is assumed to be the maestro. */
+XBT_PUBLIC void simgrid_set_maestro(void (*code)(void*), void* data);
+
 /** Retrieve the number of actors in the simulation */
 XBT_ATTRIB_DEPRECATED_v330("Please use sg_actor_count()") XBT_PUBLIC int simgrid_get_actor_count();
 
index a494fa0..fdffcc1 100644 (file)
@@ -50,6 +50,7 @@ public:
   static double get_clock();
   /** @brief Retrieve the engine singleton */
   static s4u::Engine* get_instance();
+  static s4u::Engine* get_instance(int* argc, char** argv);
 
   void load_platform(const std::string& platf) const;
 
index 69488a2..1b72388 100644 (file)
@@ -35,14 +35,12 @@ XBT_PUBLIC void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode);
 XBT_PUBLIC int SIMIX_is_maestro();
 
 /********************************** Global ************************************/
-/* Initialization and exit */
-XBT_PUBLIC void SIMIX_global_init(int* argc, char** argv);
-
 /* Set some code to execute in the maestro (must be used before the engine creation)
  *
  * If no maestro code is registered (the default), the main thread
  * is assumed to be the maestro. */
-XBT_PUBLIC void SIMIX_set_maestro(void (*code)(void*), void* data);
+XBT_ATTRIB_DEPRECATED_v333("Please use simgrid_set_maestro()") XBT_PUBLIC
+    void SIMIX_set_maestro(void (*code)(void*), void* data);
 
 /* Simulation execution */
 XBT_ATTRIB_DEPRECATED_v332("Please use EngineImpl:run()") XBT_PUBLIC void SIMIX_run();
index e1a1e4e..48e1da9 100644 (file)
@@ -8,7 +8,6 @@
 #include "JavaContext.hpp"
 #include "jxbt_utilities.hpp"
 #include "simgrid/Exception.hpp"
-#include "src/simix/smx_private.hpp"
 
 #include <functional>
 #include <utility>
index 39f01a9..938819d 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "simgrid/simix.h"
 #include "src/kernel/context/ContextThread.hpp"
-#include "src/simix/smx_private.hpp"
 
 #include "jmsg.hpp"
 
index cb08bb5..70d99fa 100644 (file)
 #include "simgrid/plugins/load.h"
 #include "simgrid/simix.h"
 
+#include "simgrid/s4u/Actor.hpp"
 #include "simgrid/s4u/Host.hpp"
 
-#include "src/simix/smx_private.hpp"
-
 #include "jmsg.hpp"
 #include "jmsg_as.hpp"
 #include "jmsg_host.h"
index 8144317..8547122 100644 (file)
@@ -12,6 +12,8 @@
 #include "jmsg_host.h"
 #include "jxbt_utilities.hpp"
 #include "simgrid/Exception.hpp"
+#include "simgrid/s4u/Actor.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java);
 
index d5d1645..a47d40c 100644 (file)
@@ -18,7 +18,7 @@
  *  This function has to be called to initialize the common structures. Then you will have to create the environment by
  *  calling  e.g. surf_host_model_init_CM02()
  *
- *  @see surf_host_model_init_CM02(), surf_host_model_init_compound(), surf_exit()
+ *  @see surf_host_model_init_CM02(), surf_host_model_init_compound()
  */
 XBT_PUBLIC void surf_init(int* argc, char** argv); /* initialize common structures */
 
@@ -48,15 +48,6 @@ XBT_PUBLIC double surf_solve(double max_date);
  */
 XBT_PUBLIC double surf_get_clock();
 
-/** @ingroup SURF_simulation
- *  @brief Exit SURF
- *
- *  Clean everything.
- *
- *  @see surf_init()
- */
-XBT_PUBLIC void surf_exit();
-
 /* surf parse file related (public because called from a test suite) */
 XBT_PUBLIC void parse_platform_file(const std::string& file);
 
index ae03c0c..5b9d583 100644 (file)
@@ -9,8 +9,8 @@
 #define XBT_PARMAP_HPP
 
 #include "src/internal_config.h" // HAVE_FUTEX_H
+#include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/context/Context.hpp"
-#include "src/simix/smx_private.hpp" /* simix_global */
 
 #include <boost/optional.hpp>
 #include <condition_variable>
@@ -286,10 +286,10 @@ template <typename T> typename Parmap<T>::Synchro* Parmap<T>::new_synchro(e_xbt_
 /** @brief Main function of a worker thread */
 template <typename T> void Parmap<T>::worker_main(ThreadData* data)
 {
+  auto engine                       = simgrid::kernel::EngineImpl::get_instance();
   Parmap<T>& parmap     = data->parmap;
   unsigned round        = 0;
-  kernel::context::Context* context =
-      simix_global->get_context_factory()->create_context(std::function<void()>(), nullptr);
+  kernel::context::Context* context = engine->get_context_factory()->create_context(std::function<void()>(), nullptr);
   kernel::context::Context::set_current(context);
 
   XBT_CDEBUG(xbt_parmap, "New worker thread created");
index d065c9f..d79c21f 100644 (file)
@@ -13,9 +13,9 @@
 #include "simgrid/sg_config.hpp"
 #include "src/include/surf/surf.hpp" //get_clock() and surf_solve()
 #include "src/kernel/resource/DiskImpl.hpp"
+#include "src/kernel/resource/profile/Profile.hpp"
 #include "src/mc/mc_record.hpp"
 #include "src/mc/mc_replay.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/smpi/include/smpi_actor.hpp"
 #include "src/surf/network_interface.hpp"
 #include "src/surf/xml/platf.hpp" // FIXME: KILLME. There must be a better way than mimicking XML here
 #include <dlfcn.h>
 #endif /* _WIN32 */
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(ker_engine, "Logging specific to Engine (kernel)");
+#if SIMGRID_HAVE_MC
+#include "src/mc/remote/AppSide.hpp"
+#endif
 
+XBT_LOG_NEW_DEFAULT_CATEGORY(ker_engine, "Logging specific to Engine (kernel)");
 namespace simgrid {
 namespace kernel {
+EngineImpl* EngineImpl::instance_ = nullptr; /* That singleton is awful too. */
 
 config::Flag<double> cfg_breakpoint{"debug/breakpoint",
                                     "When non-negative, raise a SIGTRAP after given (simulated) time", -1.0};
-EngineImpl::~EngineImpl()
+config::Flag<bool> cfg_verbose_exit{"debug/verbose-exit", "Display the actor status at exit", true};
+} // namespace kernel
+} // namespace simgrid
+
+XBT_ATTRIB_NORETURN static void inthandler(int)
 {
-  while (not timer::kernel_timers().empty()) {
-    delete timer::kernel_timers().top().second;
-    timer::kernel_timers().pop();
+  if (simgrid::kernel::cfg_verbose_exit) {
+    XBT_INFO("CTRL-C pressed. The current status will be displayed before exit (disable that behavior with option "
+             "'debug/verbose-exit').");
+    simgrid::kernel::EngineImpl::get_instance()->display_all_actor_status();
+  } else {
+    XBT_INFO("CTRL-C pressed, exiting. Hiding the current process status since 'debug/verbose-exit' is set to false.");
+  }
+  exit(1);
+}
+
+#ifndef _WIN32
+static void segvhandler(int signum, siginfo_t* siginfo, void* /*context*/)
+{
+  if ((siginfo->si_signo == SIGSEGV && siginfo->si_code == SEGV_ACCERR) || siginfo->si_signo == SIGBUS) {
+    fprintf(stderr,
+            "Access violation or Bus error detected.\n"
+            "This probably comes from a programming error in your code, or from a stack\n"
+            "overflow. If you are certain of your code, try increasing the stack size\n"
+            "   --cfg=contexts/stack-size:XXX (current size is %u KiB).\n"
+            "\n"
+            "If it does not help, this may have one of the following causes:\n"
+            "a bug in SimGrid, a bug in the OS or a bug in a third-party libraries.\n"
+            "Failing hardware can sometimes generate such errors too.\n"
+            "\n"
+            "If you think you've found a bug in SimGrid, please report it along with a\n"
+            "Minimal Working Example (MWE) reproducing your problem and a full backtrace\n"
+            "of the fault captured with gdb or valgrind.\n",
+            smx_context_stack_size / 1024);
+  } else if (siginfo->si_signo == SIGSEGV) {
+    fprintf(stderr, "Segmentation fault.\n");
+#if HAVE_SMPI
+    if (smpi_enabled() && smpi_cfg_privatization() == SmpiPrivStrategies::NONE) {
+#if HAVE_PRIVATIZATION
+      fprintf(stderr, "Try to enable SMPI variable privatization with --cfg=smpi/privatization:yes.\n");
+#else
+      fprintf(stderr, "Sadly, your system does not support --cfg=smpi/privatization:yes (yet).\n");
+#endif /* HAVE_PRIVATIZATION */
+    }
+#endif /* HAVE_SMPI */
   }
+  std::raise(signum);
+}
 
+/**
+ * Install signal handler for SIGSEGV.  Check that nobody has already installed
+ * its own handler.  For example, the Java VM does this.
+ */
+static void install_segvhandler()
+{
+  stack_t old_stack;
+
+  if (simgrid::kernel::context::Context::install_sigsegv_stack(&old_stack, true) == -1) {
+    XBT_WARN("Failed to register alternate signal stack: %s", strerror(errno));
+    return;
+  }
+  if (not(old_stack.ss_flags & SS_DISABLE)) {
+    XBT_DEBUG("An alternate stack was already installed (sp=%p, size=%zu, flags=%x). Restore it.", old_stack.ss_sp,
+              old_stack.ss_size, (unsigned)old_stack.ss_flags);
+    sigaltstack(&old_stack, nullptr);
+  }
+
+  struct sigaction action;
+  struct sigaction old_action;
+  action.sa_sigaction = &segvhandler;
+  action.sa_flags     = SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
+  sigemptyset(&action.sa_mask);
+
+  /* Linux tend to raise only SIGSEGV where other systems also raise SIGBUS on severe error */
+  for (int sig : {SIGSEGV, SIGBUS}) {
+    if (sigaction(sig, &action, &old_action) == -1) {
+      XBT_WARN("Failed to register signal handler for signal %d: %s", sig, strerror(errno));
+      continue;
+    }
+    if ((old_action.sa_flags & SA_SIGINFO) || old_action.sa_handler != SIG_DFL) {
+      XBT_DEBUG("A signal handler was already installed for signal %d (%p). Restore it.", sig,
+                (old_action.sa_flags & SA_SIGINFO) ? (void*)old_action.sa_sigaction : (void*)old_action.sa_handler);
+      sigaction(sig, &old_action, nullptr);
+    }
+  }
+}
+
+#endif /* _WIN32 */
+
+namespace simgrid {
+namespace kernel {
+
+EngineImpl::EngineImpl(int* argc, char** argv)
+{
+  EngineImpl::instance_ = this;
+}
+
+EngineImpl::~EngineImpl()
+{
   /* Since hosts_ is a std::map, the hosts are destroyed in the lexicographic order, which ensures that the output is
    * reproducible.
    */
@@ -66,6 +162,81 @@ EngineImpl::~EngineImpl()
   models_prio_.clear();
 }
 
+void EngineImpl::initialize(int* argc, char** argv)
+{
+#if SIMGRID_HAVE_MC
+  // The communication initialization is done ASAP, as we need to get some init parameters from the MC for different
+  // layers. But simix_global needs to be created, as we send the address of some of its fields to the MC that wants to
+  // read them directly.
+  simgrid::mc::AppSide::initialize();
+#endif
+
+  surf_init(argc, argv); /* Initialize SURF structures */
+
+  instance_->context_mod_init();
+
+  /* Prepare to display some more info when dying on Ctrl-C pressing */
+  std::signal(SIGINT, inthandler);
+
+#ifndef _WIN32
+  install_segvhandler();
+#endif
+
+  /* register a function to be called by SURF after the environment creation */
+  sg_platf_init();
+  s4u::Engine::on_platform_created.connect(surf_presolve);
+
+  if (config::get_value<bool>("debug/clean-atexit"))
+    atexit(shutdown);
+}
+void EngineImpl::shutdown()
+{
+  static bool already_cleaned_up = false;
+  if (already_cleaned_up)
+    return; // to avoid double cleaning by java and C
+  already_cleaned_up = true;
+  XBT_DEBUG("EngineImpl::shutdown() called. Simulation's over.");
+  if (instance_->has_actors_to_run() && simgrid_get_clock() <= 0.0) {
+    XBT_CRITICAL("   ");
+    XBT_CRITICAL("The time is still 0, and you still have processes ready to run.");
+    XBT_CRITICAL("It seems that you forgot to run the simulation that you setup.");
+    xbt_die("Bailing out to avoid that stop-before-start madness. Please fix your code.");
+  }
+
+  /* Kill all actors (but maestro) */
+  instance_->maestro_->kill_all();
+  instance_->run_all_actors();
+  instance_->empty_trash();
+
+#if HAVE_SMPI
+  if (not instance_->actor_list_.empty()) {
+    if (smpi_process()->initialized()) {
+      xbt_die("Process exited without calling MPI_Finalize - Killing simulation");
+    } else {
+      XBT_WARN("Process called exit when leaving - Skipping cleanups");
+      return;
+    }
+  }
+#endif
+
+  /* Let's free maestro now */
+  instance_->destroy_maestro();
+
+  /* Finish context module and SURF */
+  instance_->destroy_context_factory();
+
+  while (not timer::kernel_timers().empty()) {
+    delete timer::kernel_timers().top().second;
+    timer::kernel_timers().pop();
+  }
+
+  tmgr_finalize();
+  sg_platf_exit();
+
+  delete instance_;
+  instance_ = nullptr;
+}
+
 void EngineImpl::load_platform(const std::string& platf)
 {
   double start = xbt_os_time();
@@ -157,7 +328,7 @@ void EngineImpl::wake_all_waiting_actors() const
  */
 void EngineImpl::run_all_actors()
 {
-  simix_global->get_context_factory()->run_all();
+  instance_->get_context_factory()->run_all();
 
   actors_to_run_.swap(actors_that_ran_);
   actors_to_run_.clear();
@@ -175,6 +346,7 @@ actor::ActorImpl* EngineImpl::get_actor_by_pid(aid_t pid)
       return &a;
   return nullptr; // Not found, even in the trash
 }
+
 /** Execute all the tasks that are queued, e.g. `.then()` callbacks of futures. */
 bool EngineImpl::execute_tasks()
 {
@@ -376,7 +548,7 @@ void EngineImpl::run()
       if (actor_list_.size() == daemons_.size())
         for (auto const& dmon : daemons_) {
           XBT_DEBUG("Kill %s", dmon->get_cname());
-          simix_global->get_maestro()->kill(dmon);
+          maestro_->kill(dmon);
         }
     }
 
@@ -416,7 +588,7 @@ void EngineImpl::run()
       simgrid::s4u::Engine::on_deadlock();
       for (auto const& kv : actor_list_) {
         XBT_DEBUG("Kill %s", kv.second->get_cname());
-        simix_global->get_maestro()->kill(kv.second);
+        maestro_->kill(kv.second);
       }
     }
   } while (time > -1.0 || has_actors_to_run());
index b448c06..1676986 100644 (file)
@@ -70,21 +70,49 @@ class EngineImpl {
   std::vector<xbt::Task<void()>> tasks;
 
   std::mutex mutex_;
+  static EngineImpl* instance_;
+  actor::ActorImpl* maestro_ = nullptr;
+  context::ContextFactory* context_factory_ = nullptr;
+
   std::unique_ptr<void, std::function<int(void*)>> platf_handle_; //!< handle for platform library
   friend s4u::Engine;
 
 public:
-  EngineImpl() = default;
+  explicit EngineImpl(int* argc, char** argv);
 
+  /* Currently, only one instance is allowed to exist. This is why you can't copy or move it */
+#ifndef DOXYGEN
   EngineImpl(const EngineImpl&) = delete;
   EngineImpl& operator=(const EngineImpl&) = delete;
   virtual ~EngineImpl();
+  static void shutdown();
+#endif
 
+  void initialize(int* argc, char** argv);
   void load_platform(const std::string& platf);
   void load_deployment(const std::string& file) const;
   void register_function(const std::string& name, const actor::ActorCodeFactory& code);
   void register_default(const actor::ActorCodeFactory& code);
 
+  bool is_maestro(const actor::ActorImpl* actor) const { return actor == maestro_; }
+  void set_maestro(actor::ActorImpl* actor) { maestro_ = actor; }
+  actor::ActorImpl* get_maestro() const { return maestro_; }
+  void destroy_maestro()
+  {
+    delete maestro_;
+    maestro_ = nullptr;
+  }
+
+  context::ContextFactory* get_context_factory() const { return context_factory_; }
+  void set_context_factory(context::ContextFactory* factory) { context_factory_ = factory; }
+  bool has_context_factory() const { return context_factory_ != nullptr; }
+  void destroy_context_factory()
+  {
+    delete context_factory_;
+    context_factory_ = nullptr;
+  }
+
+  void context_mod_init();
   /**
    * @brief Add a model to engine list
    *
@@ -97,7 +125,9 @@ public:
   /** @brief Get list of all models managed by this engine */
   const std::vector<resource::Model*>& get_all_models() const { return models_; }
 
-  static EngineImpl* get_instance() { return simgrid::s4u::Engine::get_instance()->pimpl; }
+  static EngineImpl* get_instance() { return s4u::Engine::get_instance()->pimpl; }
+  static EngineImpl* get_instance(int* argc, char** argv) { return s4u::Engine::get_instance(argc, argv)->pimpl; }
+
   actor::ActorCodeFactory get_function(const std::string& name)
   {
     auto res = registered_functions.find(name);
index 70e8032..2bf2409 100644 (file)
@@ -6,9 +6,9 @@
 #include "src/kernel/activity/ActivityImpl.hpp"
 #include "simgrid/modelchecker.h"
 #include "src/kernel/activity/SynchroRaw.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
 #include "src/kernel/actor/SimcallObserver.hpp"
 #include "src/mc/mc_replay.hpp"
-#include "src/simix/smx_private.hpp"
 #include <boost/range/algorithm.hpp>
 #include <cmath> // isfinite()
 
index 5cd665c..dd4b9bc 100644 (file)
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Host.hpp"
 #include "simgrid/s4u/Io.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
 #include "src/kernel/actor/SimcallObserver.hpp"
+#include "src/kernel/context/Context.hpp"
 #include "src/kernel/resource/DiskImpl.hpp"
 #include "src/mc/mc_replay.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/surf/cpu_interface.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_io, simix, "Logging specific to SIMIX (io)");
index 6316b12..5a13593 100644 (file)
@@ -7,9 +7,9 @@
 #include "simgrid/Exception.hpp"
 #include "simgrid/kernel/resource/Action.hpp"
 #include "simgrid/s4u/Host.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
 #include "src/kernel/context/Context.hpp"
 #include "src/simix/popping_private.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/surf/cpu_interface.hpp"
 #include "src/surf/surf_interface.hpp"
 
index 587e847..d3b4ebf 100644 (file)
@@ -15,7 +15,6 @@
 #include "src/kernel/activity/SynchroRaw.hpp"
 #include "src/mc/mc_replay.hpp"
 #include "src/mc/remote/AppSide.hpp"
-#include "src/simix/smx_private.hpp"
 #if HAVE_SMPI
 #include "src/smpi/include/private.hpp"
 #endif
@@ -74,7 +73,7 @@ ActorImpl::ActorImpl(xbt::string name, s4u::Host* host) : host_(host), name_(std
 
 ActorImpl::~ActorImpl()
 {
-  if (simix_global != nullptr && not simix_global->is_maestro(this))
+  if (not EngineImpl::get_instance()->is_maestro(this))
     s4u::Actor::on_destruction(*get_ciface());
 }
 
@@ -103,8 +102,7 @@ ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* h
   actor->code_ = nullptr;
 
   XBT_VERB("Create context %s", actor->get_cname());
-  xbt_assert(simix_global != nullptr, "simix is not initialized, please call MSG_init first");
-  actor->context_.reset(simix_global->get_context_factory()->attach(actor));
+  actor->context_.reset(engine->get_context_factory()->attach(actor));
 
   /* Add the actor to it's host actor list */
   host->get_impl()->add_actor(actor);
@@ -179,7 +177,7 @@ void ActorImpl::cleanup()
 
   XBT_DEBUG("%s@%s(%ld) should not run anymore", get_cname(), get_host()->get_cname(), get_pid());
 
-  if (simix_global->is_maestro(this)) /* Do not cleanup maestro */
+  if (EngineImpl::get_instance()->is_maestro(this)) /* Do not cleanup maestro */
     return;
 
   XBT_DEBUG("Cleanup actor %s (%p), waiting synchro %p", get_cname(), this, waiting_synchro_.get());
@@ -236,7 +234,7 @@ void ActorImpl::exit()
 
 void ActorImpl::kill(ActorImpl* actor) const
 {
-  xbt_assert(not simix_global->is_maestro(actor), "Killing maestro is a rather bad idea");
+  xbt_assert(not EngineImpl::get_instance()->is_maestro(actor), "Killing maestro is a rather bad idea");
   if (actor->finished_) {
     XBT_DEBUG("Ignoring request to kill actor %s@%s that is already dead", actor->get_cname(),
               actor->host_->get_cname());
@@ -335,7 +333,7 @@ void ActorImpl::undaemonize()
 
 s4u::Actor* ActorImpl::restart()
 {
-  xbt_assert(not simix_global->is_maestro(this), "Restarting maestro is not supported");
+  xbt_assert(not EngineImpl::get_instance()->is_maestro(this), "Restarting maestro is not supported");
 
   XBT_DEBUG("Restarting actor %s on %s", get_cname(), host_->get_cname());
 
@@ -429,11 +427,11 @@ void ActorImpl::throw_exception(std::exception_ptr e)
 
 void ActorImpl::simcall_answer()
 {
-  if (not simix_global->is_maestro(this)) {
+  auto* engine = EngineImpl::get_instance();
+  if (not engine->is_maestro(this)) {
     XBT_DEBUG("Answer simcall %s issued by %s (%p)", SIMIX_simcall_name(simcall_), get_cname(), this);
     xbt_assert(simcall_.call_ != simix::Simcall::NONE);
     simcall_.call_ = simix::Simcall::NONE;
-    auto* engine              = EngineImpl::get_instance();
     const auto& actors_to_run = engine->get_actors_to_run();
     xbt_assert(not XBT_LOG_ISENABLED(simix_process, xbt_log_priority_debug) ||
                    std::find(begin(actors_to_run), end(actors_to_run), this) == end(actors_to_run),
@@ -474,7 +472,7 @@ ActorImpl* ActorImpl::start(const ActorCode& code)
 
   this->code_ = code;
   XBT_VERB("Create context %s", get_cname());
-  context_.reset(simix_global->get_context_factory()->create_context(ActorCode(code), this));
+  context_.reset(engine->get_context_factory()->create_context(ActorCode(code), this));
 
   XBT_DEBUG("Start context '%s'", get_cname());
 
@@ -509,17 +507,18 @@ ActorImplPtr ActorImpl::create(const std::string& name, const ActorCode& code, v
 
 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);
 
   if (not code) {
-    maestro->context_.reset(simix_global->get_context_factory()->create_context(ActorCode(), maestro));
+    maestro->context_.reset(engine->get_context_factory()->create_context(ActorCode(), maestro));
   } else {
-    maestro->context_.reset(simix_global->get_context_factory()->create_maestro(ActorCode(code), maestro));
+    maestro->context_.reset(engine->get_context_factory()->create_maestro(ActorCode(code), maestro));
   }
 
-  maestro->simcall_.issuer_     = maestro;
-  simix_global->set_maestro(maestro);
+  maestro->simcall_.issuer_ = maestro;
+  EngineImpl::get_instance()->set_maestro(maestro);
 }
 
 } // namespace actor
index 9109f6b..ae03b1b 100644 (file)
@@ -8,7 +8,6 @@
 #include "simgrid/s4u/Host.hpp"
 #include "src/kernel/activity/CommImpl.hpp"
 #include "src/kernel/context/Context.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/surf/surf_interface.hpp"
 
 #include <vector>
index b467843..30dd591 100644 (file)
@@ -107,5 +107,4 @@ XBT_PRIVATE ContextFactory* boost_factory();
 } // namespace kernel
 } // namespace simgrid
 
-XBT_PRIVATE void SIMIX_context_mod_init();
 #endif
index 2b66cb5..fb94d61 100644 (file)
@@ -6,7 +6,6 @@
 #include "ContextBoost.hpp"
 #include "simgrid/Exception.hpp"
 #include "src/internal_config.h"
-#include "src/simix/smx_private.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
 
index cdae042..9dedc92 100644 (file)
@@ -6,7 +6,6 @@
 #include "ContextRaw.hpp"
 #include "mc/mc.h"
 #include "simgrid/Exception.hpp"
-#include "src/simix/smx_private.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
 
index 5c9f34b..5716b0c 100644 (file)
@@ -8,7 +8,6 @@
 #include "src/internal_config.h"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/actor/ActorImpl.hpp"
-#include "src/simix/smx_private.hpp"
 #include "xbt/parmap.hpp"
 
 #include "src/kernel/context/ContextSwapped.hpp"
index a29203f..7cb10dd 100644 (file)
@@ -8,7 +8,6 @@
 #include "simgrid/Exception.hpp"
 #include "src/internal_config.h" /* loads context system definitions */
 #include "src/kernel/EngineImpl.hpp"
-#include "src/simix/smx_private.hpp"
 #include "xbt/function_types.h"
 #include "xbt/xbt_modinter.h" /* prototype of os thread module's init/exit in XBT */
 
@@ -157,7 +156,7 @@ void ThreadContext::suspend()
 void ThreadContext::attach_start()
 {
   // We're breaking the layers here by depending on the upper layer:
-  auto* maestro = static_cast<ThreadContext*>(simix_global->get_maestro()->context_.get());
+  auto* maestro = static_cast<ThreadContext*>(EngineImpl::get_instance()->get_maestro()->context_.get());
   maestro->begin_.release();
   xbt_assert(not this->is_maestro());
   this->start();
@@ -168,7 +167,7 @@ void ThreadContext::attach_stop()
   xbt_assert(not this->is_maestro());
   this->yield();
 
-  auto* maestro = static_cast<ThreadContext*>(simix_global->get_maestro()->context_.get());
+  auto* maestro = static_cast<ThreadContext*>(EngineImpl::get_instance()->get_maestro()->context_.get());
   maestro->end_.acquire();
 
   Context::set_current(nullptr);
index 50722e8..2e0394f 100644 (file)
@@ -9,7 +9,6 @@
 #include "simgrid/Exception.hpp"
 #include "src/kernel/actor/ActorImpl.hpp"
 #include "src/mc/mc_ignore.hpp"
-#include "src/simix/smx_private.hpp"
 
 #include "ContextUnix.hpp"
 
index 1bba77a..09d209d 100644 (file)
@@ -16,6 +16,7 @@
 #include "xbt/log.h"
 #include "xbt/system_error.hpp"
 
+#include "signal.h"
 #include <array>
 #include <memory>
 #include <string>
index 2f7aa44..9341466 100644 (file)
@@ -11,7 +11,6 @@
 #include "src/kernel/actor/SimcallObserver.hpp"
 #include "src/mc/mc_config.hpp"
 #include "src/mc/mc_replay.hpp"
-#include "src/simix/smx_private.hpp"
 
 #include "xbt/random.hpp"
 
index 4211542..c17823e 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef SIMGRID_MC_REMOTE_PTR_HPP
 #define SIMGRID_MC_REMOTE_PTR_HPP
 
-#include "src/simix/smx_private.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
 
 namespace simgrid {
 namespace mc {
index f1610fe..3e18336 100644 (file)
@@ -7,8 +7,8 @@
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Host.hpp"
 #include "src/instr/instr_private.hpp"
+#include "src/kernel/EngineImpl.hpp"
 #include "src/msg/msg_private.hpp"
-#include "src/simix/smx_private.hpp"
 #include <xbt/config.hpp>
 
 XBT_LOG_NEW_CATEGORY(msg, "All MSG categories");
@@ -34,7 +34,7 @@ void MSG_init_nocheck(int* argc, char** argv)
     simgrid::config::bind_flag(MSG_Global_t::debug_multiple_use, "msg/debug-multiple-use",
                                "Print backtraces of both processes when there is a conflict of multiple use of a task");
 
-    SIMIX_global_init(argc, argv);
+    simgrid::kernel::EngineImpl::get_instance(argc, argv);
 
     msg_global = new MSG_Global_t();
 
index 9eadb22..486a75b 100644 (file)
@@ -132,7 +132,7 @@ void VirtualMachine::destroy()
     });
   };
 
-  if (this_actor::get_host() == this) {
+  if (not this_actor::is_maestro() && this_actor::get_host() == this) {
     XBT_VERB("Launch another actor on physical host %s to destroy my own VM: %s", get_pm()->get_cname(), get_cname());
     simgrid::s4u::Actor::create(get_cname() + std::string("-destroy"), get_pm(), destroy_code);
     simgrid::s4u::this_actor::yield();
index 7d2b5b4..04f5166 100644 (file)
@@ -17,6 +17,7 @@
 #include "src/instr/instr_private.hpp"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/activity/CommImpl.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
 #include "src/mc/mc_replay.hpp"
 #include "src/surf/network_interface.hpp"
 #include "surf/surf.hpp" // routing_platf. FIXME:KILLME. SOON
@@ -28,6 +29,8 @@
 XBT_LOG_NEW_CATEGORY(s4u, "Log channels of the S4U (Simgrid for you) interface");
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_engine, s4u, "Logging specific to S4U (engine)");
 
+static simgrid::kernel::actor::ActorCode maestro_code;
+
 namespace simgrid {
 namespace s4u {
 xbt::signal<void()> Engine::on_platform_creation;
@@ -36,39 +39,46 @@ xbt::signal<void()> Engine::on_simulation_end;
 xbt::signal<void(double)> Engine::on_time_advance;
 xbt::signal<void(void)> Engine::on_deadlock;
 
-Engine* Engine::instance_ = nullptr; /* That singleton is awful, but I don't see no other solution right now. */
+Engine* Engine::instance_ = nullptr; /* This singleton is awful, but I don't see no other solution right now. */
 
 void Engine::initialize(int* argc, char** argv)
 {
   xbt_assert(Engine::instance_ == nullptr, "It is currently forbidden to create more than one instance of s4u::Engine");
   Engine::instance_ = this;
   instr::init();
-  SIMIX_global_init(argc, argv);
+  pimpl->initialize(argc, argv);
+  // Either create a new context with maestro or create
+  // a context object with the current context maestro):
+  kernel::actor::create_maestro(maestro_code);
 }
 
-Engine::Engine(std::string name) : pimpl(new kernel::EngineImpl())
+Engine::Engine(std::string name) : pimpl(new kernel::EngineImpl(nullptr, nullptr))
 {
   int argc   = 1;
   char* argv = &name[0];
   initialize(&argc, &argv);
 }
 
-Engine::Engine(int* argc, char** argv) : pimpl(new kernel::EngineImpl())
+Engine::Engine(int* argc, char** argv) : pimpl(new kernel::EngineImpl(argc, argv))
 {
   initialize(argc, argv);
 }
 
 Engine::~Engine()
 {
-  delete pimpl;
+  pimpl->shutdown();
   Engine::instance_ = nullptr;
 }
 
 /** @brief Retrieve the engine singleton */
 Engine* Engine::get_instance()
+{
+  return get_instance(nullptr, nullptr);
+}
+Engine* Engine::get_instance(int* argc, char** argv)
 {
   if (Engine::instance_ == nullptr) {
-    auto e = new Engine(nullptr, nullptr);
+    auto e = new Engine(argc, argv);
     xbt_assert(Engine::instance_ == e);
   }
   return Engine::instance_;
@@ -77,7 +87,6 @@ Engine* Engine::get_instance()
 void Engine::shutdown()
 {
   delete Engine::instance_;
-  Engine::instance_ = nullptr;
 }
 
 double Engine::get_clock()
@@ -455,7 +464,7 @@ Engine* Engine::set_default_comm_data_copy_callback(void (*callback)(kernel::act
 /* **************************** Public C interface *************************** */
 void simgrid_init(int* argc, char** argv)
 {
-  simgrid::s4u::Engine e(argc, argv);
+  static simgrid::s4u::Engine e(argc, argv);
 }
 void simgrid_load_platform(const char* file)
 {
@@ -487,3 +496,16 @@ int simgrid_get_actor_count() // XBT_ATTRIB_DEPRECATED_v330
 {
   return simgrid::s4u::Engine::get_instance()->get_actor_count();
 }
+
+void simgrid_set_maestro(void (*code)(void*), void* data)
+{
+#ifdef _WIN32
+  XBT_INFO("WARNING, SIMIX_set_maestro is believed to not work on windows. Please help us investigating this issue if "
+           "you need that feature");
+#endif
+  maestro_code = std::bind(code, data);
+}
+void SIMIX_set_maestro(void (*code)(void*), void* data) // XBT_ATTRIB_DEPRECATED_v333
+{
+  simgrid_set_maestro(code, data);
+}
index 5d323db..57b965c 100644 (file)
@@ -238,11 +238,6 @@ bool simcall_comm_test(simgrid::kernel::activity::ActivityImpl* comm)
  */
 smx_mutex_t simcall_mutex_init() // XBT_ATTRIB_DEPRECATED_v330
 {
-  if (simix_global == nullptr) {
-    fprintf(stderr, "You must initialize the SimGrid engine before using it\n"); // We can't use xbt_die since we may
-                                                                                 // get there before the initialization
-    xbt_abort();
-  }
   return simgrid::kernel::actor::simcall([] { return new simgrid::kernel::activity::MutexImpl(); });
 }
 
index f51d40d..e356ea2 100644 (file)
@@ -3,7 +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. */
 
-#include "smx_private.hpp"
+#include "src/simix/popping_private.hpp"
+#include "xbt/log.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_popping, simix,
                                 "Popping part of SIMIX (transmuting from user request into kernel handlers)");
index c3b3d94..d24df42 100644 (file)
@@ -14,7 +14,7 @@
  * That's not about http://en.wikipedia.org/wiki/Poop, despite the odor :)
  */
 
-#include "smx_private.hpp"
+#include "src/kernel/EngineImpl.hpp"
 #include "src/mc/mc_forward.hpp"
 #include "xbt/ex.h"
 #include <functional>
@@ -31,7 +31,7 @@ inline static R simcall(Simcall call, T const&... t)
 {
   smx_actor_t self = SIMIX_process_self();
   simgrid::simix::marshal(&self->simcall_, call, t...);
-  if (not simix_global->is_maestro(self)) {
+  if (not simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) {
     XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), SIMIX_simcall_name(self->simcall_));
     self->yield();
   } else {
index 20efc2d..c536c05 100644 (file)
@@ -14,7 +14,6 @@
  * That's not about http://en.wikipedia.org/wiki/Poop, despite the odor :)
  */
 
-#include "smx_private.hpp"
 #include <simgrid/host.h>
 #include <xbt/base.h>
 #if SIMGRID_HAVE_MC
@@ -22,6 +21,7 @@
 #endif
 #include "src/kernel/activity/ConditionVariableImpl.hpp"
 #include "src/kernel/actor/SimcallObserver.hpp"
+#include "src/kernel/context/Context.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);
 
index fb346f8..a98b947 100755 (executable)
@@ -307,7 +307,6 @@ if __name__ == '__main__':
 
     fd = header("popping_generated.cpp")
 
-    fd.write('#include "smx_private.hpp"\n')
     fd.write('#include <simgrid/host.h>\n')
     fd.write('#include <xbt/base.h>\n')
     fd.write('#if SIMGRID_HAVE_MC\n')
@@ -315,6 +314,7 @@ if __name__ == '__main__':
     fd.write('#endif\n')
     fd.write('#include "src/kernel/activity/ConditionVariableImpl.hpp"\n')
     fd.write('#include "src/kernel/actor/SimcallObserver.hpp"\n')
+    fd.write('#include "src/kernel/context/Context.hpp"\n')
 
     fd.write('\n')
     fd.write('XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);\n\n')
@@ -362,8 +362,8 @@ if __name__ == '__main__':
     # popping_bodies.cpp
     #
     fd = header('popping_bodies.cpp')
-    fd.write('#include "smx_private.hpp"\n')
     fd.write('#include "src/mc/mc_forward.hpp"\n')
+    fd.write('#include "src/kernel/EngineImpl.hpp"\n')
     fd.write('#include "xbt/ex.h"\n')
     fd.write('#include <functional>\n')
     fd.write('#include <simgrid/simix.hpp>\n')
@@ -380,7 +380,7 @@ inline static R simcall(Simcall call, T const&... t)
 {
   smx_actor_t self = SIMIX_process_self();
   simgrid::simix::marshal(&self->simcall_, call, t...);
-  if (not simix_global->is_maestro(self)) {
+  if (not simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) {
     XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), SIMIX_simcall_name(self->simcall_));
     self->yield();
   } else {
index 2d40401..a2c02ac 100644 (file)
@@ -6,7 +6,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "src/internal_config.h"
-#include "src/simix/smx_private.hpp"
+#include "src/kernel/EngineImpl.hpp"
 #include "src/smpi/include/private.hpp"
 #include "xbt/config.hpp"
 
@@ -53,64 +53,6 @@ unsigned smx_context_guard_size;
 static int smx_parallel_contexts = 1;
 static e_xbt_parmap_mode_t smx_parallel_synchronization_mode = XBT_PARMAP_DEFAULT;
 
-/**
- * This function is called by SIMIX_global_init() to initialize the context module.
- */
-void SIMIX_context_mod_init()
-{
-  xbt_assert(not simix_global->has_context_factory());
-
-#if HAVE_SMPI && (defined(__APPLE__) || defined(__NetBSD__))
-  smpi_init_options_internal(false);
-  std::string priv = simgrid::config::get_value<std::string>("smpi/privatization");
-  if (context_factory_name == "thread" && (priv == "dlopen" || priv == "yes" || priv == "default" || priv == "1")) {
-    XBT_WARN("dlopen+thread broken on Apple and BSD. Switching to raw contexts.");
-    context_factory_name = "raw";
-  }
-#endif
-
-#if HAVE_SMPI && defined(__FreeBSD__)
-  smpi_init_options_internal(false);
-  if (context_factory_name == "thread" && simgrid::config::get_value<std::string>("smpi/privatization") != "no") {
-    XBT_WARN("mmap broken on FreeBSD, but dlopen+thread broken too. Switching to dlopen+raw contexts.");
-    context_factory_name = "raw";
-  }
-#endif
-
-  /* select the context factory to use to create the contexts */
-  if (simgrid::kernel::context::factory_initializer != nullptr) { // Give Java a chance to hijack the factory mechanism
-    simix_global->set_context_factory(simgrid::kernel::context::factory_initializer());
-    return;
-  }
-  /* use the factory specified by --cfg=contexts/factory:value */
-  for (auto const& factory : context_factories)
-    if (context_factory_name == factory.first) {
-      simix_global->set_context_factory(factory.second());
-      break;
-    }
-
-  if (not simix_global->has_context_factory()) {
-    XBT_ERROR("Invalid context factory specified. Valid factories on this machine:");
-#if HAVE_RAW_CONTEXTS
-    XBT_ERROR("  raw: high performance context factory implemented specifically for SimGrid");
-#else
-    XBT_ERROR("  (raw contexts were disabled at compilation time on this machine -- check configure logs for details)");
-#endif
-#if HAVE_UCONTEXT_CONTEXTS
-    XBT_ERROR("  ucontext: classical system V contexts (implemented with makecontext, swapcontext and friends)");
-#else
-    XBT_ERROR("  (ucontext was disabled at compilation time on this machine -- check configure logs for details)");
-#endif
-#if HAVE_BOOST_CONTEXTS
-    XBT_ERROR("  boost: this uses the boost libraries context implementation");
-#else
-    XBT_ERROR("  (boost was disabled at compilation time on this machine -- check configure logs for details. Did you install the libboost-context-dev package?)");
-#endif
-    XBT_ERROR("  thread: slow portability layer using pthreads as provided by gcc");
-    xbt_die("Please use a valid factory.");
-  }
-}
-
 /** @brief Returns whether some parallel threads are used for the user contexts. */
 int SIMIX_context_is_parallel() {
   return smx_parallel_contexts > 1;
@@ -159,3 +101,64 @@ e_xbt_parmap_mode_t SIMIX_context_get_parallel_mode() {
 void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode) {
   smx_parallel_synchronization_mode = mode;
 }
+
+namespace simgrid {
+namespace kernel {
+
+void EngineImpl::context_mod_init()
+{
+  xbt_assert(not instance_->has_context_factory());
+
+#if HAVE_SMPI && (defined(__APPLE__) || defined(__NetBSD__))
+  smpi_init_options_internal(false);
+  std::string priv = config::get_value<std::string>("smpi/privatization");
+  if (context_factory_name == "thread" && (priv == "dlopen" || priv == "yes" || priv == "default" || priv == "1")) {
+    XBT_WARN("dlopen+thread broken on Apple and BSD. Switching to raw contexts.");
+    context_factory_name = "raw";
+  }
+#endif
+
+#if HAVE_SMPI && defined(__FreeBSD__)
+  smpi_init_options_internal(false);
+  if (context_factory_name == "thread" && config::get_value<std::string>("smpi/privatization") != "no") {
+    XBT_WARN("mmap broken on FreeBSD, but dlopen+thread broken too. Switching to dlopen+raw contexts.");
+    context_factory_name = "raw";
+  }
+#endif
+
+  /* select the context factory to use to create the contexts */
+  if (context::factory_initializer != nullptr) { // Give Java a chance to hijack the factory mechanism
+    instance_->set_context_factory(context::factory_initializer());
+    return;
+  }
+  /* use the factory specified by --cfg=contexts/factory:value */
+  for (auto const& factory : context_factories)
+    if (context_factory_name == factory.first) {
+      instance_->set_context_factory(factory.second());
+      break;
+    }
+
+  if (not instance_->has_context_factory()) {
+    XBT_ERROR("Invalid context factory specified. Valid factories on this machine:");
+#if HAVE_RAW_CONTEXTS
+    XBT_ERROR("  raw: high performance context factory implemented specifically for SimGrid");
+#else
+    XBT_ERROR("  (raw contexts were disabled at compilation time on this machine -- check configure logs for details)");
+#endif
+#if HAVE_UCONTEXT_CONTEXTS
+    XBT_ERROR("  ucontext: classical system V contexts (implemented with makecontext, swapcontext and friends)");
+#else
+    XBT_ERROR("  (ucontext was disabled at compilation time on this machine -- check configure logs for details)");
+#endif
+#if HAVE_BOOST_CONTEXTS
+    XBT_ERROR("  boost: this uses the boost libraries context implementation");
+#else
+    XBT_ERROR("  (boost was disabled at compilation time on this machine -- check configure logs for details. Did you "
+              "install the libboost-context-dev package?)");
+#endif
+    XBT_ERROR("  thread: slow portability layer using pthreads as provided by gcc");
+    xbt_die("Please use a valid factory.");
+  }
+}
+} // namespace kernel
+} // namespace simgrid
index 554ba73..5debbf8 100644 (file)
 #include "src/kernel/EngineImpl.hpp"
 #include "src/mc/mc_record.hpp"
 #include "src/mc/mc_replay.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/surf/xml/platf.hpp"
 
 #include "simgrid/kernel/resource/Model.hpp"
 
-#if SIMGRID_HAVE_MC
-#include "src/mc/remote/AppSide.hpp"
-#endif
-
 #include <memory>
 
 XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories");
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, "Logging specific to SIMIX (kernel)");
 
-std::unique_ptr<simgrid::simix::Global> simix_global;
-
 namespace simgrid {
 namespace simix {
-config::Flag<bool> cfg_verbose_exit{"debug/verbose-exit", "Display the actor status at exit", true};
 
 xbt_dynar_t simix_global_get_actors_addr()
 {
@@ -53,186 +45,6 @@ xbt_dynar_t simix_global_get_dead_actors_addr()
 } // namespace simix
 } // namespace simgrid
 
-XBT_ATTRIB_NORETURN static void inthandler(int)
-{
-  if (simgrid::simix::cfg_verbose_exit) {
-    XBT_INFO("CTRL-C pressed. The current status will be displayed before exit (disable that behavior with option "
-             "'debug/verbose-exit').");
-    simgrid::kernel::EngineImpl::get_instance()->display_all_actor_status();
-  } else {
-    XBT_INFO("CTRL-C pressed, exiting. Hiding the current process status since 'debug/verbose-exit' is set to false.");
-  }
-  exit(1);
-}
-
-#ifndef _WIN32
-static void segvhandler(int signum, siginfo_t* siginfo, void* /*context*/)
-{
-  if ((siginfo->si_signo == SIGSEGV && siginfo->si_code == SEGV_ACCERR) || siginfo->si_signo == SIGBUS) {
-    fprintf(stderr,
-            "Access violation or Bus error detected.\n"
-            "This probably comes from a programming error in your code, or from a stack\n"
-            "overflow. If you are certain of your code, try increasing the stack size\n"
-            "   --cfg=contexts/stack-size:XXX (current size is %u KiB).\n"
-            "\n"
-            "If it does not help, this may have one of the following causes:\n"
-            "a bug in SimGrid, a bug in the OS or a bug in a third-party libraries.\n"
-            "Failing hardware can sometimes generate such errors too.\n"
-            "\n"
-            "If you think you've found a bug in SimGrid, please report it along with a\n"
-            "Minimal Working Example (MWE) reproducing your problem and a full backtrace\n"
-            "of the fault captured with gdb or valgrind.\n",
-            smx_context_stack_size / 1024);
-  } else if (siginfo->si_signo == SIGSEGV) {
-    fprintf(stderr, "Segmentation fault.\n");
-#if HAVE_SMPI
-    if (smpi_enabled() && smpi_cfg_privatization() == SmpiPrivStrategies::NONE) {
-#if HAVE_PRIVATIZATION
-      fprintf(stderr, "Try to enable SMPI variable privatization with --cfg=smpi/privatization:yes.\n");
-#else
-      fprintf(stderr, "Sadly, your system does not support --cfg=smpi/privatization:yes (yet).\n");
-#endif /* HAVE_PRIVATIZATION */
-    }
-#endif /* HAVE_SMPI */
-  }
-  std::raise(signum);
-}
-
-/**
- * Install signal handler for SIGSEGV.  Check that nobody has already installed
- * its own handler.  For example, the Java VM does this.
- */
-static void install_segvhandler()
-{
-  stack_t old_stack;
-
-  if (simgrid::kernel::context::Context::install_sigsegv_stack(&old_stack, true) == -1) {
-    XBT_WARN("Failed to register alternate signal stack: %s", strerror(errno));
-    return;
-  }
-  if (not(old_stack.ss_flags & SS_DISABLE)) {
-    XBT_DEBUG("An alternate stack was already installed (sp=%p, size=%zu, flags=%x). Restore it.", old_stack.ss_sp,
-              old_stack.ss_size, (unsigned)old_stack.ss_flags);
-    sigaltstack(&old_stack, nullptr);
-  }
-
-  struct sigaction action;
-  struct sigaction old_action;
-  action.sa_sigaction = &segvhandler;
-  action.sa_flags     = SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
-  sigemptyset(&action.sa_mask);
-
-  /* Linux tend to raise only SIGSEGV where other systems also raise SIGBUS on severe error */
-  for (int sig : {SIGSEGV, SIGBUS}) {
-    if (sigaction(sig, &action, &old_action) == -1) {
-      XBT_WARN("Failed to register signal handler for signal %d: %s", sig, strerror(errno));
-      continue;
-    }
-    if ((old_action.sa_flags & SA_SIGINFO) || old_action.sa_handler != SIG_DFL) {
-      XBT_DEBUG("A signal handler was already installed for signal %d (%p). Restore it.", sig,
-                (old_action.sa_flags & SA_SIGINFO) ? (void*)old_action.sa_sigaction : (void*)old_action.sa_handler);
-      sigaction(sig, &old_action, nullptr);
-    }
-  }
-}
-
-#endif /* _WIN32 */
-
-static simgrid::kernel::actor::ActorCode maestro_code;
-void SIMIX_set_maestro(void (*code)(void*), void* data)
-{
-#ifdef _WIN32
-  XBT_INFO("WARNING, SIMIX_set_maestro is believed to not work on windows. Please help us investigating this issue if "
-           "you need that feature");
-#endif
-  maestro_code = std::bind(code, data);
-}
-
-void SIMIX_global_init(int* argc, char** argv)
-{
-  if (simix_global != nullptr)
-    return;
-
-  simix_global = std::make_unique<simgrid::simix::Global>();
-
-#if SIMGRID_HAVE_MC
-  // The communication initialization is done ASAP, as we need to get some init parameters from the MC for different
-  // layers. But simix_global needs to be created, as we send the address of some of its fields to the MC that wants to
-  // read them directly.
-  simgrid::mc::AppSide::initialize();
-#endif
-
-  surf_init(argc, argv); /* Initialize SURF structures */
-
-  SIMIX_context_mod_init();
-
-  // Either create a new context with maestro or create
-  // a context object with the current context maestro):
-  simgrid::kernel::actor::create_maestro(maestro_code);
-
-  /* Prepare to display some more info when dying on Ctrl-C pressing */
-  std::signal(SIGINT, inthandler);
-
-#ifndef _WIN32
-  install_segvhandler();
-#endif
-  /* register a function to be called by SURF after the environment creation */
-  sg_platf_init();
-  simgrid::s4u::Engine::on_platform_created.connect(surf_presolve);
-
-  if (simgrid::config::get_value<bool>("debug/clean-atexit"))
-    atexit(SIMIX_clean);
-}
-
-/**
- * @ingroup SIMIX_API
- * @brief Clean the SIMIX simulation
- *
- * This functions remove the memory used by SIMIX
- */
-void SIMIX_clean()
-{
-  static bool smx_cleaned = false;
-  if (smx_cleaned)
-    return; // to avoid double cleaning by java and C
-
-  smx_cleaned = true;
-  XBT_DEBUG("SIMIX_clean called. Simulation's over.");
-  auto* engine = simgrid::kernel::EngineImpl::get_instance();
-  if (engine->has_actors_to_run() && simgrid::s4u::Engine::get_clock() <= 0.0) {
-    XBT_CRITICAL("   ");
-    XBT_CRITICAL("The time is still 0, and you still have processes ready to run.");
-    XBT_CRITICAL("It seems that you forgot to run the simulation that you setup.");
-    xbt_die("Bailing out to avoid that stop-before-start madness. Please fix your code.");
-  }
-
-#if HAVE_SMPI
-  if (not engine->get_actor_list().empty()) {
-    if (smpi_process()->initialized()) {
-      xbt_die("Process exited without calling MPI_Finalize - Killing simulation");
-    } else {
-      XBT_WARN("Process called exit when leaving - Skipping cleanups");
-      return;
-    }
-  }
-#endif
-
-  /* Kill all processes (but maestro) */
-  simix_global->get_maestro()->kill_all();
-  engine->run_all_actors();
-  engine->empty_trash();
-
-  /* Let's free maestro now */
-  simix_global->destroy_maestro();
-
-  /* Finish context module and SURF */
-  simix_global->destroy_context_factory();
-
-  surf_exit();
-
-  simix_global = nullptr;
-}
-
 /**
  * @ingroup SIMIX_API
  * @brief A clock (in second).
@@ -251,8 +63,6 @@ void SIMIX_run() // XBT_ATTRIB_DEPRECATED_v332
 
 int SIMIX_is_maestro()
 {
-  if (simix_global == nullptr) // SimDag
-    return true;
   const simgrid::kernel::actor::ActorImpl* self = SIMIX_process_self();
-  return self == nullptr || simix_global->is_maestro(self);
+  return self == nullptr || simgrid::kernel::EngineImpl::get_instance()->is_maestro(self);
 }
diff --git a/src/simix/smx_private.hpp b/src/simix/smx_private.hpp
deleted file mode 100644 (file)
index f114e5f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2007-2021. 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 SIMIX_PRIVATE_HPP
-#define SIMIX_PRIVATE_HPP
-
-#include "simgrid/s4u/Actor.hpp"
-#include "src/kernel/actor/ActorImpl.hpp"
-#include "src/kernel/context/Context.hpp"
-
-/********************************** Simix Global ******************************/
-
-namespace simgrid {
-namespace simix {
-
-class Global {
-  kernel::context::ContextFactory* context_factory_ = nullptr;
-  kernel::actor::ActorImpl* maestro_                = nullptr;
-
-public:
-  bool is_maestro(const kernel::actor::ActorImpl* actor) const { return actor == maestro_; }
-  void set_maestro(kernel::actor::ActorImpl* actor) { maestro_ = actor; }
-  kernel::actor::ActorImpl* get_maestro() const { return maestro_; }
-  void destroy_maestro()
-  {
-    delete maestro_;
-    maestro_ = nullptr;
-  }
-
-  kernel::context::ContextFactory* get_context_factory() const { return context_factory_; }
-  void set_context_factory(kernel::context::ContextFactory* factory) { context_factory_ = factory; }
-  bool has_context_factory() const { return context_factory_ != nullptr; }
-  void destroy_context_factory()
-  {
-    delete context_factory_;
-    context_factory_ = nullptr;
-  }
-};
-}
-}
-
-XBT_PUBLIC_DATA std::unique_ptr<simgrid::simix::Global> simix_global;
-
-XBT_PUBLIC void SIMIX_clean();
-
-#endif
index 0758414..9169d0a 100644 (file)
@@ -10,7 +10,6 @@
 #include "smpi_comm.hpp"
 #include "smpi_info.hpp"
 #include "src/mc/mc_replay.hpp"
-#include "src/simix/smx_private.hpp"
 
 #if HAVE_PAPI
 #include "papi.h"
index 2c9cd03..a79eaed 100644 (file)
@@ -7,7 +7,6 @@
 #include "mc/mc.h"
 #include "private.hpp"
 #include "smpi_coll.hpp"
-#include "src/simix/smx_private.hpp"
 #include "xbt/parse_units.hpp"
 
 #include <cfloat> /* DBL_MAX */
index ba896e8..ff31723 100644 (file)
@@ -12,7 +12,6 @@
 #include "smpi_host.hpp"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/activity/CommImpl.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/smpi/include/smpi_actor.hpp"
 #include "xbt/config.hpp"
 #include "xbt/file.hpp"
@@ -544,10 +543,7 @@ int smpi_main(const char* executable, int argc, char* argv[])
   }
 
   smpi_init_options_internal(true);
-  simgrid::instr::init();
-  SIMIX_global_init(&argc, argv);
-
-  auto engine              = simgrid::s4u::Engine::get_instance();
+  auto engine = simgrid::s4u::Engine::get_instance(&argc, argv);
 
   sg_storage_file_system_init();
   // parse the platform file: get the host list
index bff153d..4b82f5d 100644 (file)
@@ -13,7 +13,6 @@
 #include "xbt/file.hpp"
 #include <boost/tokenizer.hpp>
 #include "smpi_config.hpp"
-#include "src/simix/smx_private.hpp"
 #include <algorithm>
 #include "private.hpp"
 
index f057400..1c43dbc 100644 (file)
@@ -6,7 +6,6 @@
 #include "smpi_status.hpp"
 #include "private.hpp"
 #include "smpi_datatype.hpp"
-#include "src/simix/smx_private.hpp"
 
 namespace simgrid{
 namespace smpi{
index 48b2c01..bbe48f2 100644 (file)
@@ -22,7 +22,6 @@
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/resource/DiskImpl.hpp"
 #include "src/kernel/resource/profile/Profile.hpp"
-#include "src/simix/smx_private.hpp"
 #include "src/surf/HostImpl.hpp"
 #include "src/surf/xml/platf_private.hpp"
 
index 27ff69a..595cdf4 100644 (file)
@@ -198,13 +198,3 @@ void surf_init(int* argc, char** argv)
 
   sg_config_init(argc, argv);
 }
-
-void surf_exit()
-{
-  simgrid::s4u::Engine::shutdown();
-
-  tmgr_finalize();
-  sg_platf_exit();
-
-  NOW = 0; /* Just in case the user plans to restart the simulation afterward */
-}
index f436b1f..01443c9 100644 (file)
@@ -6,13 +6,13 @@
 /* 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 "simgrid/simix.h"
+#include "simgrid/s4u/Engine.hpp"
 #include "xbt/log.h"
 
 int main(int argc, char* argv[])
 {
   xbt_log_control_set("root.fmt:[%c/%p]%e%m%n");
   xbt_log_control_set("simix_context.threshold:verbose");
-  SIMIX_global_init(&argc, argv);
+  simgrid::s4u::Engine::get_instance(&argc, argv);
   return 0;
 }
index 35208b3..fb5dfb8 100644 (file)
@@ -8,6 +8,7 @@
 #endif
 
 #include <mc/mc.h>
+#include <simgrid/s4u/Engine.hpp>
 
 #include "mc/datatypes.h"
 #include "src/mc/mc_private.hpp"
@@ -116,7 +117,7 @@ static void test_type_by_name(const simgrid::mc::RemoteProcess& process, s_foo /
 
 int main(int argc, char** argv)
 {
-  SIMIX_global_init(&argc, argv);
+  simgrid::s4u::Engine::get_instance(&argc, argv);
 
   const simgrid::mc::Variable* var;
   simgrid::mc::Type* type;
index 3533acd..ef3d323 100644 (file)
@@ -27,7 +27,6 @@ set(EXTRA_DIST
   src/simix/popping_generated.cpp
   src/simix/popping_enum.hpp
   src/simix/popping_accessors.hpp
-  src/simix/smx_private.hpp
   src/smpi/colls/coll_tuned_topo.hpp
   src/smpi/colls/colls_private.hpp
   src/smpi/colls/smpi_mvapich2_selector_stampede.hpp