Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
start modernizing ConditionVariableImpl
authorMartin Quinson <martin.quinson@loria.fr>
Sun, 15 Apr 2018 21:01:40 +0000 (23:01 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Sun, 15 Apr 2018 21:01:40 +0000 (23:01 +0200)
include/simgrid/forward.h
include/simgrid/s4u/ConditionVariable.hpp
include/simgrid/simix.h
include/xbt/synchro.h
src/kernel/activity/ConditionVariableImpl.cpp
src/kernel/activity/ConditionVariableImpl.hpp
src/simix/popping_accessors.hpp
src/simix/popping_bodies.cpp
src/simix/popping_generated.cpp
src/simix/simcalls.in
src/xbt/xbt_os_synchro.cpp

index f45e35e..8f0fd64 100644 (file)
@@ -61,6 +61,8 @@ namespace activity {
   XBT_PUBLIC void intrusive_ptr_add_ref(ActivityImpl* activity);
   XBT_PUBLIC void intrusive_ptr_release(ActivityImpl* activity);
 
+  class ConditionVariableImpl;
+
   class CommImpl;
   using CommImplPtr = boost::intrusive_ptr<CommImpl>;
   class ExecImpl;
@@ -133,6 +135,7 @@ typedef simgrid::trace_mgr::trace* tmgr_trace_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;
 typedef simgrid::kernel::activity::MutexImpl* smx_mutex_t;
 typedef simgrid::kernel::activity::MailboxImpl* smx_mailbox_t;
 typedef simgrid::surf::StorageImpl* surf_storage_t;
@@ -150,6 +153,7 @@ typedef struct kernel_Activity* smx_activity_t;
 
 typedef struct s_smx_context* smx_context_t;
 typedef struct s_smx_actor* smx_actor_t;
+typedef struct s_smx_cond_t* smx_cond_t;
 typedef struct s_smx_mutex* smx_mutex_t;
 typedef struct s_smx_mailbox* smx_mailbox_t;
 typedef struct s_surf_storage* surf_storage_t;
index 8e89a59..cf86939 100644 (file)
@@ -23,7 +23,7 @@ namespace s4u {
  */
 class XBT_PUBLIC ConditionVariable {
 private:
-  friend s_smx_cond_t;
+  friend kernel::activity::ConditionVariableImpl;
   smx_cond_t cond_;
   explicit ConditionVariable(smx_cond_t cond) : cond_(cond) {}
 public:
index 51196db..482973a 100644 (file)
@@ -48,10 +48,6 @@ typedef enum {
 /**
  * \ingroup simix_synchro_management
  */
-typedef struct s_smx_cond_t* smx_cond_t;
-/**
- * \ingroup simix_synchro_management
- */
 typedef struct s_smx_sem_t* smx_sem_t;
 
 /* ****************************** Process *********************************** */
@@ -261,8 +257,6 @@ XBT_PUBLIC int simcall_mutex_trylock(smx_mutex_t mutex);
 XBT_PUBLIC void simcall_mutex_unlock(smx_mutex_t mutex);
 
 XBT_PUBLIC smx_cond_t simcall_cond_init();
-XBT_PUBLIC void SIMIX_cond_unref(smx_cond_t cond);
-XBT_PUBLIC smx_cond_t SIMIX_cond_ref(smx_cond_t cond);
 XBT_PUBLIC void simcall_cond_signal(smx_cond_t cond);
 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);
index a03505a..68d0ee5 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef XBT_THREAD_H
 #define XBT_THREAD_H
 
+#include "simgrid/forward.h"
 #include <xbt/function_types.h>
 #include <xbt/misc.h> /* SG_BEGIN_DECL */
 
@@ -51,7 +52,11 @@ XBT_PUBLIC void xbt_mutex_destroy(xbt_mutex_t mutex);
 /** @brief Thread condition data type (opaque object)
  *  @hideinitializer
  */
+#ifdef __cplusplus
+typedef simgrid::kernel::activity::ConditionVariableImpl* xbt_cond_t;
+#else
 typedef struct s_smx_cond_* xbt_cond_t;
+#endif
 
 /** @brief Creates a condition variable */
 XBT_PUBLIC xbt_cond_t xbt_cond_init(void);
index 349a206..b08e892 100644 (file)
@@ -26,7 +26,7 @@ static void _SIMIX_cond_wait(smx_cond_t cond, smx_mutex_t mutex, double timeout,
 smx_cond_t SIMIX_cond_init()
 {
   XBT_IN("()");
-  smx_cond_t cond = new s_smx_cond_t();
+  smx_cond_t cond = new simgrid::kernel::activity::ConditionVariableImpl();
   XBT_OUT();
   return cond;
 }
@@ -79,6 +79,13 @@ static void _SIMIX_cond_wait(smx_cond_t cond, smx_mutex_t mutex, double timeout,
   XBT_OUT();
 }
 
+namespace simgrid {
+namespace kernel {
+namespace activity {
+
+ConditionVariableImpl::ConditionVariableImpl() : cond_(this) {}
+ConditionVariableImpl::~ConditionVariableImpl() = default;
+
 /**
  * \brief Signalizes a condition.
  *
@@ -86,16 +93,15 @@ static void _SIMIX_cond_wait(smx_cond_t cond, smx_mutex_t mutex, double timeout,
  * If there are no process sleeping, no action is done.
  * \param cond A condition
  */
-void SIMIX_cond_signal(smx_cond_t cond)
+void ConditionVariableImpl::signal()
 {
-  XBT_IN("(%p)", cond);
-  XBT_DEBUG("Signal condition %p", cond);
+  XBT_DEBUG("Signal condition %p", this);
 
   /* If there are processes waiting for the condition choose one and try
      to make it acquire the mutex */
-  if (not cond->sleeping.empty()) {
-    auto& proc = cond->sleeping.front();
-    cond->sleeping.pop_front();
+  if (not sleeping.empty()) {
+    auto& proc = sleeping.front();
+    sleeping.pop_front();
 
     /* Destroy waiter's synchronization */
     proc.waiting_synchro = nullptr;
@@ -119,47 +125,40 @@ void SIMIX_cond_signal(smx_cond_t cond)
  *
  * Signal ALL processes waiting on a condition.
  * If there are no process waiting, no action is done.
- * \param cond A condition
  */
-void SIMIX_cond_broadcast(smx_cond_t cond)
+void ConditionVariableImpl::broadcast()
 {
-  XBT_IN("(%p)", cond);
-  XBT_DEBUG("Broadcast condition %p", cond);
+  XBT_DEBUG("Broadcast condition %p", this);
 
   /* Signal the condition until nobody is waiting on it */
-  while (not cond->sleeping.empty()) {
-    SIMIX_cond_signal(cond);
-  }
-  XBT_OUT();
+  while (not sleeping.empty())
+    signal();
 }
 
-smx_cond_t SIMIX_cond_ref(smx_cond_t cond)
+// boost::intrusive_ptr<ConditionVariableImpl> support:
+void intrusive_ptr_add_ref(simgrid::kernel::activity::ConditionVariableImpl* cond)
 {
-  if (cond != nullptr)
-    intrusive_ptr_add_ref(cond);
-  return cond;
+  cond->refcount_.fetch_add(1, std::memory_order_relaxed);
 }
 
-void SIMIX_cond_unref(smx_cond_t cond)
+void intrusive_ptr_release(simgrid::kernel::activity::ConditionVariableImpl* cond)
 {
-  XBT_IN("(%p)", cond);
-  XBT_DEBUG("Destroy condition %p", cond);
-  if (cond != nullptr) {
-    intrusive_ptr_release(cond);
+  if (cond->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
+    std::atomic_thread_fence(std::memory_order_acquire);
+    xbt_assert(cond->sleeping.empty(), "Cannot destroy conditional since someone is still using it");
+    delete cond;
   }
-  XBT_OUT();
+}
+} // namespace activity
+} // namespace kernel
 }
 
-void intrusive_ptr_add_ref(s_smx_cond_t* cond)
+XBT_PRIVATE void simcall_HANDLER_cond_signal(smx_simcall_t simcall, smx_cond_t cond)
 {
-  auto previous = cond->refcount_.fetch_add(1);
-  xbt_assert(previous != 0);
+  cond->signal();
 }
 
-void intrusive_ptr_release(s_smx_cond_t* cond)
+XBT_PRIVATE void simcall_HANDLER_cond_broadcast(smx_simcall_t simcall, smx_cond_t cond)
 {
-  if (cond->refcount_.fetch_sub(1) == 1) {
-    xbt_assert(cond->sleeping.empty(), "Cannot destroy conditional since someone is still using it");
-    delete cond;
-  }
+  cond->broadcast();
 }
index e0634e6..eeb95d1 100644 (file)
 #include "src/simix/ActorImpl.hpp"
 #include <boost/intrusive/list.hpp>
 
-struct s_smx_cond_t {
-  s_smx_cond_t() : cond_(this) {}
+namespace simgrid {
+namespace kernel {
+namespace activity {
+
+class XBT_PUBLIC ConditionVariableImpl {
+public:
+  ConditionVariableImpl();
+  ~ConditionVariableImpl();
 
-  std::atomic_int_fast32_t refcount_{1};
-  smx_mutex_t mutex = nullptr;
   simgrid::kernel::actor::SynchroList sleeping; /* list of sleeping processes */
+  smx_mutex_t mutex = nullptr;
   simgrid::s4u::ConditionVariable cond_;
-};
 
+  void broadcast();
+  void signal();
+
+private:
+  std::atomic_int_fast32_t refcount_{1};
+  friend void intrusive_ptr_add_ref(ConditionVariableImpl* cond);
+  friend void intrusive_ptr_release(ConditionVariableImpl* cond);
+};
+} // namespace activity
+} // namespace kernel
+} // namespace simgrid
 XBT_PRIVATE smx_cond_t SIMIX_cond_init();
-XBT_PRIVATE void SIMIX_cond_broadcast(smx_cond_t cond);
-XBT_PRIVATE void SIMIX_cond_signal(smx_cond_t cond);
-XBT_PRIVATE void intrusive_ptr_add_ref(s_smx_cond_t* cond);
-XBT_PRIVATE void intrusive_ptr_release(s_smx_cond_t* cond);
+
+// simcall handlers
+XBT_PRIVATE void simcall_HANDLER_cond_signal(smx_simcall_t simcall, smx_cond_t cond);
+XBT_PRIVATE void simcall_HANDLER_cond_broadcast(smx_simcall_t simcall, smx_cond_t cond);
 
 #endif
index 3dde9c6..5be2202 100644 (file)
@@ -1406,8 +1406,10 @@ XBT_PRIVATE void simcall_HANDLER_comm_testany(smx_simcall_t simcall, boost::intr
 XBT_PRIVATE void simcall_HANDLER_mutex_lock(smx_simcall_t simcall, smx_mutex_t mutex);
 XBT_PRIVATE int simcall_HANDLER_mutex_trylock(smx_simcall_t simcall, smx_mutex_t mutex);
 XBT_PRIVATE void simcall_HANDLER_mutex_unlock(smx_simcall_t simcall, smx_mutex_t mutex);
+XBT_PRIVATE void simcall_HANDLER_cond_signal(smx_simcall_t simcall, smx_cond_t cond);
 XBT_PRIVATE void simcall_HANDLER_cond_wait(smx_simcall_t simcall, smx_cond_t cond, smx_mutex_t mutex);
 XBT_PRIVATE void simcall_HANDLER_cond_wait_timeout(smx_simcall_t simcall, smx_cond_t cond, smx_mutex_t mutex, double timeout);
+XBT_PRIVATE void simcall_HANDLER_cond_broadcast(smx_simcall_t simcall, smx_cond_t cond);
 XBT_PRIVATE void simcall_HANDLER_sem_acquire(smx_simcall_t simcall, smx_sem_t sem);
 XBT_PRIVATE void simcall_HANDLER_sem_acquire_timeout(smx_simcall_t simcall, smx_sem_t sem, double timeout);
 XBT_PRIVATE void simcall_HANDLER_storage_read(smx_simcall_t simcall, surf_storage_t st, sg_size_t size);
index f7ce5be..9914be1 100644 (file)
@@ -203,7 +203,7 @@ inline static smx_cond_t simcall_BODY_cond_init()
 inline static void simcall_BODY_cond_signal(smx_cond_t cond)
 {
   if (0) /* Go to that function to follow the code flow through the simcall barrier */
-    SIMIX_cond_signal(cond);
+    simcall_HANDLER_cond_signal(&SIMIX_process_self()->simcall, cond);
   return simcall<void, smx_cond_t>(SIMCALL_COND_SIGNAL, cond);
 }
 
@@ -224,7 +224,7 @@ inline static void simcall_BODY_cond_wait_timeout(smx_cond_t cond, smx_mutex_t m
 inline static void simcall_BODY_cond_broadcast(smx_cond_t cond)
 {
   if (0) /* Go to that function to follow the code flow through the simcall barrier */
-    SIMIX_cond_broadcast(cond);
+    simcall_HANDLER_cond_broadcast(&SIMIX_process_self()->simcall, cond);
   return simcall<void, smx_cond_t>(SIMCALL_COND_BROADCAST, cond);
 }
 
index bd9f4df..b9b4caa 100644 (file)
@@ -187,7 +187,7 @@ case SIMCALL_COND_INIT:
   break;
 
 case SIMCALL_COND_SIGNAL:
-  SIMIX_cond_signal(simgrid::simix::unmarshal<smx_cond_t>(simcall->args[0]));
+  simcall_HANDLER_cond_signal(simcall, simgrid::simix::unmarshal<smx_cond_t>(simcall->args[0]));
   SIMIX_simcall_answer(simcall);
   break;
 
@@ -200,7 +200,7 @@ case SIMCALL_COND_WAIT_TIMEOUT:
   break;
 
 case SIMCALL_COND_BROADCAST:
-  SIMIX_cond_broadcast(simgrid::simix::unmarshal<smx_cond_t>(simcall->args[0]));
+  simcall_HANDLER_cond_broadcast(simcall, simgrid::simix::unmarshal<smx_cond_t>(simcall->args[0]));
   SIMIX_simcall_answer(simcall);
   break;
 
index 53330ed..5f695cd 100644 (file)
@@ -63,10 +63,10 @@ int         mutex_trylock(smx_mutex_t mutex);
 void        mutex_unlock(smx_mutex_t mutex);
 
 smx_cond_t cond_init() [[nohandler]];
-void       cond_signal(smx_cond_t cond) [[nohandler]];
+void       cond_signal(smx_cond_t cond);
 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]];
-void       cond_broadcast(smx_cond_t cond) [[nohandler]];
+void       cond_broadcast(smx_cond_t cond);
 
 void      sem_acquire(smx_sem_t sem) [[block]];
 void      sem_acquire_timeout(smx_sem_t sem, double timeout) [[block]];
index ad97cb4..79b0b19 100644 (file)
@@ -6,11 +6,11 @@
 /* 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 "simgrid/simix.h" /* used implementation */
+#include "src/kernel/activity/ConditionVariableImpl.hpp"
 #include "xbt/ex.hpp"
 #include "xbt/synchro.h"
 
-#include "simgrid/simix.h" /* used implementation */
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_sync, xbt, "Synchronization mechanism");
 
 /****** mutex related functions ******/
@@ -76,5 +76,5 @@ void xbt_cond_broadcast(xbt_cond_t cond)
 
 void xbt_cond_destroy(xbt_cond_t cond)
 {
-  SIMIX_cond_unref((smx_cond_t)cond);
+  delete cond;
 }