Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
improve the doc of the context factories
[simgrid.git] / src / simix / smx_context.cpp
index 83424f0..2edefd4 100644 (file)
@@ -6,18 +6,22 @@
 /* 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 <cerrno>
+#include <cstring>
+
 #include <utility>
 #include <string>
 
 #include <xbt/config.hpp>
+#include <xbt/log.h>
 #include <xbt/range.hpp>
+#include <xbt/sysdep.h>
 
 #include "src/internal_config.h"
 #include "xbt/log.h"
 #include "xbt/swag.h"
 #include "xbt/xbt_os_thread.h"
 #include "smx_private.h"
-#include "smx_private.hpp"
 #include "simgrid/sg_config.h"
 #include "src/internal_config.h"
 #include "simgrid/modelchecker.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_context, simix, "Context switching mechanism");
 
-static std::pair<const char*, simgrid::simix::ContextFactoryInitializer> context_factories[] = {
+static std::pair<const char*, simgrid::kernel::context::ContextFactoryInitializer> context_factories[] = {
 #if HAVE_RAW_CONTEXTS
-  { "raw", simgrid::simix::raw_factory },
+  { "raw", &simgrid::kernel::context::raw_factory },
 #endif
 #if HAVE_UCONTEXT_CONTEXTS
-  { "ucontext", simgrid::simix::sysv_factory },
+  { "ucontext", &simgrid::kernel::context::sysv_factory },
 #endif
 #if HAVE_BOOST_CONTEXTS
-  { "boost", simgrid::simix::boost_factory },
+  { "boost", &simgrid::kernel::context::boost_factory },
 #endif
 #if HAVE_THREAD_CONTEXTS
-  { "thread", simgrid::simix::thread_factory },
+  { "thread", &simgrid::kernel::context::thread_factory },
 #endif
 };
 
-static_assert(sizeof(context_factories) != 0,
-  "No context factories are enabled for this build");
+static_assert(sizeof(context_factories) != 0, "No context factories are enabled for this build");
 
 // Create the list of possible contexts:
 static inline
@@ -91,44 +94,22 @@ static int smx_parallel_contexts = 1;
 static int smx_parallel_threshold = 2;
 static e_xbt_parmap_mode_t smx_parallel_synchronization_mode = XBT_PARMAP_DEFAULT;
 
-static inline
-void invalid_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.");
-}
-
 /**
  * This function is called by SIMIX_global_init() to initialize the context module.
  */
-void SIMIX_context_mod_init(void)
+void SIMIX_context_mod_init()
 {
+  xbt_assert(simix_global->context_factory == nullptr);
+
 #if HAVE_THREAD_CONTEXTS && !HAVE_THREAD_LOCAL_STORAGE
   /* the __thread storage class is not available on this platform:
    * use getspecific/setspecific instead to store the current context in each thread */
   xbt_os_thread_key_create(&smx_current_context_key);
 #endif
-  if (simix_global->context_factory)
-    return;
+
   /* select the context factory to use to create the contexts */
-  if (simgrid::simix::factory_initializer) { // Give Java a chance to hijack the factory mechanism
-    simix_global->context_factory = simgrid::simix::factory_initializer();
+  if (simgrid::kernel::context::factory_initializer) { // Give Java a chance to hijack the factory mechanism
+    simix_global->context_factory = simgrid::kernel::context::factory_initializer();
     return;
   }
   /* use the factory specified by --cfg=contexts/factory:value */
@@ -137,20 +118,39 @@ void SIMIX_context_mod_init(void)
       simix_global->context_factory = factory.second();
       break;
     }
-  if (simix_global->context_factory == nullptr)
-    invalid_context_factory();
+
+  if (simix_global->context_factory == nullptr) {
+    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.");
+  }
 }
 
 /**
  * This function is called by SIMIX_clean() to finalize the context module.
  */
-void SIMIX_context_mod_exit(void)
+void SIMIX_context_mod_exit()
 {
   delete simix_global->context_factory;
   simix_global->context_factory = nullptr;
 }
 
-void *SIMIX_context_stack_new(void)
+void *SIMIX_context_stack_new()
 {
   void *stack;
 
@@ -184,9 +184,13 @@ void *SIMIX_context_stack_new(void)
 
 #ifndef _WIN32
     if (mprotect(stack, smx_context_guard_size, PROT_NONE) == -1) {
-      xbt_die("Failed to protect stack: %s", strerror(errno));
-      /* This is fatal. We are going to fail at some point when
-         we tryi reusing this. */
+      xbt_die(
+          "Failed to protect stack: %s.\n"
+          "If you are running a lot of actors, you may be exceeding the amount of mappings allowed per process.\n"
+          "On Linux systems, change this value with sudo sysctl -w vm.max_map_count=newvalue (default value: 65536)\n"
+          "Please see http://simgrid.gforge.inria.fr/simgrid/latest/doc/html/options.html#options_virt for more info.",
+          strerror(errno));
+      /* This is fatal. We are going to fail at some point when we try reusing this. */
     }
 #endif
     stack = (char *)stack + smx_context_guard_size;
@@ -231,16 +235,15 @@ void SIMIX_context_stack_delete(void *stack)
 }
 
 /** @brief Returns whether some parallel threads are used for the user contexts. */
-int SIMIX_context_is_parallel(void) {
+int SIMIX_context_is_parallel() {
   return smx_parallel_contexts > 1;
 }
 
 /**
- * \brief Returns the number of parallel threads used
- * for the user contexts.
+ * @brief Returns the number of parallel threads used for the user contexts.
  * \return the number of threads (1 means no parallelism)
  */
-int SIMIX_context_get_nthreads(void) {
+int SIMIX_context_get_nthreads() {
   return smx_parallel_contexts;
 }
 
@@ -274,7 +277,7 @@ void SIMIX_context_set_nthreads(int nb_threads) {
  * \return when the number of user processes ready to run is above
  * this threshold, they are run in parallel
  */
-int SIMIX_context_get_parallel_threshold(void) {
+int SIMIX_context_get_parallel_threshold() {
   return smx_parallel_threshold;
 }
 
@@ -296,7 +299,7 @@ void SIMIX_context_set_parallel_threshold(int threshold) {
  * parallel.
  * \return how threads are synchronized if processes are run in parallel
  */
-e_xbt_parmap_mode_t SIMIX_context_get_parallel_mode(void) {
+e_xbt_parmap_mode_t SIMIX_context_get_parallel_mode() {
   return smx_parallel_synchronization_mode;
 }
 
@@ -313,7 +316,7 @@ void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode) {
  * \brief Returns the current context of this thread.
  * \return the current context of this thread
  */
-smx_context_t SIMIX_context_get_current(void)
+smx_context_t SIMIX_context_get_current()
 {
   if (SIMIX_context_is_parallel()) {
 #if HAVE_THREAD_LOCAL_STORAGE