From 51d099097598a993323850816311d3f78956e6a0 Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Mon, 18 Feb 2019 19:32:54 +0100 Subject: [PATCH] objectify simix timers. public C API remains for now. Might be deprecated or removed (?) --- doc/doxygen/uhood.doc | 4 +- include/simgrid/forward.h | 3 + include/simgrid/kernel/future.hpp | 2 +- include/simgrid/simix.h | 3 - include/simgrid/simix.hpp | 49 +++++++---- src/kernel/context/Context.cpp | 2 +- src/simix/ActorImpl.cpp | 4 +- src/simix/smx_global.cpp | 82 +++++++++---------- src/simix/smx_network.cpp | 4 +- src/surf/sg_platf.cpp | 2 +- .../generic-simcalls/generic-simcalls.cpp | 2 +- 11 files changed, 84 insertions(+), 73 deletions(-) diff --git a/doc/doxygen/uhood.doc b/doc/doxygen/uhood.doc index df2de9bcab..14350bdd0e 100644 --- a/doc/doxygen/uhood.doc +++ b/doc/doxygen/uhood.doc @@ -181,9 +181,7 @@ simgrid::kernel::Future kernel_wait_until(double date) { auto promise = std::make_shared>(); auto future = promise->get_future(); - SIMIX_timer_set(date, [promise] { - promise->set_value(); - }); + simgrid::simix::Timer::set(date, [promise] { promise->set_value(); }); return future; } ~~~ diff --git a/include/simgrid/forward.h b/include/simgrid/forward.h index 049fcf96a0..ef576ad250 100644 --- a/include/simgrid/forward.h +++ b/include/simgrid/forward.h @@ -154,6 +154,7 @@ class Profile; } // namespace kernel namespace simix { class Host; + class Timer; } namespace surf { class Cpu; @@ -184,6 +185,7 @@ typedef simgrid::s4u::NetZone s4u_NetZone; typedef simgrid::s4u::VirtualMachine s4u_VM; typedef boost::intrusive_ptr smx_activity_t; +typedef simgrid::simix::Timer* smx_timer_t; typedef simgrid::kernel::context::Context* smx_context_t; typedef simgrid::kernel::actor::ActorImpl* smx_actor_t; typedef simgrid::kernel::activity::ConditionVariableImpl* smx_cond_t; @@ -204,6 +206,7 @@ typedef struct s4u_NetZone s4u_NetZone; typedef struct s4u_VM s4u_VM; typedef struct kernel_Activity* smx_activity_t; +typedef struct s_smx_timer* smx_timer_t; typedef struct s_smx_actor* smx_actor_t; typedef struct s_smx_cond_t* smx_cond_t; typedef struct s_smx_context* smx_context_t; diff --git a/include/simgrid/kernel/future.hpp b/include/simgrid/kernel/future.hpp index 30f7f51b1d..810e9dd233 100644 --- a/include/simgrid/kernel/future.hpp +++ b/include/simgrid/kernel/future.hpp @@ -440,7 +440,7 @@ template Future unwrap_future(Future> future) * auto promise = std::make_shared>(); * auto future = promise->get_future(); * - * SIMIX_timer_set(date, [promise] { + * simgrid::simix::Timer::set(date, [promise] { * try { * int value = compute_the_value(); * if (value < 0) diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index 4b362d865e..172615effd 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -86,9 +86,6 @@ XBT_PUBLIC void SIMIX_set_maestro(void (*code)(void*), void* data); XBT_PUBLIC void SIMIX_run(); XBT_PUBLIC double SIMIX_get_clock(); -/* Timer functions FIXME: should these be public? */ -typedef struct s_smx_timer_t* smx_timer_t; - XBT_PUBLIC smx_timer_t SIMIX_timer_set(double date, void (*function)(void*), void* arg); XBT_PUBLIC void SIMIX_timer_remove(smx_timer_t timer); XBT_PUBLIC double SIMIX_timer_next(); diff --git a/include/simgrid/simix.hpp b/include/simgrid/simix.hpp index 72a9f50d07..4e7aeff162 100644 --- a/include/simgrid/simix.hpp +++ b/include/simgrid/simix.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -40,7 +41,6 @@ void simcall_run_blocking(F& f) } namespace simgrid { - namespace simix { /** Execute some code in the kernel/maestro @@ -75,24 +75,45 @@ typedef std::function ActorCode; typedef std::function args)> ActorCodeFactory; XBT_PUBLIC void register_function(const std::string& name, ActorCodeFactory factory); -} -} + +typedef std::pair TimerQelt; +static boost::heap::fibonacci_heap>> simix_timers; + +/** @brief Timer datatype */ +class Timer { + double date = 0.0; + +public: + decltype(simix_timers)::handle_type handle_; + + Timer(double date, simgrid::xbt::Task callback) : date(date), callback(std::move(callback)) {} + + simgrid::xbt::Task callback; + double get_date() { return date; } + void remove(); + + template static inline Timer* set(double date, F callback) + { + return set(date, simgrid::xbt::Task(std::move(callback))); + } + + template static inline Timer* set(double date, R (*callback)(T*), T* arg) + { + return set(date, [callback, arg]() { callback(arg); }); + } + + static Timer* set(double date, void (*callback)(void*), void* arg); + static Timer* set(double date, simgrid::xbt::Task callback); + static double next() { return simix_timers.empty() ? -1.0 : simix_timers.top().first; } +}; + +} // namespace simix +} // namespace simgrid XBT_PUBLIC smx_actor_t simcall_process_create(std::string name, simgrid::simix::ActorCode code, void* data, sg_host_t host, std::unordered_map* properties); XBT_PUBLIC smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task callback); -template inline -smx_timer_t SIMIX_timer_set(double date, F callback) -{ - return SIMIX_timer_set(date, simgrid::xbt::Task(std::move(callback))); -} - -template inline -smx_timer_t SIMIX_timer_set(double date, R(*callback)(T*), T* arg) -{ - return SIMIX_timer_set(date, [callback, arg]() { callback(arg); }); -} #endif diff --git a/src/kernel/context/Context.cpp b/src/kernel/context/Context.cpp index 44f2383bbd..0471a5cd56 100644 --- a/src/kernel/context/Context.cpp +++ b/src/kernel/context/Context.cpp @@ -101,7 +101,7 @@ void Context::stop() /* Unregister from the kill timer if any */ if (actor_->kill_timer != nullptr) { - SIMIX_timer_remove(actor_->kill_timer); + actor_->kill_timer->remove(); actor_->kill_timer = nullptr; } diff --git a/src/simix/ActorImpl.cpp b/src/simix/ActorImpl.cpp index 850e828c54..a966e2603d 100644 --- a/src/simix/ActorImpl.cpp +++ b/src/simix/ActorImpl.cpp @@ -170,7 +170,7 @@ void ActorImpl::set_kill_time(double kill_time) if (kill_time <= SIMIX_get_clock()) return; XBT_DEBUG("Set kill time %f for actor %s@%s", kill_time, get_cname(), host_->get_cname()); - kill_timer = SIMIX_timer_set(kill_time, [this] { + kill_timer = simix::Timer::set(kill_time, [this] { this->exit(); kill_timer = nullptr; }); @@ -178,7 +178,7 @@ void ActorImpl::set_kill_time(double kill_time) double ActorImpl::get_kill_time() { - return SIMIX_timer_get_date(kill_timer); + return kill_timer ? kill_timer->get_date() : 0; } static void dying_daemon(int /*exit_status*/, void* data) diff --git a/src/simix/smx_global.cpp b/src/simix/smx_global.cpp index 99f9d1cec9..aade81de83 100644 --- a/src/simix/smx_global.cpp +++ b/src/simix/smx_global.cpp @@ -25,29 +25,12 @@ #include "src/mc/remote/Client.hpp" #endif -#include XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, "Logging specific to SIMIX (kernel)"); std::unique_ptr simix_global; -namespace { -typedef std::pair TimerQelt; -boost::heap::fibonacci_heap>> simix_timers; -} - -/** @brief Timer datatype */ -class s_smx_timer_t { - double date = 0.0; - -public: - decltype(simix_timers)::handle_type handle_; - simgrid::xbt::Task callback; - double getDate() { return date; } - s_smx_timer_t(double date, simgrid::xbt::Task callback) : date(date), callback(std::move(callback)) {} -}; - void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr) = nullptr; bool _sg_do_verbose_exit = true; @@ -139,13 +122,29 @@ static void install_segvhandler() #endif /* _WIN32 */ /********************************* SIMIX **************************************/ -double SIMIX_timer_next() +namespace simgrid { +namespace simix { + +Timer* Timer::set(double date, void (*callback)(void*), void* arg) { - return simix_timers.empty() ? -1.0 : simix_timers.top().first; + Timer* timer = new Timer(date, simgrid::xbt::make_task([callback, arg]() { callback(arg); })); + timer->handle_ = simix_timers.emplace(std::make_pair(date, timer)); + return timer; } -namespace simgrid { -namespace simix { +Timer* Timer::set(double date, simgrid::xbt::Task callback) +{ + Timer* timer = new Timer(date, std::move(callback)); + timer->handle_ = simix_timers.emplace(std::make_pair(date, timer)); + return timer; +} + +/** @brief cancels a timer that was added earlier */ +void Timer::remove() +{ + simgrid::simix::simix_timers.erase(handle_); + delete this; +} void Global::empty_trash() { @@ -274,9 +273,9 @@ void SIMIX_clean() /* Exit the SIMIX network module */ SIMIX_mailbox_exit(); - while (not simix_timers.empty()) { - delete simix_timers.top().second; - simix_timers.pop(); + while (not simgrid::simix::simix_timers.empty()) { + delete simgrid::simix::simix_timers.top().second; + simgrid::simix::simix_timers.pop(); } /* Free the remaining data structures */ simix_global->actors_to_run.clear(); @@ -344,11 +343,11 @@ static void SIMIX_wake_processes() static bool SIMIX_execute_timers() { bool result = false; - while (not simix_timers.empty() && SIMIX_get_clock() >= simix_timers.top().first) { + while (not simgrid::simix::simix_timers.empty() && SIMIX_get_clock() >= simgrid::simix::simix_timers.top().first) { result = true; // FIXME: make the timers being real callbacks (i.e. provide dispatchers that read and expand the args) - smx_timer_t timer = simix_timers.top().second; - simix_timers.pop(); + smx_timer_t timer = simgrid::simix::simix_timers.top().second; + simgrid::simix::simix_timers.pop(); try { timer->callback(); } catch (...) { @@ -500,7 +499,7 @@ void SIMIX_run() } } - time = SIMIX_timer_next(); + time = simgrid::simix::Timer::next(); if (time > -1.0 || not simix_global->process_list.empty()) { XBT_DEBUG("Calling surf_solve"); time = surf_solve(time); @@ -543,38 +542,31 @@ void SIMIX_run() simgrid::s4u::on_simulation_end(); } -/** - * @brief Set the date to execute a function - * - * Set the date to execute the function on the surf. - * @param date Date to execute function - * @param callback Function to be executed - * @param arg Parameters of the function - * - */ +double SIMIX_timer_next() +{ + return simgrid::simix::Timer::next(); +} + smx_timer_t SIMIX_timer_set(double date, void (*callback)(void*), void *arg) { - smx_timer_t timer = new s_smx_timer_t(date, simgrid::xbt::make_task([callback, arg]() { callback(arg); })); - timer->handle_ = simix_timers.emplace(std::make_pair(date, timer)); - return timer; + return simgrid::simix::Timer::set(date, callback, arg); } smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task callback) { - smx_timer_t timer = new s_smx_timer_t(date, std::move(callback)); - timer->handle_ = simix_timers.emplace(std::make_pair(date, timer)); + smx_timer_t timer = new simgrid::simix::Timer(date, std::move(callback)); + timer->handle_ = simgrid::simix::simix_timers.emplace(std::make_pair(date, timer)); return timer; } /** @brief cancels a timer that was added earlier */ void SIMIX_timer_remove(smx_timer_t timer) { - simix_timers.erase(timer->handle_); - delete timer; + timer->remove(); } /** @brief Returns the date at which the timer will trigger (or 0 if nullptr timer) */ double SIMIX_timer_get_date(smx_timer_t timer) { - return timer ? timer->getDate() : 0; + return timer ? timer->get_date() : 0; } void SIMIX_display_process_status() diff --git a/src/simix/smx_network.cpp b/src/simix/smx_network.cpp index 828235a065..54219f1999 100644 --- a/src/simix/smx_network.cpp +++ b/src/simix/smx_network.cpp @@ -313,7 +313,7 @@ void simcall_HANDLER_comm_waitany(smx_simcall_t simcall, xbt_dynar_t synchros, d if (timeout < 0.0){ simcall->timer = NULL; } else { - simcall->timer = SIMIX_timer_set(SIMIX_get_clock() + timeout, [simcall]() { + simcall->timer = simgrid::simix::Timer::set(SIMIX_get_clock() + timeout, [simcall]() { SIMIX_waitany_remove_simcall_from_actions(simcall); simcall_comm_waitany__set__result(simcall, -1); SIMIX_simcall_answer(simcall); @@ -373,7 +373,7 @@ void SIMIX_comm_finish(smx_activity_t synchro) if (simcall->call == SIMCALL_COMM_WAITANY) { SIMIX_waitany_remove_simcall_from_actions(simcall); if (simcall->timer) { - SIMIX_timer_remove(simcall->timer); + simcall->timer->remove(); simcall->timer = nullptr; } if (not MC_is_active() && not MC_record_replay_is_active()) diff --git a/src/surf/sg_platf.cpp b/src/surf/sg_platf.cpp index 37e952b0a9..9b6bc757fd 100644 --- a/src/surf/sg_platf.cpp +++ b/src/surf/sg_platf.cpp @@ -451,7 +451,7 @@ void sg_platf_new_actor(simgrid::kernel::routing::ActorCreationArgs* actor) arg = new simgrid::kernel::actor::ProcessArg(actor_name, code, nullptr, host, kill_time, properties, auto_restart); XBT_DEBUG("Process %s@%s will be started at time %f", arg->name.c_str(), arg->host->get_cname(), start_time); - SIMIX_timer_set(start_time, [arg, auto_restart]() { + simgrid::simix::Timer::set(start_time, [arg, auto_restart]() { simgrid::kernel::actor::ActorImplPtr actor = simgrid::kernel::actor::ActorImpl::create( arg->name.c_str(), std::move(arg->code), arg->data, arg->host, arg->properties.get(), nullptr); if (arg->kill_time >= 0) diff --git a/teshsuite/simix/generic-simcalls/generic-simcalls.cpp b/teshsuite/simix/generic-simcalls/generic-simcalls.cpp index 7c1516767a..5e8ddf5731 100644 --- a/teshsuite/simix/generic-simcalls/generic-simcalls.cpp +++ b/teshsuite/simix/generic-simcalls/generic-simcalls.cpp @@ -27,7 +27,7 @@ static simgrid::kernel::Future kernel_wait_until(double date) { auto promise = std::make_shared>(); auto future = promise->get_future(); - SIMIX_timer_set(date, [promise] { promise->set_value(); }); + simgrid::simix::Timer::set(date, [promise] { promise->set_value(); }); return future; } -- 2.20.1