From: Arnaud Giersch Date: Tue, 21 May 2019 20:15:25 +0000 (+0200) Subject: Save worker's context directly in TLS. X-Git-Tag: v3.22.4~83 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/955310e4fe48139407cabfd6cae815a287932291 Save worker's context directly in TLS. --- diff --git a/src/kernel/context/ContextSwapped.cpp b/src/kernel/context/ContextSwapped.cpp index 9263c633df..fbecf2b664 100644 --- a/src/kernel/context/ContextSwapped.cpp +++ b/src/kernel/context/ContextSwapped.cpp @@ -35,21 +35,20 @@ namespace simgrid { namespace kernel { namespace context { -/* rank of the execution thread */ -thread_local uintptr_t SwappedContext::worker_id_; /* thread-specific storage for the thread id */ +/* thread-specific storage for the worker's context */ +thread_local SwappedContext* SwappedContext::worker_context_ = nullptr; SwappedContextFactory::SwappedContextFactory() : ContextFactory(), parallel_(SIMIX_context_is_parallel()) { parmap_ = nullptr; // will be created lazily with the right parameters if needed (ie, in parallel) - workers_context_.resize(parallel_ ? SIMIX_context_get_nthreads() : 1, 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 - if (not factory->parallel_ && factory_->workers_context_[0] == nullptr) - factory_->workers_context_[0] = this; + if (not factory->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"); @@ -157,8 +156,6 @@ void SwappedContextFactory::run_all() * for the ones of the simulated processes that must run. */ if (parallel_) { - threads_working_ = 0; - // We lazily create the parmap so that all options are actually processed when doing so. if (parmap_ == nullptr) parmap_.reset( @@ -197,14 +194,11 @@ void SwappedContextFactory::run_all() void SwappedContext::resume() { if (factory_->parallel_) { - // Save the thread number (my body) in an os-thread-specific area - worker_id_ = factory_->threads_working_.fetch_add(1, std::memory_order_relaxed); - // Save my current soul (either maestro, or one of the minions) in a permanent area - SwappedContext* worker_context = static_cast(self()); - factory_->workers_context_[worker_id_] = worker_context; + // Save my current soul (either maestro, or one of the minions) in a thread-specific area + worker_context_ = static_cast(self()); // Switch my soul and the actor's one Context::set_current(this); - worker_context->swap_into(this); + worker_context_->swap_into(this); // No body runs that soul anymore at this point, but it is stored in a safe place. // When the executed actor will do a blocking action, ActorImpl::yield() will call suspend(), below. } else { // sequential execution @@ -235,8 +229,8 @@ void SwappedContext::suspend() } else { // All actors were run, go back to the parmap context XBT_DEBUG("No more actors to run"); - // worker_id_ is the identity of my body, stored in thread_local when starting the scheduling round - next_context = factory_->workers_context_[worker_id_]; + // worker_context_ is my own soul, stored in thread_local when starting the scheduling round + next_context = worker_context_; // When given that soul, the body will wait for the next scheduling round } @@ -257,7 +251,7 @@ void SwappedContext::suspend() } else { /* all processes were run, actually return to maestro */ XBT_DEBUG("No more actors to run"); - next_context = factory_->workers_context_[0]; + next_context = factory_->maestro_context_; } Context::set_current(next_context); this->swap_into(next_context); diff --git a/src/kernel/context/ContextSwapped.hpp b/src/kernel/context/ContextSwapped.hpp index c132b63f81..8380fa001e 100644 --- a/src/kernel/context/ContextSwapped.hpp +++ b/src/kernel/context/ContextSwapped.hpp @@ -27,12 +27,12 @@ public: private: bool parallel_; - unsigned long process_index_ = 0; // Next actor to execute during sequential run_all() + /* For the sequential execution */ + unsigned long process_index_ = 0; // next actor to execute + SwappedContext* maestro_context_ = nullptr; // save maestro's context /* For the parallel execution */ std::unique_ptr> parmap_; - std::vector workers_context_; /* space to save the worker's context in each thread */ - std::atomic threads_working_{0}; /* number of threads that have started their work */ }; class SwappedContext : public Context { @@ -50,7 +50,7 @@ public: unsigned char* get_stack(); - static thread_local uintptr_t worker_id_; + static thread_local SwappedContext* worker_context_; #if HAVE_SANITIZER_ADDRESS_FIBER_SUPPORT const void* asan_stack_ = nullptr;