/* 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 "src/internal_config.h"
-
-#include "xbt/parmap.hpp"
+#include "ContextRaw.hpp"
-#include "src/simix/smx_private.h"
#include "mc/mc.h"
+#include "src/internal_config.h"
+#include "xbt/parmap.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
-// ***** Class definitions
-
-namespace simgrid {
-namespace kernel {
-namespace context {
-
-class RawContext;
-class RawContextFactory;
-
-/** @brief Fast context switching inspired from SystemV ucontexts.
- *
- * The main difference to the System V context is that Raw Contexts are much faster because they don't
- * preserve the signal mask when switching. This saves a system call (at least on Linux) on each context switch.
- */
-class RawContext : public Context {
-protected:
- void* stack_ = nullptr;
- /** pointer to top the stack stack */
- void* stack_top_ = nullptr;
-public:
- friend class RawContextFactory;
- RawContext(std::function<void()> code,
- void_pfn_smxprocess_t cleanup_func,
- smx_actor_t process);
- ~RawContext() override;
-
- static void wrapper(void* arg);
- void stop() override;
- void suspend() override;
- void resume();
-private:
- void suspend_serial();
- void suspend_parallel();
- void resume_serial();
- void resume_parallel();
-};
-
-class RawContextFactory : public ContextFactory {
-public:
- RawContextFactory();
- ~RawContextFactory() override;
- RawContext* create_context(std::function<void()> code,
- void_pfn_smxprocess_t cleanup, smx_actor_t process) override;
- void run_all() override;
-private:
- void run_all_adaptative();
- void run_all_serial();
- void run_all_parallel();
-};
-
-ContextFactory* raw_factory()
-{
- XBT_VERB("Using raw contexts. Because the glibc is just not good enough for us.");
- return new RawContextFactory();
-}
-
-}}} // namespace
-
// ***** Loads of static stuff
#if HAVE_THREAD_CONTEXTS
xbt_os_thread_key_create(&raw_worker_id_key);
// TODO, lazily init
raw_parmap = nullptr;
- raw_workers_context = xbt_new(RawContext*, nthreads);
+ raw_workers_context = new RawContext*[nthreads];
raw_maestro_context = nullptr;
#endif
- // TODO, if(SIMIX_context_get_parallel_threshold() > 1) => choose dynamically
+ // TODO: choose dynamically when SIMIX_context_get_parallel_threshold() > 1
}
}
{
#if HAVE_THREAD_CONTEXTS
delete raw_parmap;
- xbt_free(raw_workers_context);
+ delete[] raw_workers_context;
#endif
}
XBT_DEBUG("No more processes to run");
uintptr_t worker_id = (uintptr_t)
xbt_os_thread_get_specific(raw_worker_id_key);
- next_context = static_cast<RawContext*>(raw_workers_context[worker_id]);
+ next_context = raw_workers_context[worker_id];
XBT_DEBUG("Restoring worker stack %zu (working threads = %zu)",
worker_id, raw_threads_working);
}
#endif
}
-/** @brief Resumes all processes ready to run. */
-void RawContextFactory::run_all_adaptative()
+ContextFactory* raw_factory()
{
- unsigned long nb_processes = simix_global->process_to_run.size();
- if (SIMIX_context_is_parallel() &&
- static_cast<unsigned long>(SIMIX_context_get_parallel_threshold()) < nb_processes) {
- raw_context_parallel = true;
- XBT_DEBUG("Runall // %lu", nb_processes);
- this->run_all_parallel();
- } else {
- XBT_DEBUG("Runall serial %lu", nb_processes);
- raw_context_parallel = false;
- this->run_all_serial();
- }
+ XBT_VERB("Using raw contexts. Because the glibc is just not good enough for us.");
+ return new RawContextFactory();
}
-
}}}