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();
-/* 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
return result.get();
}
+XBT_PUBLIC(const std::vector<smx_actor_t>&) process_get_runnable();
XBT_PUBLIC(void) set_maestro(std::function<void()> code);
XBT_PUBLIC(void) create_maestro(std::function<void()> code);
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<JavaContext*>(process->context)->resume();
}
}
-/* 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. */
// BoostContextFactory
-bool BoostContext::parallel_ = false;
-xbt_parmap_t BoostContext::parmap_ = nullptr;
-uintptr_t BoostContext::threads_working_ = 0;
+bool BoostContext::parallel_ = false;
+simgrid::xbt::Parmap<smx_actor_t>* 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*> BoostContext::workers_context_;
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<smx_actor_t>(nthreads, SIMIX_context_get_parallel_mode());
BoostContext::workers_context_.clear();
BoostContext::workers_context_.resize(nthreads, nullptr);
BoostContext::maestro_context_ = nullptr;
{
#if HAVE_THREAD_CONTEXTS
if (BoostContext::parmap_) {
- xbt_parmap_destroy(BoostContext::parmap_);
+ delete BoostContext::parmap_;
BoostContext::parmap_ = nullptr;
}
BoostContext::workers_context_.clear();
#if HAVE_THREAD_CONTEXTS
if (BoostContext::parallel_) {
BoostContext::threads_working_ = 0;
- xbt_parmap_apply(BoostContext::parmap_,
- [](void* arg) {
- smx_actor_t process = static_cast<smx_actor_t>(arg);
- BoostContext* context = static_cast<BoostContext*>(process->context);
- return context->resume();
- },
- simix_global->process_to_run);
+ BoostContext::parmap_->apply(
+ [](smx_actor_t process) {
+ BoostContext* context = static_cast<BoostContext*>(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<BoostContext*>(first_process->context)->resume();
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<BoostSerialContext*>(xbt_dynar_get_as(simix_global->process_to_run, i, smx_actor_t)->context);
+ next_context = static_cast<BoostSerialContext*>(simix_global->process_to_run[i]->context);
} else {
/* all processes were run, return to maestro */
XBT_DEBUG("No more process to run");
void BoostParallelContext::suspend()
{
- smx_actor_t next_work = static_cast<smx_actor_t>(xbt_parmap_next(parmap_));
- BoostParallelContext* next_context = nullptr;
-
- if (next_work != nullptr) {
+ boost::optional<smx_actor_t> next_work = parmap_->next();
+ BoostParallelContext* next_context;
+ if (next_work) {
XBT_DEBUG("Run next process");
- next_context = static_cast<BoostParallelContext*>(next_work->context);
+ next_context = static_cast<BoostParallelContext*>(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_);
-/* 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. */
#include <functional>
#include <vector>
-#include <xbt/parmap.h>
+#include <xbt/parmap.hpp>
#include <simgrid/simix.hpp>
class BoostContext : public Context {
protected: // static
static bool parallel_;
- static xbt_parmap_t parmap_;
+ static simgrid::xbt::Parmap<smx_actor_t>* parmap_;
static std::vector<BoostContext*> workers_context_;
static uintptr_t threads_working_;
static xbt_os_thread_key_t worker_id_key_;
#include "src/internal_config.h"
-#include "xbt/parmap.h"
+#include "xbt/parmap.hpp"
#include "src/simix/smx_private.h"
#include "mc/mc.h"
// ***** Loads of static stuff
#if HAVE_THREAD_CONTEXTS
-static xbt_parmap_t raw_parmap;
+static simgrid::xbt::Parmap<smx_actor_t>* 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 */
RawContextFactory::~RawContextFactory()
{
#if HAVE_THREAD_CONTEXTS
- if (raw_parmap)
- xbt_parmap_destroy(raw_parmap);
+ delete raw_parmap;
xbt_free(raw_workers_context);
#endif
}
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<RawContext*>(first_process->context)->resume_serial();
}
#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<smx_actor_t>(arg);
+ raw_parmap = new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
+ raw_parmap->apply(
+ [](smx_actor_t process) {
RawContext* context = static_cast<RawContext*>(process->context);
context->resume_parallel();
},
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<RawContext*>(xbt_dynar_get_as(simix_global->process_to_run, i, smx_actor_t)->context);
+ next_context = static_cast<RawContext*>(simix_global->process_to_run[i]->context);
} else {
/* all processes were run, return to maestro */
XBT_DEBUG("No more process to run");
{
#if HAVE_THREAD_CONTEXTS
/* determine the next context */
- smx_actor_t next_work = static_cast<smx_actor_t>(xbt_parmap_next(raw_parmap));
- RawContext* next_context = nullptr;
-
- if (next_work != nullptr) {
+ boost::optional<smx_actor_t> 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<RawContext*>(next_work->context);
+ next_context = static_cast<RawContext*>(next_work.get()->context);
} else {
/* all processes were run, go to the barrier */
XBT_DEBUG("No more processes to run");
/** @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<unsigned long>(SIMIX_context_get_parallel_threshold()) < nb_processes) {
raw_context_parallel = true;
{
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<ThreadContext*>(process->context);
xbt_os_sem_release(context->begin_);
}
} 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<ThreadContext*>(process->context)->begin_);
- xbt_dynar_foreach(simix_global->process_to_run, index, process)
- xbt_os_sem_acquire(static_cast<ThreadContext*>(process->context)->end_);
+ for (smx_actor_t process : simix_global->process_to_run)
+ xbt_os_sem_acquire(static_cast<ThreadContext*>(process->context)->end_);
}
}
#include <ucontext.h> /* 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
*
}}}
#if HAVE_THREAD_CONTEXTS
-static xbt_parmap_t sysv_parmap;
+static simgrid::xbt::Parmap<smx_actor_t>* 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 */
UContextFactory::~UContextFactory()
{
#if HAVE_THREAD_CONTEXTS
- if (sysv_parmap)
- xbt_parmap_destroy(sysv_parmap);
+ delete sysv_parmap;
xbt_free(sysv_workers_context);
#endif
}
// 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<ParallelUContext*>(process->context);
- context->resume();
- },
- simix_global->process_to_run);
+ sysv_parmap =
+ new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
+
+ sysv_parmap->apply(
+ [](smx_actor_t process) {
+ ParallelUContext* context = static_cast<ParallelUContext*>(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<SerialUContext*>(first_process->context);
context->resume();
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");
#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<smx_actor_t> 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<ParallelUContext*>(next_work.get()->context);
} else {
// All processes were run, go to the barrier
XBT_DEBUG("No more processes to run");
// 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:
#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);
/* 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 */
/* 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);
{
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) {
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);
}
}
boost::dynamic_pointer_cast<simgrid::kernel::activity::SleepImpl>(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);
}
}
}
/** @brief Returns the list of processes to run. */
-xbt_dynar_t SIMIX_process_get_runnable()
+const std::vector<smx_actor_t>& simgrid::simix::process_get_runnable()
{
return simix_global->process_to_run;
}
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);
}
}
#include <csignal> /* Signal handling */
#include <cstdlib>
+#include <xbt/algorithm.hpp>
#include <xbt/functional.hpp>
#include "simgrid/s4u/Engine.hpp"
simix_global = std::unique_ptr<simgrid::simix::Global>(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;
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.");
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;
}
}
-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()
{
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 */
* 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);
}
/* 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) {
#include <signal.h>
#include <map>
+#include <vector>
/********************************** Simix 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<smx_actor_t> process_to_run;
+ std::vector<smx_actor_t> process_that_ran;
std::map<aid_t, smx_actor_t> 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.