From: Arnaud Giersch Date: Fri, 4 May 2018 15:05:40 +0000 (+0200) Subject: Stop using costly exceptions on timeout for simix synchros. X-Git-Tag: v3.20~287 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/8efeb3a6aa2c201800a3ba19416ea9728af3bff6 Stop using costly exceptions on timeout for simix synchros. Gives a speedup up to 1.7 on a particular application! --- diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index 1a2c48a722..3e8858598e 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -254,11 +254,11 @@ XBT_PUBLIC void simcall_mutex_unlock(smx_mutex_t mutex); XBT_PUBLIC smx_cond_t simcall_cond_init(); XBT_PUBLIC void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex); -XBT_PUBLIC void simcall_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double max_duration); +XBT_PUBLIC int simcall_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double max_duration); XBT_PUBLIC void SIMIX_sem_destroy(smx_sem_t sem); XBT_PUBLIC void simcall_sem_acquire(smx_sem_t sem); -XBT_PUBLIC void simcall_sem_acquire_timeout(smx_sem_t sem, double max_duration); +XBT_PUBLIC int simcall_sem_acquire_timeout(smx_sem_t sem, double max_duration); /***************************** Storage **********************************/ XBT_PUBLIC sg_size_t simcall_storage_read(surf_storage_t st, sg_size_t size); diff --git a/src/kernel/activity/ConditionVariableImpl.cpp b/src/kernel/activity/ConditionVariableImpl.cpp index 06836e0fb8..c49ab05a08 100644 --- a/src/kernel/activity/ConditionVariableImpl.cpp +++ b/src/kernel/activity/ConditionVariableImpl.cpp @@ -54,7 +54,7 @@ void simcall_HANDLER_cond_wait_timeout(smx_simcall_t simcall, smx_cond_t cond, s { XBT_IN("(%p)", simcall); smx_actor_t issuer = simcall->issuer; - + simcall_cond_wait_timeout__set__result(simcall, 0); // default result, will be set to 1 on timeout _SIMIX_cond_wait(cond, mutex, timeout, issuer, simcall); XBT_OUT(); } diff --git a/src/msg/msg_synchro.cpp b/src/msg/msg_synchro.cpp index a1e4886c4d..c2895a3417 100644 --- a/src/msg/msg_synchro.cpp +++ b/src/msg/msg_synchro.cpp @@ -29,15 +29,7 @@ void MSG_sem_acquire(msg_sem_t sem) { /** @brief locks on a semaphore object up until the provided timeout expires */ msg_error_t MSG_sem_acquire_timeout(msg_sem_t sem, double timeout) { - msg_error_t res = MSG_OK; - try { - simcall_sem_acquire_timeout(sem,timeout); - } catch(xbt_ex& e) { - if (e.category == timeout_error) - return MSG_TIMEOUT; - throw; - } - return res; + return simcall_sem_acquire_timeout(sem, timeout) ? MSG_TIMEOUT : MSG_OK; } /** @brief releases the semaphore object */ diff --git a/src/simix/libsmx.cpp b/src/simix/libsmx.cpp index 15c75f6845..3647e351e8 100644 --- a/src/simix/libsmx.cpp +++ b/src/simix/libsmx.cpp @@ -467,10 +467,10 @@ void simcall_cond_wait(smx_cond_t cond, smx_mutex_t mutex) * \ingroup simix_synchro_management * */ -void simcall_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) +int simcall_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) { xbt_assert(std::isfinite(timeout), "timeout is not finite!"); - simcall_BODY_cond_wait_timeout(cond, mutex, timeout); + return simcall_BODY_cond_wait_timeout(cond, mutex, timeout); } /** @@ -486,10 +486,10 @@ void simcall_sem_acquire(smx_sem_t sem) * \ingroup simix_synchro_management * */ -void simcall_sem_acquire_timeout(smx_sem_t sem, double timeout) +int simcall_sem_acquire_timeout(smx_sem_t sem, double timeout) { xbt_assert(std::isfinite(timeout), "timeout is not finite!"); - simcall_BODY_sem_acquire_timeout(sem, timeout); + return simcall_BODY_sem_acquire_timeout(sem, timeout); } sg_size_t simcall_storage_read(surf_storage_t st, sg_size_t size) diff --git a/src/simix/popping_accessors.hpp b/src/simix/popping_accessors.hpp index ff804efddb..072cf55725 100644 --- a/src/simix/popping_accessors.hpp +++ b/src/simix/popping_accessors.hpp @@ -924,6 +924,18 @@ static inline void simcall_cond_wait_timeout__set__timeout(smx_simcall_t simcall { simgrid::simix::marshal(simcall->args[2], arg); } +static inline int simcall_cond_wait_timeout__get__result(smx_simcall_t simcall) +{ + return simgrid::simix::unmarshal(simcall->result); +} +static inline int simcall_cond_wait_timeout__getraw__result(smx_simcall_t simcall) +{ + return simgrid::simix::unmarshal_raw(simcall->result); +} +static inline void simcall_cond_wait_timeout__set__result(smx_simcall_t simcall, int result) +{ + simgrid::simix::marshal(simcall->result, result); +} static inline smx_sem_t simcall_sem_acquire__get__sem(smx_simcall_t simcall) { @@ -962,6 +974,18 @@ static inline void simcall_sem_acquire_timeout__set__timeout(smx_simcall_t simca { simgrid::simix::marshal(simcall->args[1], arg); } +static inline int simcall_sem_acquire_timeout__get__result(smx_simcall_t simcall) +{ + return simgrid::simix::unmarshal(simcall->result); +} +static inline int simcall_sem_acquire_timeout__getraw__result(smx_simcall_t simcall) +{ + return simgrid::simix::unmarshal_raw(simcall->result); +} +static inline void simcall_sem_acquire_timeout__set__result(smx_simcall_t simcall, int result) +{ + simgrid::simix::marshal(simcall->result, result); +} static inline surf_storage_t simcall_storage_read__get__st(smx_simcall_t simcall) { diff --git a/src/simix/popping_bodies.cpp b/src/simix/popping_bodies.cpp index ad12e39687..9c65c5c7fa 100644 --- a/src/simix/popping_bodies.cpp +++ b/src/simix/popping_bodies.cpp @@ -163,11 +163,11 @@ inline static void simcall_BODY_cond_wait(smx_cond_t cond, smx_mutex_t mutex) return simcall(SIMCALL_COND_WAIT, cond, mutex); } -inline static void simcall_BODY_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) +inline static int simcall_BODY_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) { if (0) /* Go to that function to follow the code flow through the simcall barrier */ simcall_HANDLER_cond_wait_timeout(&SIMIX_process_self()->simcall, cond, mutex, timeout); - return simcall(SIMCALL_COND_WAIT_TIMEOUT, cond, mutex, timeout); + return simcall(SIMCALL_COND_WAIT_TIMEOUT, cond, mutex, timeout); } inline static void simcall_BODY_sem_acquire(smx_sem_t sem) @@ -177,11 +177,11 @@ inline static void simcall_BODY_sem_acquire(smx_sem_t sem) return simcall(SIMCALL_SEM_ACQUIRE, sem); } -inline static void simcall_BODY_sem_acquire_timeout(smx_sem_t sem, double timeout) +inline static int simcall_BODY_sem_acquire_timeout(smx_sem_t sem, double timeout) { if (0) /* Go to that function to follow the code flow through the simcall barrier */ simcall_HANDLER_sem_acquire_timeout(&SIMIX_process_self()->simcall, sem, timeout); - return simcall(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem, timeout); + return simcall(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem, timeout); } inline static sg_size_t simcall_BODY_storage_read(surf_storage_t st, sg_size_t size) diff --git a/src/simix/simcalls.in b/src/simix/simcalls.in index e637b58dcc..7c26066a64 100644 --- a/src/simix/simcalls.in +++ b/src/simix/simcalls.in @@ -57,10 +57,10 @@ int mutex_trylock(smx_mutex_t mutex); void mutex_unlock(smx_mutex_t mutex); void cond_wait(smx_cond_t cond, smx_mutex_t mutex) [[block]]; -void cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) [[block]]; +int cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout) [[block]]; void sem_acquire(smx_sem_t sem) [[block]]; -void sem_acquire_timeout(smx_sem_t sem, double timeout) [[block]]; +int sem_acquire_timeout(smx_sem_t sem, double timeout) [[block]]; sg_size_t storage_read(surf_storage_t st, sg_size_t size) [[block]]; sg_size_t storage_write(surf_storage_t st, sg_size_t size) [[block]]; diff --git a/src/simix/smx_synchro.cpp b/src/simix/smx_synchro.cpp index fe1fa3f0c8..24f863649d 100644 --- a/src/simix/smx_synchro.cpp +++ b/src/simix/smx_synchro.cpp @@ -42,6 +42,7 @@ void SIMIX_synchro_stop_waiting(smx_actor_t process, smx_simcall_t simcall) case SIMCALL_COND_WAIT_TIMEOUT: simgrid::xbt::intrusive_erase(simcall_cond_wait_timeout__get__cond(simcall)->sleeping, *process); + simcall_cond_wait_timeout__set__result(simcall, 1); // signal a timeout break; case SIMCALL_SEM_ACQUIRE: @@ -50,6 +51,7 @@ void SIMIX_synchro_stop_waiting(smx_actor_t process, smx_simcall_t simcall) case SIMCALL_SEM_ACQUIRE_TIMEOUT: simgrid::xbt::intrusive_erase(simcall_sem_acquire_timeout__get__sem(simcall)->sleeping, *process); + simcall_sem_acquire_timeout__set__result(simcall, 1); // signal a timeout break; default: @@ -64,19 +66,11 @@ void SIMIX_synchro_finish(smx_activity_t synchro) smx_simcall_t simcall = synchro->simcalls.front(); synchro->simcalls.pop_front(); - switch (synchro->state) { - - case SIMIX_SRC_TIMEOUT: - SMX_EXCEPTION(simcall->issuer, timeout_error, 0, "Synchro's wait timeout"); - break; - - case SIMIX_FAILED: - simcall->issuer->context->iwannadie = 1; - break; - - default: + if (synchro->state != SIMIX_SRC_TIMEOUT) { + if (synchro->state == SIMIX_FAILED) + simcall->issuer->context->iwannadie = 1; + else THROW_IMPOSSIBLE; - break; } SIMIX_synchro_stop_waiting(simcall->issuer, simcall); @@ -179,6 +173,7 @@ void simcall_HANDLER_sem_acquire(smx_simcall_t simcall, smx_sem_t sem) void simcall_HANDLER_sem_acquire_timeout(smx_simcall_t simcall, smx_sem_t sem, double timeout) { XBT_IN("(%p)",simcall); + simcall_sem_acquire_timeout__set__result(simcall, 0); // default result, will be set to 1 on timeout _SIMIX_sem_wait(sem, timeout, simcall->issuer, simcall); XBT_OUT(); } diff --git a/src/xbt/xbt_os_synchro.cpp b/src/xbt/xbt_os_synchro.cpp index 4e38f7ed23..eaab5a695b 100644 --- a/src/xbt/xbt_os_synchro.cpp +++ b/src/xbt/xbt_os_synchro.cpp @@ -52,16 +52,7 @@ void xbt_cond_wait(xbt_cond_t cond, xbt_mutex_t mutex) int xbt_cond_timedwait(xbt_cond_t cond, xbt_mutex_t mutex, double delay) { - try { - simcall_cond_wait_timeout((smx_cond_t)cond, (smx_mutex_t)mutex, delay); - } catch (xbt_ex& e) { - if (e.category == timeout_error) { - return 1; - } else { - throw; // rethrow the exceptions that I don't know - } - } - return 0; + return simcall_cond_wait_timeout((smx_cond_t)cond, (smx_mutex_t)mutex, delay); } void xbt_cond_signal(xbt_cond_t cond)