Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Stop using costly exceptions on timeout for simix synchros.
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Fri, 4 May 2018 15:05:40 +0000 (17:05 +0200)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Fri, 4 May 2018 19:44:03 +0000 (21:44 +0200)
Gives a speedup up to 1.7 on a particular application!

include/simgrid/simix.h
src/kernel/activity/ConditionVariableImpl.cpp
src/msg/msg_synchro.cpp
src/simix/libsmx.cpp
src/simix/popping_accessors.hpp
src/simix/popping_bodies.cpp
src/simix/simcalls.in
src/simix/smx_synchro.cpp
src/xbt/xbt_os_synchro.cpp

index 1a2c48a..3e88585 100644 (file)
@@ -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);
index 06836e0..c49ab05 100644 (file)
@@ -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();
 }
index a1e4886..c2895a3 100644 (file)
@@ -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 */
index 15c75f6..3647e35 100644 (file)
@@ -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)
index ff804ef..072cf55 100644 (file)
@@ -924,6 +924,18 @@ static inline void simcall_cond_wait_timeout__set__timeout(smx_simcall_t simcall
 {
   simgrid::simix::marshal<double>(simcall->args[2], arg);
 }
+static inline int simcall_cond_wait_timeout__get__result(smx_simcall_t simcall)
+{
+  return simgrid::simix::unmarshal<int>(simcall->result);
+}
+static inline int simcall_cond_wait_timeout__getraw__result(smx_simcall_t simcall)
+{
+  return simgrid::simix::unmarshal_raw<int>(simcall->result);
+}
+static inline void simcall_cond_wait_timeout__set__result(smx_simcall_t simcall, int result)
+{
+  simgrid::simix::marshal<int>(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<double>(simcall->args[1], arg);
 }
+static inline int simcall_sem_acquire_timeout__get__result(smx_simcall_t simcall)
+{
+  return simgrid::simix::unmarshal<int>(simcall->result);
+}
+static inline int simcall_sem_acquire_timeout__getraw__result(smx_simcall_t simcall)
+{
+  return simgrid::simix::unmarshal_raw<int>(simcall->result);
+}
+static inline void simcall_sem_acquire_timeout__set__result(smx_simcall_t simcall, int result)
+{
+  simgrid::simix::marshal<int>(simcall->result, result);
+}
 
 static inline surf_storage_t simcall_storage_read__get__st(smx_simcall_t simcall)
 {
index ad12e39..9c65c5c 100644 (file)
@@ -163,11 +163,11 @@ inline static void simcall_BODY_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
   return simcall<void, smx_cond_t, smx_mutex_t>(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<void, smx_cond_t, smx_mutex_t, double>(SIMCALL_COND_WAIT_TIMEOUT, cond, mutex, timeout);
+  return simcall<int, smx_cond_t, smx_mutex_t, double>(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<void, smx_sem_t>(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<void, smx_sem_t, double>(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem, timeout);
+  return simcall<int, smx_sem_t, double>(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem, timeout);
 }
 
 inline static sg_size_t simcall_BODY_storage_read(surf_storage_t st, sg_size_t size)
index e637b58..7c26066 100644 (file)
@@ -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]];
index fe1fa3f..24f8636 100644 (file)
@@ -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();
 }
index 4e38f7e..eaab5a6 100644 (file)
@@ -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)