X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/10ceac5fd14fb0426b5c93bda85676a79b02d0be..c93f29cd7a1453e10d8635f11e48cf0d537a83a2:/src/kernel/context/ContextRaw.cpp diff --git a/src/kernel/context/ContextRaw.cpp b/src/kernel/context/ContextRaw.cpp index 2d87f6bf94..5695d19728 100644 --- a/src/kernel/context/ContextRaw.cpp +++ b/src/kernel/context/ContextRaw.cpp @@ -1,22 +1,14 @@ -/* Copyright (c) 2009-2015. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2009-2017. 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. */ -#include +#include "src/internal_config.h" -#include -#include +#include "xbt/parmap.hpp" -#include "src/internal_config.h" - -#include "xbt/log.h" -#include "xbt/parmap.h" -#include "xbt/dynar.h" - -#include "src/simix/smx_private.h" #include "mc/mc.h" +#include "src/simix/smx_private.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context); @@ -31,21 +23,22 @@ class RawContextFactory; /** @brief Fast context switching inspired from SystemV ucontexts. * - * The main difference to the System V context is that Raw Contexts are much faster because they don't + * The main difference to the System V context is that Raw Contexts are much faster because they don't * preserve the signal mask when switching. This saves a system call (at least on Linux) on each context switch. */ class RawContext : public Context { -protected: - void* stack_ = nullptr; +private: + void* stack_ = nullptr; /** pointer to top the stack stack */ void* stack_top_ = nullptr; + public: friend class RawContextFactory; RawContext(std::function code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process); ~RawContext() override; -public: + static void wrapper(void* arg); void stop() override; void suspend() override; @@ -81,7 +74,7 @@ ContextFactory* raw_factory() // ***** Loads of static stuff #if HAVE_THREAD_CONTEXTS -static xbt_parmap_t raw_parmap; +static simgrid::xbt::Parmap* raw_parmap; static simgrid::kernel::context::RawContext** raw_workers_context; /* space to save the worker context in each thread */ static uintptr_t raw_threads_working; /* number of threads that have started their work */ static xbt_os_thread_key_t raw_worker_id_key; /* thread-specific storage for the thread id */ @@ -275,34 +268,37 @@ RawContextFactory::RawContextFactory() xbt_os_thread_key_create(&raw_worker_id_key); // TODO, lazily init raw_parmap = nullptr; - raw_workers_context = xbt_new(RawContext*, nthreads); + raw_workers_context = new RawContext*[nthreads]; raw_maestro_context = nullptr; #endif - // TODO, if(SIMIX_context_get_parallel_threshold() > 1) => choose dynamically + // TODO: choose dynamically when SIMIX_context_get_parallel_threshold() > 1 } } RawContextFactory::~RawContextFactory() { #if HAVE_THREAD_CONTEXTS - if (raw_parmap) - xbt_parmap_destroy(raw_parmap); - xbt_free(raw_workers_context); + delete raw_parmap; + delete[] raw_workers_context; #endif } RawContext* RawContextFactory::create_context(std::function code, void_pfn_smxprocess_t cleanup, smx_actor_t process) { - return this->new_context(std::move(code), - cleanup, process); + return this->new_context(std::move(code), cleanup, process); } void RawContext::wrapper(void* arg) { - RawContext* context = (RawContext*) arg; - (*context)(); - context->stop(); + RawContext* context = static_cast(arg); + try { + (*context)(); + context->Context::stop(); + } catch (StopRequest const&) { + XBT_DEBUG("Caught a StopRequest"); + } + context->suspend(); } RawContext::RawContext(std::function code, @@ -333,7 +329,7 @@ RawContext::~RawContext() void RawContext::stop() { Context::stop(); - this->suspend(); + throw StopRequest(); } void RawContextFactory::run_all() @@ -346,11 +342,10 @@ void RawContextFactory::run_all() void RawContextFactory::run_all_serial() { - if (xbt_dynar_is_empty(simix_global->process_to_run)) + if (simix_global->process_to_run.empty()) return; - smx_actor_t first_process = - xbt_dynar_get_as(simix_global->process_to_run, 0, smx_actor_t); + smx_actor_t first_process = simix_global->process_to_run.front(); raw_process_index = 1; static_cast(first_process->context)->resume_serial(); } @@ -360,11 +355,9 @@ void RawContextFactory::run_all_parallel() #if HAVE_THREAD_CONTEXTS raw_threads_working = 0; if (raw_parmap == nullptr) - raw_parmap = xbt_parmap_new( - SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode()); - xbt_parmap_apply(raw_parmap, - [](void* arg) { - smx_actor_t process = static_cast(arg); + raw_parmap = new simgrid::xbt::Parmap(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode()); + raw_parmap->apply( + [](smx_actor_t process) { RawContext* context = static_cast(process->context); context->resume_parallel(); }, @@ -386,18 +379,16 @@ void RawContext::suspend_serial() { /* determine the next context */ RawContext* next_context = nullptr; - unsigned long int i; - i = raw_process_index++; - if (i < xbt_dynar_length(simix_global->process_to_run)) { + 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 = (RawContext*) xbt_dynar_get_as( - simix_global->process_to_run, i, smx_actor_t)->context; - } - else { + 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 = (RawContext*) raw_maestro_context; + next_context = static_cast(raw_maestro_context); } SIMIX_context_set_current(next_context); raw_swapcontext(&this->stack_top_, next_context->stack_top_); @@ -407,20 +398,18 @@ void RawContext::suspend_parallel() { #if HAVE_THREAD_CONTEXTS /* determine the next context */ - smx_actor_t next_work = (smx_actor_t) xbt_parmap_next(raw_parmap); - RawContext* next_context = nullptr; - - if (next_work != nullptr) { + boost::optional 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 = (RawContext*) next_work->context; - } - else { + next_context = static_cast(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 = (RawContext*) raw_workers_context[worker_id]; + next_context = raw_workers_context[worker_id]; XBT_DEBUG("Restoring worker stack %zu (working threads = %zu)", worker_id, raw_threads_working); } @@ -449,7 +438,7 @@ void RawContext::resume_parallel() #if HAVE_THREAD_CONTEXTS uintptr_t worker_id = __sync_fetch_and_add(&raw_threads_working, 1); xbt_os_thread_set_specific(raw_worker_id_key, (void*) worker_id); - RawContext* worker_context = (RawContext*) SIMIX_context_self(); + RawContext* worker_context = static_cast(SIMIX_context_self()); raw_workers_context[worker_id] = worker_context; XBT_DEBUG("Saving worker stack %zu", worker_id); SIMIX_context_set_current(this); @@ -462,17 +451,17 @@ void RawContext::resume_parallel() /** @brief Resumes all processes ready to run. */ void RawContextFactory::run_all_adaptative() { - unsigned long nb_processes = xbt_dynar_length(simix_global->process_to_run); - if (SIMIX_context_is_parallel() - && (unsigned long) SIMIX_context_get_parallel_threshold() < nb_processes) { - raw_context_parallel = true; - XBT_DEBUG("Runall // %lu", nb_processes); - this->run_all_parallel(); - } else { - XBT_DEBUG("Runall serial %lu", nb_processes); - raw_context_parallel = false; - this->run_all_serial(); - } + unsigned long nb_processes = simix_global->process_to_run.size(); + if (SIMIX_context_is_parallel() && + static_cast(SIMIX_context_get_parallel_threshold()) < nb_processes) { + raw_context_parallel = true; + XBT_DEBUG("Runall // %lu", nb_processes); + this->run_all_parallel(); + } else { + XBT_DEBUG("Runall serial %lu", nb_processes); + raw_context_parallel = false; + this->run_all_serial(); + } } }}}