From e41d2dbe8c7406672257c3d37a2350882a380150 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Thu, 3 Aug 2017 13:56:50 +0200 Subject: [PATCH] Use std::vector instead of dynar in simix_global (process_{to_run,that_ran}). --- include/simgrid/simix.h | 1 - include/simgrid/simix.hpp | 3 +- src/bindings/java/JavaContext.cpp | 5 +-- src/kernel/context/ContextBoost.cpp | 47 ++++++++++++------------ src/kernel/context/ContextBoost.hpp | 6 ++-- src/kernel/context/ContextRaw.cpp | 35 ++++++++---------- src/kernel/context/ContextThread.cpp | 12 +++---- src/kernel/context/ContextUnix.cpp | 54 +++++++++++++--------------- src/mc/mc_base.cpp | 8 ++--- src/simix/ActorImpl.cpp | 24 +++++++------ src/simix/popping.cpp | 5 +-- src/simix/smx_global.cpp | 53 +++++++++++++-------------- src/simix/smx_private.h | 5 +-- 13 files changed, 116 insertions(+), 142 deletions(-) diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index 44e263529b..232564a0a1 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -72,7 +72,6 @@ extern int smx_context_guard_size_was_set; SG_BEGIN_DECL() -XBT_PUBLIC(xbt_dynar_t) SIMIX_process_get_runnable(); XBT_PUBLIC(smx_actor_t) SIMIX_process_from_PID(aid_t PID); XBT_PUBLIC(xbt_dynar_t) SIMIX_processes_as_dynar(); diff --git a/include/simgrid/simix.hpp b/include/simgrid/simix.hpp index eb7e26b88a..f21fa3d539 100644 --- a/include/simgrid/simix.hpp +++ b/include/simgrid/simix.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2010, 2012-2015. The SimGrid Team. +/* Copyright (c) 2007-2010, 2012-2017. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -69,6 +69,7 @@ typename std::result_of::type kernelImmediate(F&& code) return result.get(); } +XBT_PUBLIC(const std::vector&) process_get_runnable(); XBT_PUBLIC(void) set_maestro(std::function code); XBT_PUBLIC(void) create_maestro(std::function code); diff --git a/src/bindings/java/JavaContext.cpp b/src/bindings/java/JavaContext.cpp index e39a7b9740..c796b18c0d 100644 --- a/src/bindings/java/JavaContext.cpp +++ b/src/bindings/java/JavaContext.cpp @@ -47,10 +47,7 @@ JavaContext* JavaContextFactory::create_context( void JavaContextFactory::run_all() { - xbt_dynar_t processes = SIMIX_process_get_runnable(); - smx_actor_t process; - unsigned int cursor; - xbt_dynar_foreach(processes, cursor, process) { + for (smx_actor_t process : simgrid::simix::process_get_runnable()) { static_cast(process->context)->resume(); } } diff --git a/src/kernel/context/ContextBoost.cpp b/src/kernel/context/ContextBoost.cpp index a88920d898..3028445dd9 100644 --- a/src/kernel/context/ContextBoost.cpp +++ b/src/kernel/context/ContextBoost.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-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. */ @@ -49,12 +49,12 @@ public: // BoostContextFactory -bool BoostContext::parallel_ = false; -xbt_parmap_t BoostContext::parmap_ = nullptr; -uintptr_t BoostContext::threads_working_ = 0; +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; +unsigned long BoostContext::process_index_ = 0; +BoostContext* BoostContext::maestro_context_ = nullptr; std::vector BoostContext::workers_context_; BoostContextFactory::BoostContextFactory() @@ -64,7 +64,7 @@ BoostContextFactory::BoostContextFactory() if (BoostContext::parallel_) { #if HAVE_THREAD_CONTEXTS int nthreads = SIMIX_context_get_nthreads(); - BoostContext::parmap_ = xbt_parmap_new(nthreads, SIMIX_context_get_parallel_mode()); + BoostContext::parmap_ = new simgrid::xbt::Parmap(nthreads, SIMIX_context_get_parallel_mode()); BoostContext::workers_context_.clear(); BoostContext::workers_context_.resize(nthreads, nullptr); BoostContext::maestro_context_ = nullptr; @@ -79,7 +79,7 @@ BoostContextFactory::~BoostContextFactory() { #if HAVE_THREAD_CONTEXTS if (BoostContext::parmap_) { - xbt_parmap_destroy(BoostContext::parmap_); + delete BoostContext::parmap_; BoostContext::parmap_ = nullptr; } BoostContext::workers_context_.clear(); @@ -106,19 +106,18 @@ void BoostContextFactory::run_all() #if HAVE_THREAD_CONTEXTS if (BoostContext::parallel_) { BoostContext::threads_working_ = 0; - xbt_parmap_apply(BoostContext::parmap_, - [](void* arg) { - smx_actor_t process = static_cast(arg); - BoostContext* context = static_cast(process->context); - return context->resume(); - }, - simix_global->process_to_run); + BoostContext::parmap_->apply( + [](smx_actor_t process) { + BoostContext* context = static_cast(process->context); + return context->resume(); + }, + simix_global->process_to_run); } else #endif { - 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(); BoostContext::process_index_ = 1; /* execute the first process */ static_cast(first_process->context)->resume(); @@ -193,11 +192,10 @@ void BoostSerialContext::suspend() unsigned long int i = process_index_; process_index_++; - if (i < xbt_dynar_length(simix_global->process_to_run)) { + if (i < simix_global->process_to_run.size()) { /* execute the next process */ XBT_DEBUG("Run next process"); - next_context = - static_cast(xbt_dynar_get_as(simix_global->process_to_run, i, smx_actor_t)->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"); @@ -223,12 +221,11 @@ void BoostSerialContext::stop() void BoostParallelContext::suspend() { - smx_actor_t next_work = static_cast(xbt_parmap_next(parmap_)); - BoostParallelContext* next_context = nullptr; - - if (next_work != nullptr) { + boost::optional next_work = parmap_->next(); + BoostParallelContext* next_context; + if (next_work) { XBT_DEBUG("Run next process"); - next_context = static_cast(next_work->context); + next_context = static_cast(next_work.get()->context); } else { XBT_DEBUG("No more processes to run"); uintptr_t worker_id = (uintptr_t)xbt_os_thread_get_specific(worker_id_key_); diff --git a/src/kernel/context/ContextBoost.hpp b/src/kernel/context/ContextBoost.hpp index 578fe10932..e8a34c2229 100644 --- a/src/kernel/context/ContextBoost.hpp +++ b/src/kernel/context/ContextBoost.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-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. */ @@ -9,7 +9,7 @@ #include #include -#include +#include #include @@ -27,7 +27,7 @@ class BoostContextFactory; class BoostContext : public Context { protected: // static static bool parallel_; - static xbt_parmap_t parmap_; + static simgrid::xbt::Parmap* parmap_; static std::vector workers_context_; static uintptr_t threads_working_; static xbt_os_thread_key_t worker_id_key_; diff --git a/src/kernel/context/ContextRaw.cpp b/src/kernel/context/ContextRaw.cpp index 057d46e8da..53726aa300 100644 --- a/src/kernel/context/ContextRaw.cpp +++ b/src/kernel/context/ContextRaw.cpp @@ -5,7 +5,7 @@ #include "src/internal_config.h" -#include "xbt/parmap.h" +#include "xbt/parmap.hpp" #include "src/simix/smx_private.h" #include "mc/mc.h" @@ -73,7 +73,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 */ @@ -277,8 +277,7 @@ RawContextFactory::RawContextFactory() RawContextFactory::~RawContextFactory() { #if HAVE_THREAD_CONTEXTS - if (raw_parmap) - xbt_parmap_destroy(raw_parmap); + delete raw_parmap; xbt_free(raw_workers_context); #endif } @@ -337,11 +336,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(); } @@ -351,11 +349,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(); }, @@ -379,10 +375,10 @@ void RawContext::suspend_serial() RawContext* next_context = nullptr; unsigned long int i = raw_process_index; raw_process_index++; - if (i < xbt_dynar_length(simix_global->process_to_run)) { + if (i < simix_global->process_to_run.size()) { /* execute the next process */ XBT_DEBUG("Run next process"); - next_context = static_cast(xbt_dynar_get_as(simix_global->process_to_run, i, smx_actor_t)->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"); @@ -396,13 +392,12 @@ void RawContext::suspend_parallel() { #if HAVE_THREAD_CONTEXTS /* determine the next context */ - smx_actor_t next_work = static_cast(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 = static_cast(next_work->context); + next_context = static_cast(next_work.get()->context); } else { /* all processes were run, go to the barrier */ XBT_DEBUG("No more processes to run"); @@ -450,7 +445,7 @@ 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); + 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; diff --git a/src/kernel/context/ContextThread.cpp b/src/kernel/context/ContextThread.cpp index 85ac35a62a..4ed2f29012 100644 --- a/src/kernel/context/ContextThread.cpp +++ b/src/kernel/context/ContextThread.cpp @@ -58,9 +58,7 @@ void ThreadContextFactory::run_all() { if (smx_ctx_thread_sem == nullptr) { // Serial execution - smx_actor_t process; - unsigned int cursor; - xbt_dynar_foreach(simix_global->process_to_run, cursor, process) { + for (smx_actor_t process : simix_global->process_to_run) { XBT_DEBUG("Handling %p",process); ThreadContext* context = static_cast(process->context); xbt_os_sem_release(context->begin_); @@ -68,12 +66,10 @@ void ThreadContextFactory::run_all() } } else { // Parallel execution - unsigned int index; - smx_actor_t process; - xbt_dynar_foreach(simix_global->process_to_run, index, process) + for (smx_actor_t process : simix_global->process_to_run) xbt_os_sem_release(static_cast(process->context)->begin_); - xbt_dynar_foreach(simix_global->process_to_run, index, process) - xbt_os_sem_acquire(static_cast(process->context)->end_); + for (smx_actor_t process : simix_global->process_to_run) + xbt_os_sem_acquire(static_cast(process->context)->end_); } } diff --git a/src/kernel/context/ContextUnix.cpp b/src/kernel/context/ContextUnix.cpp index ac2a4b5fbe..036af58dca 100644 --- a/src/kernel/context/ContextUnix.cpp +++ b/src/kernel/context/ContextUnix.cpp @@ -7,12 +7,11 @@ #include /* context relative declarations */ -#include "src/simix/ActorImpl.hpp" -#include "src/simix/smx_private.h" -#include "xbt/parmap.h" #include "mc/mc.h" #include "src/mc/mc_ignore.h" - +#include "src/simix/ActorImpl.hpp" +#include "src/simix/smx_private.h" +#include "xbt/parmap.hpp" /** Many integers are needed to store a pointer * @@ -55,7 +54,7 @@ namespace context { }}} #if HAVE_THREAD_CONTEXTS -static xbt_parmap_t sysv_parmap; +static simgrid::xbt::Parmap* sysv_parmap; static simgrid::kernel::context::ParallelUContext** sysv_workers_context; /* space to save the worker's context in each thread */ static uintptr_t sysv_threads_working; /* number of threads that have started their work */ static xbt_os_thread_key_t sysv_worker_id_key; /* thread-specific storage for the thread id */ @@ -146,8 +145,7 @@ UContextFactory::UContextFactory() : ContextFactory("UContextFactory") UContextFactory::~UContextFactory() { #if HAVE_THREAD_CONTEXTS - if (sysv_parmap) - xbt_parmap_destroy(sysv_parmap); + delete sysv_parmap; xbt_free(sysv_workers_context); #endif } @@ -169,25 +167,24 @@ void UContextFactory::run_all() // with simix_global->context_factory (which might not be initialized // when bootstrapping): if (sysv_parmap == nullptr) - sysv_parmap = xbt_parmap_new( - SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode()); - - xbt_parmap_apply(sysv_parmap, - [](void* arg) { - smx_actor_t process = (smx_actor_t) arg; - ParallelUContext* context = static_cast(process->context); - context->resume(); - }, - simix_global->process_to_run); + sysv_parmap = + new simgrid::xbt::Parmap(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode()); + + sysv_parmap->apply( + [](smx_actor_t process) { + ParallelUContext* context = static_cast(process->context); + context->resume(); + }, + simix_global->process_to_run); #else xbt_die("You asked for a parallel execution, but you don't have any threads."); #endif } else { // 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(); sysv_process_index = 1; SerialUContext* context = static_cast(first_process->context); context->resume(); @@ -270,11 +267,10 @@ void SerialUContext::suspend() SerialUContext* next_context = nullptr; unsigned long int i = sysv_process_index++; - if (i < xbt_dynar_length(simix_global->process_to_run)) { + if (i < simix_global->process_to_run.size()) { /* execute the next process */ XBT_DEBUG("Run next process"); - next_context = (SerialUContext*) xbt_dynar_get_as( - simix_global->process_to_run,i, smx_actor_t)->context; + next_context = (SerialUContext*)simix_global->process_to_run[i]->context; } else { /* all processes were run, return to maestro */ XBT_DEBUG("No more process to run"); @@ -345,15 +341,12 @@ void ParallelUContext::suspend() #if HAVE_THREAD_CONTEXTS /* determine the next context */ // Get the next soul to embody now: - smx_actor_t next_work = (smx_actor_t) xbt_parmap_next(sysv_parmap); - ParallelUContext* next_context = nullptr; - // Will contain the next soul to run, either simulated or initial minion's one - ucontext_t* next_stack; - - if (next_work != nullptr) { + boost::optional next_work = sysv_parmap->next(); + ParallelUContext* next_context; + if (next_work) { // There is a next soul to embody (ie, a next process to resume) XBT_DEBUG("Run next process"); - next_context = (ParallelUContext*) next_work->context; + next_context = static_cast(next_work.get()->context); } else { // All processes were run, go to the barrier XBT_DEBUG("No more processes to run"); @@ -366,7 +359,8 @@ void ParallelUContext::suspend() // When given that soul, the body will wait for the next scheduling round } - next_stack = &next_context->uc_; + // Will contain the next soul to run, either simulated or initial minion's one + ucontext_t* next_stack = &next_context->uc_; SIMIX_context_set_current(next_context); // Get that next soul: diff --git a/src/mc/mc_base.cpp b/src/mc/mc_base.cpp index f3bc7d96e4..a12f15c1e7 100644 --- a/src/mc/mc_base.cpp +++ b/src/mc/mc_base.cpp @@ -35,13 +35,9 @@ void wait_for_requests() #if SIMGRID_HAVE_MC xbt_assert(mc_model_checker == nullptr, "This must be called from the client"); #endif - - smx_actor_t process; - unsigned int iter; - - while (not xbt_dynar_is_empty(simix_global->process_to_run)) { + while (not simix_global->process_to_run.empty()) { SIMIX_process_runall(); - xbt_dynar_foreach(simix_global->process_that_ran, iter, process) { + for (smx_actor_t process : simix_global->process_that_ran) { smx_simcall_t req = &process->simcall; if (req->call != SIMCALL_NONE && not simgrid::mc::request_is_visible(req)) SIMIX_simcall_handle(req, 0); diff --git a/src/simix/ActorImpl.cpp b/src/simix/ActorImpl.cpp index aac766fa14..e3f5d1db68 100644 --- a/src/simix/ActorImpl.cpp +++ b/src/simix/ActorImpl.cpp @@ -345,7 +345,7 @@ smx_actor_t SIMIX_process_create(const char* name, std::function code, v /* Now insert it in the global process list and in the process to run list */ simix_global->process_list[process->pid] = process; XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->getCname()); - xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process); + simix_global->process_to_run.push_back(process); intrusive_ptr_add_ref(process); /* Tracing the process creation */ @@ -409,7 +409,7 @@ smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostn /* Now insert it in the global process list and in the process to run list */ simix_global->process_list[process->pid] = process; XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->getCname()); - xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process); + simix_global->process_to_run.push_back(process); /* Tracing the process creation */ TRACE_msg_process_create(process->cname(), process->pid, process->host); @@ -453,10 +453,8 @@ void SIMIX_process_runall() { SIMIX_context_runall(); - xbt_dynar_t tmp = simix_global->process_that_ran; - simix_global->process_that_ran = simix_global->process_to_run; - simix_global->process_to_run = tmp; - xbt_dynar_reset(simix_global->process_to_run); + simix_global->process_to_run.swap(simix_global->process_that_ran); + simix_global->process_to_run.clear(); } void simcall_HANDLER_process_kill(smx_simcall_t simcall, smx_actor_t process) { @@ -524,9 +522,11 @@ void SIMIX_process_kill(smx_actor_t process, smx_actor_t issuer) { process->waiting_synchro = nullptr; } - if (not xbt_dynar_member(simix_global->process_to_run, &(process)) && process != issuer) { + if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) == + end(simix_global->process_to_run) && + process != issuer) { XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str()); - xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process); + simix_global->process_to_run.push_back(process); } } @@ -563,9 +563,11 @@ void SIMIX_process_throw(smx_actor_t process, xbt_errcat_t cat, int value, const boost::dynamic_pointer_cast(process->waiting_synchro); if (sleep != nullptr) { SIMIX_process_sleep_destroy(process->waiting_synchro); - if (not xbt_dynar_member(simix_global->process_to_run, &(process)) && process != SIMIX_process_self()) { + if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) == + end(simix_global->process_to_run) && + process != SIMIX_process_self()) { XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str()); - xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process); + simix_global->process_to_run.push_back(process); } } @@ -820,7 +822,7 @@ void SIMIX_process_exception_terminate(xbt_ex_t * e) } /** @brief Returns the list of processes to run. */ -xbt_dynar_t SIMIX_process_get_runnable() +const std::vector& simgrid::simix::process_get_runnable() { return simix_global->process_to_run; } diff --git a/src/simix/popping.cpp b/src/simix/popping.cpp index c4cb8aed30..91a79b1091 100644 --- a/src/simix/popping.cpp +++ b/src/simix/popping.cpp @@ -25,9 +25,10 @@ void SIMIX_simcall_answer(smx_simcall_t simcall) simcall->issuer->name.c_str(), simcall->issuer); simcall->issuer->simcall.call = SIMCALL_NONE; /* This check should be useless and slows everyone. Reactivate if you see something weird in process scheduling. */ - // if (xbt_dynar_member(simix_global->process_to_run, &(simcall->issuer))) + // if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), simcall->issuer) != + // end(simix_global->process_to_run)) // DIE_IMPOSSIBLE; - xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, simcall->issuer); + simix_global->process_to_run.push_back(simcall->issuer); } } diff --git a/src/simix/smx_global.cpp b/src/simix/smx_global.cpp index d00955b753..2aa1d17443 100644 --- a/src/simix/smx_global.cpp +++ b/src/simix/smx_global.cpp @@ -10,6 +10,7 @@ #include /* Signal handling */ #include +#include #include #include "simgrid/s4u/Engine.hpp" @@ -204,8 +205,6 @@ void SIMIX_global_init(int *argc, char **argv) simix_global = std::unique_ptr(new simgrid::simix::Global()); simgrid::simix::ActorImpl proc; - simix_global->process_to_run = xbt_dynar_new(sizeof(smx_actor_t), nullptr); - simix_global->process_that_ran = xbt_dynar_new(sizeof(smx_actor_t), nullptr); simix_global->process_to_destroy = xbt_swag_new(xbt_swag_offset(proc, destroy_hookup)); simix_global->maestro_process = nullptr; simix_global->create_process_function = &SIMIX_process_create; @@ -277,7 +276,7 @@ void SIMIX_clean() smx_cleaned = 1; XBT_DEBUG("SIMIX_clean called. Simulation's over."); - if (not xbt_dynar_is_empty(simix_global->process_to_run) && SIMIX_get_clock() <= 0.0) { + if (not simix_global->process_to_run.empty() && SIMIX_get_clock() <= 0.0) { XBT_CRITICAL(" "); XBT_CRITICAL("The time is still 0, and you still have processes ready to run."); XBT_CRITICAL("It seems that you forgot to run the simulation that you setup."); @@ -292,8 +291,8 @@ void SIMIX_clean() xbt_heap_free(simix_timers); simix_timers = nullptr; /* Free the remaining data structures */ - xbt_dynar_free(&simix_global->process_to_run); - xbt_dynar_free(&simix_global->process_that_ran); + simix_global->process_to_run.clear(); + simix_global->process_that_ran.clear(); xbt_swag_free(simix_global->process_to_destroy); simix_global->process_list.clear(); simix_global->process_to_destroy = nullptr; @@ -334,19 +333,6 @@ double SIMIX_get_clock() } } -static int process_syscall_color(void *p) -{ - switch ((*(smx_actor_t *)p)->simcall.call) { - case SIMCALL_NONE: - case SIMCALL_PROCESS_KILL: - return 2; - // case SIMCALL_PROCESS_RESUME: - // return 1; - default: - return 0; - } -} - /** Wake up all processes waiting for a Surf action to finish */ static void SIMIX_wake_processes() { @@ -429,18 +415,29 @@ void SIMIX_run() double time = 0; do { - XBT_DEBUG("New Schedule Round; size(queue)=%lu", xbt_dynar_length(simix_global->process_to_run)); + XBT_DEBUG("New Schedule Round; size(queue)=%zu", simix_global->process_to_run.size()); SIMIX_execute_tasks(); - while (not xbt_dynar_is_empty(simix_global->process_to_run)) { - XBT_DEBUG("New Sub-Schedule Round; size(queue)=%lu", xbt_dynar_length(simix_global->process_to_run)); + while (not simix_global->process_to_run.empty()) { + XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", simix_global->process_to_run.size()); /* Run all processes that are ready to run, possibly in parallel */ SIMIX_process_runall(); /* Move all killer processes to the end of the list, because killing a process that have an ongoing simcall is a bad idea */ - xbt_dynar_three_way_partition(simix_global->process_that_ran, process_syscall_color); + simgrid::xbt::three_way_partition(begin(simix_global->process_that_ran), end(simix_global->process_that_ran), + [](smx_actor_t p) { + switch (p->simcall.call) { + case SIMCALL_NONE: + case SIMCALL_PROCESS_KILL: + return 2; + // case SIMCALL_PROCESS_RESUME: + // return 1; + default: + return 0; + } + }); /* answer sequentially and in a fixed arbitrary order all the simcalls that were issued during that sub-round */ @@ -497,9 +494,7 @@ void SIMIX_run() * That would thus be a pure waste of time. */ - unsigned int iter; - smx_actor_t process; - xbt_dynar_foreach(simix_global->process_that_ran, iter, process) { + for (smx_actor_t process : simix_global->process_that_ran) { if (process->simcall.call != SIMCALL_NONE) { SIMIX_simcall_handle(&process->simcall, 0); } @@ -548,13 +543,13 @@ void SIMIX_run() /* Clean processes to destroy */ SIMIX_process_empty_trash(); - XBT_DEBUG("### time %f, #processes %zu, #to_run %lu", time, simix_global->process_list.size(), - xbt_dynar_length(simix_global->process_to_run)); + XBT_DEBUG("### time %f, #processes %zu, #to_run %zu", time, simix_global->process_list.size(), + simix_global->process_to_run.size()); - if (xbt_dynar_is_empty(simix_global->process_to_run) && not simix_global->process_list.empty()) + if (simix_global->process_to_run.empty() && not simix_global->process_list.empty()) simgrid::simix::onDeadlock(); - } while (time > -1.0 || not xbt_dynar_is_empty(simix_global->process_to_run)); + } while (time > -1.0 || not simix_global->process_to_run.empty()); if (simix_global->process_list.size() != 0) { diff --git a/src/simix/smx_private.h b/src/simix/smx_private.h index a0c713eba7..f10bf4d126 100644 --- a/src/simix/smx_private.h +++ b/src/simix/smx_private.h @@ -11,6 +11,7 @@ #include #include +#include /********************************** Simix Global ******************************/ @@ -22,8 +23,8 @@ class Global { public: smx_context_factory_t context_factory = nullptr; - xbt_dynar_t process_to_run = nullptr; - xbt_dynar_t process_that_ran = nullptr; + std::vector process_to_run; + std::vector process_that_ran; std::map process_list; #if SIMGRID_HAVE_MC /* MCer cannot read the std::map above in the remote process, so we copy the info it needs in a dynar. -- 2.20.1