-RawContextFactory::RawContextFactory()
- : ContextFactory("RawContextFactory")
-{
- raw_context_parallel = SIMIX_context_is_parallel();
- if (raw_context_parallel) {
-#if HAVE_THREAD_CONTEXTS
- int nthreads = SIMIX_context_get_nthreads();
- xbt_os_thread_key_create(&raw_worker_id_key);
- // TODO, lazily init
- raw_parmap = nullptr;
- raw_workers_context = xbt_new(RawContext*, nthreads);
- raw_maestro_context = nullptr;
-#endif
- // TODO, if(SIMIX_context_get_parallel_threshold() > 1) => choose dynamically
- }
-}
-
-RawContextFactory::~RawContextFactory()
-{
-#if HAVE_THREAD_CONTEXTS
- if (raw_parmap)
- xbt_parmap_destroy(raw_parmap);
- xbt_free(raw_workers_context);
-#endif
-}
-
-RawContext* RawContextFactory::create_context(std::function<void()> code,
- void_pfn_smxprocess_t cleanup, smx_actor_t process)
-{
- return this->new_context<RawContext>(std::move(code), cleanup, process);
-}
-
-void RawContext::wrapper(void* arg)
-{
- RawContext* context = static_cast<RawContext*>(arg);
- (*context)();
- context->stop();
-}
-
-RawContext::RawContext(std::function<void()> code,
- void_pfn_smxprocess_t cleanup, smx_actor_t process)
- : Context(std::move(code), cleanup, process)
-{
- if (has_code()) {
- this->stack_ = SIMIX_context_stack_new();
- this->stack_top_ = raw_makecontext(this->stack_,
- smx_context_usable_stack_size,
- RawContext::wrapper,
- this);
- } else {
- if(process != nullptr && raw_maestro_context == nullptr)
- raw_maestro_context = this;
- if (MC_is_active())
- MC_ignore_heap(
- &raw_maestro_context->stack_top_,
- sizeof(raw_maestro_context->stack_top_));
- }
-}
-
-RawContext::~RawContext()
-{
- SIMIX_context_stack_delete(this->stack_);
-}
-
-void RawContext::stop()
-{
- Context::stop();
- this->suspend();
-}
-
-void RawContextFactory::run_all()
-{
- if (raw_context_parallel)
- run_all_parallel();
- else
- run_all_serial();
-}
-
-void RawContextFactory::run_all_serial()
-{
- if (xbt_dynar_is_empty(simix_global->process_to_run))
- return;
-
- smx_actor_t first_process =
- xbt_dynar_get_as(simix_global->process_to_run, 0, smx_actor_t);
- raw_process_index = 1;
- static_cast<RawContext*>(first_process->context)->resume_serial();
-}
-
-void RawContextFactory::run_all_parallel()
-{
-#if HAVE_THREAD_CONTEXTS
- raw_threads_working = 0;
- if (raw_parmap == nullptr)
- raw_parmap = xbt_parmap_new(
- SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
- xbt_parmap_apply(raw_parmap,
- [](void* arg) {
- smx_actor_t process = static_cast<smx_actor_t>(arg);
- RawContext* context = static_cast<RawContext*>(process->context);
- context->resume_parallel();
- },
- simix_global->process_to_run);
-#else
- xbt_die("You asked for a parallel execution, but you don't have any threads.");
-#endif
-}