-BoostContext::BoostContext(std::function<void()> code,
- void_pfn_smxprocess_t cleanup_func, smx_actor_t process)
- : Context(std::move(code), cleanup_func, process)
-{
-
- /* if the user provided a function for the process then use it, otherwise it is the context for maestro */
- if (has_code()) {
- this->stack_ = SIMIX_context_stack_new();
-// We need to pass the bottom of the stack to make_fcontext, depending on the stack direction it may be the lower
-// or higher address:
-#if PTH_STACKGROWTH == -1
- void* stack = static_cast<char*>(this->stack_) + smx_context_usable_stack_size;
-#else
- void* stack = this->stack_;
-#endif
- ASAN_EVAL(this->asan_stack_ = stack);
-#if BOOST_VERSION < 106100
- this->fc_ = boost::context::make_fcontext(stack, smx_context_usable_stack_size, smx_ctx_boost_wrapper);
-#else
- this->fc_ = boost::context::detail::make_fcontext(stack, smx_context_usable_stack_size, smx_ctx_boost_wrapper);
-#endif
- } else {
-#if BOOST_VERSION < 105600
- this->fc_ = new boost::context::fcontext_t();
-#endif
- if (BoostContext::maestro_context_ == nullptr)
- BoostContext::maestro_context_ = this;
- }
-}
-
-BoostContext::~BoostContext()
-{
-#if BOOST_VERSION < 105600
- if (not this->stack_)
- delete this->fc_;
-#endif
- if (this == maestro_context_)
- maestro_context_ = nullptr;
- SIMIX_context_stack_delete(this->stack_);
-}
-
-// BoostSerialContext
-
-void BoostContext::stop()
-{
- Context::stop();
- throw StopRequest();
-}
-
-void BoostContext::resume()
-{
- SIMIX_context_set_current(this);
- smx_ctx_boost_jump_fcontext(maestro_context_, this);
-}
-
-void BoostSerialContext::suspend()
-{
- /* determine the next context */
- BoostSerialContext* next_context;
- unsigned long int i = process_index_;
- process_index_++;
-
- if (i < simix_global->process_to_run.size()) {
- /* execute the next process */
- XBT_DEBUG("Run next process");
- next_context = static_cast<BoostSerialContext*>(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<BoostSerialContext*>(maestro_context_);
- }
- SIMIX_context_set_current(static_cast<smx_context_t>(next_context));
- smx_ctx_boost_jump_fcontext(this, next_context);
-}
-
-// BoostParallelContext
-
-#if HAVE_THREAD_CONTEXTS
-
-void BoostParallelContext::suspend()
-{
- boost::optional<smx_actor_t> next_work = parmap_->next();
- BoostParallelContext* next_context;
- if (next_work) {
- XBT_DEBUG("Run next process");
- next_context = static_cast<BoostParallelContext*>(next_work.get()->context);
- } else {
- XBT_DEBUG("No more processes to run");
- uintptr_t worker_id = reinterpret_cast<uintptr_t>(xbt_os_thread_get_specific(worker_id_key_));
- next_context = static_cast<BoostParallelContext*>(workers_context_[worker_id]);
- }
-
- SIMIX_context_set_current(static_cast<smx_context_t>(next_context));
- smx_ctx_boost_jump_fcontext(this, next_context);
-}
-
-void BoostParallelContext::resume()
-{
- uintptr_t worker_id = __sync_fetch_and_add(&threads_working_, 1);
- xbt_os_thread_set_specific(worker_id_key_, reinterpret_cast<void*>(worker_id));
-
- BoostParallelContext* worker_context = static_cast<BoostParallelContext*>(SIMIX_context_self());
- workers_context_[worker_id] = worker_context;
-
- SIMIX_context_set_current(this);
- smx_ctx_boost_jump_fcontext(worker_context, this);
-}
-
-#endif
-