- context->suspend();
-}
-
-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();
- throw StopRequest();
-}
-
-void RawContextFactory::run_all()
-{
- if (raw_context_parallel)
- run_all_parallel();
- else
- run_all_serial();
-}
-
-void RawContextFactory::run_all_serial()
-{
- if (simix_global->process_to_run.empty())
- return;
-
- smx_actor_t first_process = simix_global->process_to_run.front();
- 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 = new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
- raw_parmap->apply(
- [](smx_actor_t process) {
- 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
-}
-
-void RawContext::suspend()
-{
- if (raw_context_parallel)
- RawContext::suspend_parallel();
- else
- RawContext::suspend_serial();
-}
-
-void RawContext::suspend_serial()
-{
- /* determine the next context */
- RawContext* next_context = nullptr;
- unsigned long int i = raw_process_index;
- raw_process_index++;
- if (i < simix_global->process_to_run.size()) {
- /* execute the next process */
- XBT_DEBUG("Run next process");
- next_context = static_cast<RawContext*>(simix_global->process_to_run[i]->context);
- } else {
- /* all processes were run, return to maestro */
- XBT_DEBUG("No more process to run");
- next_context = static_cast<RawContext*>(raw_maestro_context);
- }
- SIMIX_context_set_current(next_context);
- raw_swapcontext(&this->stack_top_, next_context->stack_top_);
-}
-
-void RawContext::suspend_parallel()
-{
-#if HAVE_THREAD_CONTEXTS
- /* determine the next context */
- boost::optional<smx_actor_t> next_work = raw_parmap->next();
- RawContext* next_context;
- if (next_work) {
- /* there is a next process to resume */
- XBT_DEBUG("Run next process");
- next_context = static_cast<RawContext*>(next_work.get()->context);
- } else {
- /* all processes were run, go to the barrier */
- XBT_DEBUG("No more processes to run");
- uintptr_t worker_id = (uintptr_t)
- xbt_os_thread_get_specific(raw_worker_id_key);
- next_context = raw_workers_context[worker_id];
- XBT_DEBUG("Restoring worker stack %zu (working threads = %zu)",
- worker_id, raw_threads_working);
- }
-
- SIMIX_context_set_current(next_context);
- raw_swapcontext(&this->stack_top_, next_context->stack_top_);
-#endif
-}