From c93f29cd7a1453e10d8635f11e48cf0d537a83a2 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Fri, 20 Oct 2017 13:48:38 +0200 Subject: [PATCH] ContextBoost: cleanup in includes and cosmetic moves and renames. --- src/kernel/context/ContextBoost.cpp | 205 ++++++++++++---------------- src/kernel/context/ContextBoost.hpp | 68 +++++---- 2 files changed, 126 insertions(+), 147 deletions(-) diff --git a/src/kernel/context/ContextBoost.cpp b/src/kernel/context/ContextBoost.cpp index 3e1836237d..6a8beb7c37 100644 --- a/src/kernel/context/ContextBoost.cpp +++ b/src/kernel/context/ContextBoost.cpp @@ -3,20 +3,10 @@ /* 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 +#include "ContextBoost.hpp" -#include #include -#include - -#include - #include -#include - -#include "src/internal_config.h" -#include "src/kernel/context/ContextBoost.hpp" -#include "src/simix/smx_private.hpp" #if HAVE_SANITIZE_ADDRESS_FIBER_SUPPORT #include @@ -36,37 +26,8 @@ namespace simgrid { namespace kernel { namespace context { -class BoostSerialContext : public BoostContext { -public: - BoostSerialContext(std::function code, - void_pfn_smxprocess_t cleanup_func, - smx_actor_t process) - : BoostContext(std::move(code), cleanup_func, process) {} - void suspend() override; -}; - -#if HAVE_THREAD_CONTEXTS -class BoostParallelContext : public BoostContext { -public: - BoostParallelContext(std::function code, - void_pfn_smxprocess_t cleanup_func, - smx_actor_t process) - : BoostContext(std::move(code), cleanup_func, process) {} - void suspend() override; - void resume() override; -}; -#endif - // BoostContextFactory -bool BoostContext::parallel_ = false; -simgrid::xbt::Parmap* BoostContext::parmap_ = nullptr; -uintptr_t BoostContext::threads_working_ = 0; -xbt_os_thread_key_t BoostContext::worker_id_key_; -unsigned long BoostContext::process_index_ = 0; -BoostContext* BoostContext::maestro_context_ = nullptr; -std::vector BoostContext::workers_context_; - BoostContextFactory::BoostContextFactory() : ContextFactory("BoostContextFactory") { @@ -96,16 +57,12 @@ BoostContextFactory::~BoostContextFactory() smx_context_t BoostContextFactory::create_context(std::function code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process) { - BoostContext* context = nullptr; - if (BoostContext::parallel_) #if HAVE_THREAD_CONTEXTS - context = this->new_context(std::move(code), cleanup_func, process); -#else - xbt_die("No support for parallel execution"); + if (BoostContext::parallel_) + return this->new_context(std::move(code), cleanup_func, process); #endif - else - context = this->new_context(std::move(code), cleanup_func, process); - return context; + + return this->new_context(std::move(code), cleanup_func, process); } void BoostContextFactory::run_all() @@ -122,68 +79,38 @@ void BoostContextFactory::run_all() return context->resume(); }, simix_global->process_to_run); - } else -#endif - { - if (simix_global->process_to_run.empty()) - return; - smx_actor_t first_process = simix_global->process_to_run.front(); - BoostContext::process_index_ = 1; - /* execute the first process */ - static_cast(first_process->context)->resume(); + return; } +#endif + + if (simix_global->process_to_run.empty()) + return; + smx_actor_t first_process = simix_global->process_to_run.front(); + BoostContext::process_index_ = 1; + /* execute the first process */ + static_cast(first_process->context)->resume(); } // BoostContext -void BoostContext::smx_ctx_boost_wrapper(BoostContext::ctx_arg_type arg) -{ -#if BOOST_VERSION < 106100 - BoostContext* context = reinterpret_cast(arg); -#else - ASAN_FINISH_SWITCH(nullptr, &static_cast(arg.data)[0]->asan_stack_, - &static_cast(arg.data)[0]->asan_stack_size_); - static_cast(arg.data)[0]->fc_ = arg.fctx; - BoostContext* context = static_cast(arg.data)[1]; -#endif - try { - (*context)(); - context->Context::stop(); - } catch (StopRequest const&) { - XBT_DEBUG("Caught a StopRequest"); - } - ASAN_EVAL(context->asan_stop_ = true); - context->suspend(); -} - -inline void BoostContext::smx_ctx_boost_jump_fcontext(BoostContext* from, BoostContext* to) -{ -#if BOOST_VERSION < 105600 - boost::context::jump_fcontext(from->fc_, to->fc_, reinterpret_cast(to)); -#elif BOOST_VERSION < 106100 - boost::context::jump_fcontext(&from->fc_, to->fc_, reinterpret_cast(to)); -#else - BoostContext* ctx[2] = {from, to}; - void* fake_stack; - ASAN_START_SWITCH(from->asan_stop_ ? nullptr : &fake_stack, to->asan_stack_, to->asan_stack_size_); - boost::context::detail::transfer_t arg = boost::context::detail::jump_fcontext(to->fc_, ctx); - ASAN_FINISH_SWITCH(fake_stack, &static_cast(arg.data)[0]->asan_stack_, - &static_cast(arg.data)[0]->asan_stack_size_); - static_cast(arg.data)[0]->fc_ = arg.fctx; -#endif -} +bool BoostContext::parallel_ = false; +simgrid::xbt::Parmap* BoostContext::parmap_ = nullptr; +uintptr_t BoostContext::threads_working_ = 0; +xbt_os_thread_key_t BoostContext::worker_id_key_; +unsigned long BoostContext::process_index_ = 0; +BoostContext* BoostContext::maestro_context_ = nullptr; +std::vector BoostContext::workers_context_; -BoostContext::BoostContext(std::function code, - void_pfn_smxprocess_t cleanup_func, smx_actor_t process) - : Context(std::move(code), cleanup_func, process) +BoostContext::BoostContext(std::function 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: + /* 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(this->stack_) + smx_context_usable_stack_size; #else @@ -191,9 +118,9 @@ BoostContext::BoostContext(std::function code, #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); + this->fc_ = boost::context::make_fcontext(stack, smx_context_usable_stack_size, BoostContext::wrapper); #else - this->fc_ = boost::context::detail::make_fcontext(stack, smx_context_usable_stack_size, smx_ctx_boost_wrapper); + this->fc_ = boost::context::detail::make_fcontext(stack, smx_context_usable_stack_size, BoostContext::wrapper); #endif } else { #if BOOST_VERSION < 105600 @@ -215,7 +142,42 @@ BoostContext::~BoostContext() SIMIX_context_stack_delete(this->stack_); } -// BoostSerialContext +void BoostContext::wrapper(BoostContext::arg_type arg) +{ +#if BOOST_VERSION < 106100 + BoostContext* context = reinterpret_cast(arg); +#else + ASAN_FINISH_SWITCH(nullptr, &static_cast(arg.data)[0]->asan_stack_, + &static_cast(arg.data)[0]->asan_stack_size_); + static_cast(arg.data)[0]->fc_ = arg.fctx; + BoostContext* context = static_cast(arg.data)[1]; +#endif + try { + (*context)(); + context->Context::stop(); + } catch (StopRequest const&) { + XBT_DEBUG("Caught a StopRequest"); + } + ASAN_EVAL(context->asan_stop_ = true); + context->suspend(); +} + +inline void BoostContext::swap(BoostContext* from, BoostContext* to) +{ +#if BOOST_VERSION < 105600 + boost::context::jump_fcontext(from->fc_, to->fc_, reinterpret_cast(to)); +#elif BOOST_VERSION < 106100 + boost::context::jump_fcontext(&from->fc_, to->fc_, reinterpret_cast(to)); +#else + BoostContext* ctx[2] = {from, to}; + void* fake_stack; + ASAN_START_SWITCH(from->asan_stop_ ? nullptr : &fake_stack, to->asan_stack_, to->asan_stack_size_); + boost::context::detail::transfer_t arg = boost::context::detail::jump_fcontext(to->fc_, ctx); + ASAN_FINISH_SWITCH(fake_stack, &static_cast(arg.data)[0]->asan_stack_, + &static_cast(arg.data)[0]->asan_stack_size_); + static_cast(arg.data)[0]->fc_ = arg.fctx; +#endif +} void BoostContext::stop() { @@ -223,63 +185,65 @@ void BoostContext::stop() throw StopRequest(); } -void BoostContext::resume() -{ - SIMIX_context_set_current(this); - smx_ctx_boost_jump_fcontext(maestro_context_, this); -} +// SerialBoostContext -void BoostSerialContext::suspend() +void SerialBoostContext::suspend() { /* determine the next context */ - BoostSerialContext* next_context; + SerialBoostContext* 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(simix_global->process_to_run[i]->context); + next_context = static_cast(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(maestro_context_); + next_context = static_cast(maestro_context_); } SIMIX_context_set_current(static_cast(next_context)); - smx_ctx_boost_jump_fcontext(this, next_context); + BoostContext::swap(this, next_context); +} + +void SerialBoostContext::resume() +{ + SIMIX_context_set_current(this); + BoostContext::swap(maestro_context_, this); } -// BoostParallelContext +// ParallelBoostContext #if HAVE_THREAD_CONTEXTS -void BoostParallelContext::suspend() +void ParallelBoostContext::suspend() { boost::optional next_work = parmap_->next(); - BoostParallelContext* next_context; + ParallelBoostContext* next_context; if (next_work) { XBT_DEBUG("Run next process"); - next_context = static_cast(next_work.get()->context); + next_context = static_cast(next_work.get()->context); } else { XBT_DEBUG("No more processes to run"); uintptr_t worker_id = reinterpret_cast(xbt_os_thread_get_specific(worker_id_key_)); - next_context = static_cast(workers_context_[worker_id]); + next_context = static_cast(workers_context_[worker_id]); } SIMIX_context_set_current(static_cast(next_context)); - smx_ctx_boost_jump_fcontext(this, next_context); + BoostContext::swap(this, next_context); } -void BoostParallelContext::resume() +void ParallelBoostContext::resume() { uintptr_t worker_id = __sync_fetch_and_add(&threads_working_, 1); xbt_os_thread_set_specific(worker_id_key_, reinterpret_cast(worker_id)); - BoostParallelContext* worker_context = static_cast(SIMIX_context_self()); + ParallelBoostContext* worker_context = static_cast(SIMIX_context_self()); workers_context_[worker_id] = worker_context; SIMIX_context_set_current(this); - smx_ctx_boost_jump_fcontext(worker_context, this); + BoostContext::swap(worker_context, this); } #endif @@ -289,5 +253,4 @@ XBT_PRIVATE ContextFactory* boost_factory() XBT_VERB("Using Boost contexts. Welcome to the 21th century."); return new BoostContextFactory(); } - }}} // namespace diff --git a/src/kernel/context/ContextBoost.hpp b/src/kernel/context/ContextBoost.hpp index f1261db402..a816fe62ba 100644 --- a/src/kernel/context/ContextBoost.hpp +++ b/src/kernel/context/ContextBoost.hpp @@ -6,27 +6,27 @@ #ifndef SIMGRID_SIMIX_BOOST_CONTEXT_HPP #define SIMGRID_SIMIX_BOOST_CONTEXT_HPP -#include -#if BOOST_VERSION < 106100 -#include -#else -#include -#endif +#include + +#include #include #include -#include - #include +#include +#include +#include "Context.hpp" +#include "src/internal_config.h" +#include "src/simix/smx_private.hpp" namespace simgrid { namespace kernel { namespace context { class BoostContext; -class BoostSerialContext; -class BoostParallelContext; +class SerialBoostContext; +class ParallelBoostContext; class BoostContextFactory; /** @brief Userspace context switching implementation based on Boost.Context */ @@ -42,16 +42,16 @@ protected: // static #if BOOST_VERSION < 105600 boost::context::fcontext_t* fc_ = nullptr; - typedef intptr_t ctx_arg_type; + typedef intptr_t arg_type; #elif BOOST_VERSION < 106100 boost::context::fcontext_t fc_; - typedef intptr_t ctx_arg_type; + typedef intptr_t arg_type; #else boost::context::detail::fcontext_t fc_; - typedef boost::context::detail::transfer_t ctx_arg_type; + typedef boost::context::detail::transfer_t arg_type; #endif - static void smx_ctx_boost_wrapper(ctx_arg_type); - static void smx_ctx_boost_jump_fcontext(BoostContext*, BoostContext*); + static void wrapper(arg_type arg); + static void swap(BoostContext* from, BoostContext* to); #if HAVE_SANITIZE_ADDRESS_FIBER_SUPPORT const void* asan_stack_ = nullptr; @@ -61,25 +61,41 @@ protected: // static void* stack_ = nullptr; public: - friend BoostContextFactory; - BoostContext(std::function code, - void_pfn_smxprocess_t cleanup_func, - smx_actor_t process); + BoostContext(std::function code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process); ~BoostContext() override; void stop() override; - virtual void resume(); + virtual void resume() = 0; + + friend BoostContextFactory; }; -class BoostContextFactory : public ContextFactory { +class SerialBoostContext : public BoostContext { +public: + SerialBoostContext(std::function code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process) + : BoostContext(std::move(code), cleanup_func, process) + { + } + void suspend() override; + void resume() override; +}; + +#if HAVE_THREAD_CONTEXTS +class ParallelBoostContext : public BoostContext { public: - friend BoostContext; - friend BoostSerialContext; - friend BoostParallelContext; + ParallelBoostContext(std::function code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process) + : BoostContext(std::move(code), cleanup_func, process) + { + } + void suspend() override; + void resume() override; +}; +#endif +class BoostContextFactory : public ContextFactory { +public: BoostContextFactory(); ~BoostContextFactory() override; - Context* create_context(std::function code, - void_pfn_smxprocess_t, smx_actor_t process) override; + Context* create_context(std::function code, void_pfn_smxprocess_t, smx_actor_t process) override; void run_all() override; }; -- 2.20.1