"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",
- simgrid::kernel::context::stack_size / 1024);
+ simgrid::kernel::context::Context::stack_size / 1024);
} else if (siginfo->si_signo == SIGSEGV) {
fprintf(stderr, "Segmentation fault.\n");
#if HAVE_SMPI
: ActorIDTrait(name, ppid), host_(host), piface_(this)
{
simcall_.issuer_ = this;
- stacksize_ = context::stack_size;
+ stacksize_ = context::Context::stack_size;
}
ActorImpl::~ActorImpl()
namespace simgrid::kernel::context {
-static e_xbt_parmap_mode_t parallel_synchronization_mode = XBT_PARMAP_DEFAULT;
-static int parallel_contexts = 1;
-unsigned stack_size;
-unsigned guard_size;
-
-/** @brief Returns whether some parallel threads are used for the user contexts. */
-bool is_parallel()
-{
- return parallel_contexts > 1;
-}
-
-/**
- * @brief Returns the number of parallel threads used for the user contexts.
- * @return the number of threads (1 means no parallelism)
- */
-int get_nthreads()
-{
- return parallel_contexts;
-}
-
-/**
- * @brief Sets the number of parallel threads to use for the user contexts.
- *
- * This function should be called before initializing SIMIX.
- * A value of 1 means no parallelism (1 thread only).
- * If the value is greater than 1, the thread support must be enabled.
- *
- * @param nb_threads the number of threads to use
- */
-void set_nthreads(int nb_threads)
+void Context::set_nthreads(int nb_threads)
{
if (nb_threads <= 0) {
nb_threads = std::thread::hardware_concurrency();
XBT_INFO("Auto-setting contexts/nthreads to %d", nb_threads);
}
- parallel_contexts = nb_threads;
-}
-
-/**
- * @brief Sets the synchronization mode to use when actors are run in parallel.
- * @param mode how to synchronize threads if actors are run in parallel
- */
-void set_parallel_mode(e_xbt_parmap_mode_t mode)
-{
- parallel_synchronization_mode = mode;
-}
-
-/**
- * @brief Returns the synchronization mode used when actors are run in parallel.
- * @return how threads are synchronized if actors are run in parallel
- */
-e_xbt_parmap_mode_t get_parallel_mode()
-{
- return parallel_synchronization_mode;
+ Context::parallel_contexts = nb_threads;
}
ContextFactory::~ContextFactory() = default;
+e_xbt_parmap_mode_t Context::parallel_mode = XBT_PARMAP_DEFAULT;
+int Context::parallel_contexts = 1;
+unsigned Context::stack_size;
+unsigned Context::guard_size;
thread_local Context* Context::current_context_ = nullptr;
/* Install or disable alternate signal stack, for SIGSEGV handler. */
#include <functional>
namespace simgrid::kernel::context {
-extern unsigned stack_size;
-extern unsigned guard_size;
class XBT_PUBLIC ContextFactory {
public:
class XBT_PUBLIC Context {
friend ContextFactory;
+ static int parallel_contexts;
static thread_local Context* current_context_;
std::function<void()> code_;
void declare_context(std::size_t size);
public:
+ static e_xbt_parmap_mode_t parallel_mode;
+ static unsigned stack_size;
+ static unsigned guard_size;
+
static int install_sigsegv_stack(bool enable);
Context(std::function<void()>&& code, actor::ActorImpl* actor, bool maestro);
bool has_code() const { return static_cast<bool>(code_); }
actor::ActorImpl* get_actor() const { return this->actor_; }
+ /** @brief Returns whether some parallel threads are used for the user contexts. */
+ static bool is_parallel() { return parallel_contexts > 1; }
+ /** @brief Returns the number of parallel threads used for the user contexts (1 means no parallelism). */
+ static int get_nthreads() { return parallel_contexts; }
+ /**
+ * @brief Sets the number of parallel threads to use for the user contexts.
+ *
+ * This function should be called before initializing SIMIX.
+ * A value of 1 means no parallelism (1 thread only).
+ * If the value is greater than 1, the thread support must be enabled.
+ * If the value is less than 1, the optimal number of threads is chosen automatically.
+ *
+ * @param nb_threads the number of threads to use
+ */
+ static void set_nthreads(int nb_threads);
+
// Scheduling methods
virtual void stop();
virtual void suspend() = 0;
XBT_PRIVATE ContextFactory* raw_factory();
XBT_PRIVATE ContextFactory* boost_factory();
-XBT_PUBLIC bool is_parallel();
-XBT_PUBLIC int get_nthreads();
-XBT_PUBLIC void set_nthreads(int nb_threads);
-XBT_PUBLIC void set_parallel_mode(e_xbt_parmap_mode_t mode);
-XBT_PUBLIC e_xbt_parmap_mode_t get_parallel_mode();
} // namespace simgrid::kernel::context
#endif
* stuff It is much easier to understand what happens if you see the working threads as bodies that swap their soul
* for the ones of the simulated processes that must run.
*/
- if (is_parallel()) {
+ if (Context::is_parallel()) {
// We lazily create the parmap so that all options are actually processed when doing so.
if (parmap_ == nullptr)
- parmap_ = std::make_unique<simgrid::xbt::Parmap<actor::ActorImpl*>>(get_nthreads(), get_parallel_mode());
+ parmap_ =
+ std::make_unique<simgrid::xbt::Parmap<actor::ActorImpl*>>(Context::get_nthreads(), Context::parallel_mode);
// Usually, Parmap::apply() executes the provided function on all elements of the array.
// Here, the executed function does not return the control to the parmap before all the array is processed:
ThreadContextFactory::ThreadContextFactory() : ContextFactory()
{
- if (stack_size != 8 * 1024 * 1024)
+ if (Context::stack_size != 8 * 1024 * 1024)
XBT_INFO("Stack size modifications are ignored by thread factory.");
- if (is_parallel())
+ if (Context::is_parallel())
ParallelThreadContext::initialize();
}
ThreadContextFactory::~ThreadContextFactory()
{
- if (is_parallel())
+ if (Context::is_parallel())
ParallelThreadContext::finalize();
}
ThreadContext* ThreadContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor, bool maestro)
{
- if (is_parallel())
+ if (Context::is_parallel())
return this->new_context<ParallelThreadContext>(std::move(code), actor, maestro);
else
return this->new_context<SerialThreadContext>(std::move(code), actor, maestro);
void ThreadContextFactory::run_all(std::vector<actor::ActorImpl*> const& actors_list)
{
- if (is_parallel())
+ if (Context::is_parallel())
ParallelThreadContext::run_all(actors_list);
else
static void _sg_cfg_cb_contexts_parallel_mode(std::string_view mode_name)
{
if (mode_name == "posix") {
- simgrid::kernel::context::set_parallel_mode(XBT_PARMAP_POSIX);
+ simgrid::kernel::context::Context::parallel_mode = XBT_PARMAP_POSIX;
} else if (mode_name == "futex") {
- simgrid::kernel::context::set_parallel_mode(XBT_PARMAP_FUTEX);
+ simgrid::kernel::context::Context::parallel_mode = XBT_PARMAP_FUTEX;
} else if (mode_name == "busy_wait") {
- simgrid::kernel::context::set_parallel_mode(XBT_PARMAP_BUSY_WAIT);
+ simgrid::kernel::context::Context::parallel_mode = XBT_PARMAP_BUSY_WAIT;
} else {
xbt_die("Command line setting of the parallel synchronization mode should "
"be one of \"posix\", \"futex\" or \"busy_wait\"");
static simgrid::config::Flag<int> cfg_context_stack_size{
"contexts/stack-size", "Stack size of contexts in KiB (not with threads)", 8 * 1024,
- [](int value) { simgrid::kernel::context::stack_size = value * 1024; }};
+ [](int value) { simgrid::kernel::context::Context::stack_size = value * 1024; }};
/* guard size for contexts stacks in memory pages */
#if (PTH_STACKGROWTH != -1)
#endif
static simgrid::config::Flag<int> cfg_context_guard_size{
"contexts/guard-size", "Guard size for contexts stacks in memory pages", default_guard_size,
- [](int value) { simgrid::kernel::context::guard_size = value * xbt_pagesize; }};
+ [](int value) { simgrid::kernel::context::Context::guard_size = value * xbt_pagesize; }};
static simgrid::config::Flag<int> cfg_context_nthreads{
"contexts/nthreads", "Number of parallel threads used to execute user contexts", 1, [](int nthreads) {
"Parallel simulation is forbidden in the verified program, as there is no protection against race "
"conditions in mmalloc itself. Please don't be so greedy and show some mercy for our implementation.");
#endif
- simgrid::kernel::context::set_nthreads(nthreads);
+ simgrid::kernel::context::Context::set_nthreads(nthreads);
}};
/* synchronization mode for parallel user contexts */
sg_config_cmd_line(argc, argv);
- xbt_mallocator_initialization_is_done(simgrid::kernel::context::is_parallel());
+ xbt_mallocator_initialization_is_done(simgrid::kernel::context::Context::is_parallel());
}
void sg_config_finalize()
// We only need a simcall if the order of the setters is important (parallel run or MC execution).
// Otherwise, just call the function with no simcall
- if (simgrid::kernel::context::is_parallel()
+ if (simgrid::kernel::context::Context::is_parallel()
#if SIMGRID_HAVE_MC
|| MC_is_active() || MC_record_replay_is_active()
#endif
XBT_INFO("Parmap benchmark with %d workers (modes = %#x)...", nthreads, modes);
XBT_INFO("%s", "");
- simgrid::kernel::context::set_nthreads(nthreads);
+ simgrid::kernel::context::Context::set_nthreads(nthreads);
XBT_INFO("Benchmark for parmap create+apply+destroy (small comp):");
bench_all_modes(nthreads, timeout, modes, true, &fun_small_comp);
int status = 0;
xbt_log_control_set("parmap_test.fmt:[%c/%p]%e%m%n");
simgrid::s4u::Engine e(&argc, argv);
- simgrid::kernel::context::set_nthreads(16); // dummy value > 1
+ simgrid::kernel::context::Context::set_nthreads(16); // dummy value > 1
XBT_INFO("Basic testing posix");
status += test_parmap_basic(XBT_PARMAP_POSIX);