X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/8e7feffef5e41a487cc322c68265c09cc0d7bdf2..ccf671a80a47f0489c33fb1dc2a8aadfc28b5b88:/src/kernel/context/ContextSwapped.cpp diff --git a/src/kernel/context/ContextSwapped.cpp b/src/kernel/context/ContextSwapped.cpp index e6e6a7bf00..bd913fb87c 100644 --- a/src/kernel/context/ContextSwapped.cpp +++ b/src/kernel/context/ContextSwapped.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2020. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2021. The SimGrid Team. All rights reserved. */ /* 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. */ @@ -12,6 +12,9 @@ #include "src/kernel/context/ContextSwapped.hpp" +#include +#include + #ifdef _WIN32 #include #include @@ -30,6 +33,9 @@ #if HAVE_SANITIZER_ADDRESS_FIBER_SUPPORT #include #endif +#if HAVE_SANITIZER_THREAD_FIBER_SUPPORT +#include +#endif XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context); @@ -46,7 +52,7 @@ void smx_ctx_wrapper(simgrid::kernel::context::SwappedContext* context) } catch (simgrid::ForcefulKillException const&) { XBT_DEBUG("Caught a ForcefulKillException"); } catch (simgrid::Exception const& e) { - XBT_INFO("Actor killed by an uncaught exception %s", simgrid::xbt::demangle(typeid(e).name()).get()); + XBT_INFO("Actor killed by an uncaught exception %s", boost::core::demangle(typeid(e).name()).c_str()); throw; } #if HAVE_SANITIZER_ADDRESS_FIBER_SUPPORT @@ -66,12 +72,12 @@ thread_local SwappedContext* SwappedContext::worker_context_ = nullptr; SwappedContext::SwappedContext(std::function&& code, smx_actor_t actor, SwappedContextFactory* factory) : Context(std::move(code), actor), factory_(*factory) { - // Save maestro (=context created first) in preparation for run_all + // Save maestro (=first created context) in preparation for run_all if (not SIMIX_context_is_parallel() && factory_.maestro_context_ == nullptr) factory_.maestro_context_ = this; if (has_code()) { - xbt_assert((smx_context_stack_size & 0xf) == 0, "smx_context_stack_size should be multiple of 16"); + xbt_assert((actor->get_stacksize() & 0xf) == 0, "Actor stack size should be multiple of 16"); if (smx_context_guard_size > 0 && not MC_is_active()) { #if PTH_STACKGROWTH != -1 xbt_die( @@ -82,11 +88,11 @@ SwappedContext::SwappedContext(std::function&& code, smx_actor_t actor, * Protected pages need to be put after the stack when PTH_STACKGROWTH == 1. */ #endif - size_t size = smx_context_stack_size + smx_context_guard_size; + size_t size = actor->get_stacksize() + smx_context_guard_size; #if SIMGRID_HAVE_MC /* Cannot use posix_memalign when SIMGRID_HAVE_MC. Align stack by hand, and save the * pointer returned by xbt_malloc0. */ - unsigned char* alloc = static_cast(xbt_malloc0(size + xbt_pagesize)); + auto* alloc = static_cast(xbt_malloc0(size + xbt_pagesize)); stack_ = alloc - (reinterpret_cast(alloc) & (xbt_pagesize - 1)) + xbt_pagesize; reinterpret_cast(stack_)[-1] = alloc; #elif !defined(_WIN32) @@ -113,15 +119,23 @@ SwappedContext::SwappedContext(std::function&& code, smx_actor_t actor, #endif this->stack_ = this->stack_ + smx_context_guard_size; } else { - this->stack_ = static_cast(xbt_malloc0(smx_context_stack_size)); + this->stack_ = static_cast(xbt_malloc0(actor->get_stacksize())); } #if HAVE_VALGRIND_H if (RUNNING_ON_VALGRIND) - this->valgrind_stack_id_ = VALGRIND_STACK_REGISTER(this->stack_, this->stack_ + smx_context_stack_size); + this->valgrind_stack_id_ = VALGRIND_STACK_REGISTER(this->stack_, this->stack_ + actor->get_stacksize()); #endif #if HAVE_SANITIZER_ADDRESS_FIBER_SUPPORT this->asan_stack_ = get_stack_bottom(); +#endif +#if HAVE_SANITIZER_THREAD_FIBER_SUPPORT + this->tsan_fiber_ = __tsan_create_fiber(0); +#endif + } else { + // not has_code(): in maestro context +#if HAVE_SANITIZER_THREAD_FIBER_SUPPORT + this->tsan_fiber_ = __tsan_get_current_fiber(); #endif } } @@ -131,6 +145,9 @@ SwappedContext::~SwappedContext() if (stack_ == nullptr) // maestro has no extra stack return; +#if HAVE_SANITIZER_THREAD_FIBER_SUPPORT + __tsan_destroy_fiber(tsan_fiber_); +#endif #if HAVE_VALGRIND_H if (RUNNING_ON_VALGRIND) VALGRIND_STACK_DEREGISTER(valgrind_stack_id_); @@ -153,6 +170,16 @@ SwappedContext::~SwappedContext() xbt_free(stack_); } +unsigned char* SwappedContext::get_stack_bottom() const +{ + // Depending on the stack direction, its bottom (that make_fcontext needs) may be the lower or higher end +#if PTH_STACKGROWTH == 1 + return stack_; +#else + return stack_ + get_actor()->get_stacksize(); +#endif +} + void SwappedContext::stop() { Context::stop(); @@ -167,6 +194,9 @@ void SwappedContext::swap_into(SwappedContext* to) to->asan_ctx_ = this; __sanitizer_start_switch_fiber(this->asan_stop_ ? nullptr : &fake_stack, to->asan_stack_, to->asan_stack_size_); #endif +#if HAVE_SANITIZER_THREAD_FIBER_SUPPORT + __tsan_switch_to_fiber(to->tsan_fiber_, 0); +#endif swap_into_for_real(to); @@ -185,8 +215,8 @@ void SwappedContextFactory::run_all() if (SIMIX_context_is_parallel()) { // We lazily create the parmap so that all options are actually processed when doing so. if (parmap_ == nullptr) - parmap_.reset( - new simgrid::xbt::Parmap(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode())); + parmap_ = std::make_unique>(SIMIX_context_get_nthreads(), + SIMIX_context_get_parallel_mode()); // Usually, Parmap::apply() executes the provided function on all elements of the array. // Here, the executed function does not return the control to the parmap before all the array is processed: @@ -196,7 +226,7 @@ void SwappedContextFactory::run_all() // - So, resume() is only launched from the parmap for the first job of each minion. parmap_->apply( [](const actor::ActorImpl* process) { - SwappedContext* context = static_cast(process->context_.get()); + auto* context = static_cast(process->context_.get()); context->resume(); }, simix_global->actors_to_run); @@ -220,7 +250,7 @@ void SwappedContextFactory::run_all() */ void SwappedContext::resume() { - SwappedContext* old = static_cast(self()); + auto* old = static_cast(self()); if (SIMIX_context_is_parallel()) { // Save my current soul (either maestro, or one of the minions) in a thread-specific area worker_context_ = old;