Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[s4u] Allocate ConditionVariable on the heap and return ConditionVariablePtr
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 4 Jul 2016 09:57:44 +0000 (11:57 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Wed, 6 Jul 2016 11:45:41 +0000 (13:45 +0200)
examples/s4u/actions-comm/s4u_actions-comm.cpp
include/simgrid/s4u/conditionVariable.hpp
src/s4u/s4u_conditionVariable.cpp
src/simix/smx_synchro.cpp
src/simix/smx_synchro_private.h

index 0f64779..51c89d3 100644 (file)
@@ -164,11 +164,11 @@ static void action_wait(const char *const *action)
 static void action_barrier(const char *const *action)
 {
   static simgrid::s4u::MutexPtr mutex = nullptr;
-  static simgrid::s4u::ConditionVariable *cond = NULL;
+  static simgrid::s4u::ConditionVariablePtr cond = nullptr;
   static int processes_arrived_sofar = 0;
   if (mutex == nullptr) {          // first arriving on the barrier
     mutex = simgrid::s4u::Mutex::createMutex();
-    cond = new simgrid::s4u::ConditionVariable();
+    cond = simgrid::s4u::ConditionVariable::createConditionVariable();
     processes_arrived_sofar = 0;
   }
   ACT_DEBUG("Entering barrier: %s (%d already there)", NAME, processes_arrived_sofar);
@@ -188,7 +188,7 @@ static void action_barrier(const char *const *action)
 
   processes_arrived_sofar--;
   if (processes_arrived_sofar<=0) {
-    delete cond;
+    cond = nullptr;
     mutex = nullptr;
   }
 }
index 0530406..cad7507 100644 (file)
@@ -30,35 +30,21 @@ class Mutex;
  *  timestamp timeouts.
  */
 XBT_PUBLIC_CLASS ConditionVariable {
-  
+private:
+  friend s_smx_cond;
+  smx_cond_t cond_;
+  ConditionVariable(smx_cond_t cond) : cond_(cond) {}
 public:
-  ConditionVariable();
 
-  ConditionVariable(ConditionVariable* cond) : cond_(SIMIX_cond_ref(cond->cond_)) {}
-  ~ConditionVariable();
+  ConditionVariable(ConditionVariable const&) = delete;
+  ConditionVariable& operator=(ConditionVariable const&) = delete;
 
-  // Copy+move (with the copy-and-swap idiom):
-  ConditionVariable(ConditionVariable const& cond) : cond_(SIMIX_cond_ref(cond.cond_)) {}
-  friend void swap(ConditionVariable& first, ConditionVariable& second)
-  {
-    using std::swap;
-    swap(first.cond_, second.cond_);
-  }
-  ConditionVariable& operator=(ConditionVariable cond)
-  {
-    swap(*this, cond);
-    return *this;
-  }
-  ConditionVariable(ConditionVariable&& cond) : cond_(nullptr)
-  {
-    swap(*this, cond);
-  }
+  friend XBT_PUBLIC(void) intrusive_ptr_add_ref(ConditionVariable* cond);
+  friend XBT_PUBLIC(void) intrusive_ptr_release(ConditionVariable* cond);
+  using Ptr = boost::intrusive_ptr<ConditionVariable>;
+
+  static Ptr createConditionVariable();
 
-  bool valid() const
-  {
-    return cond_ != nullptr;
-  }
-  
   //  Wait functions:
 
   void wait(std::unique_lock<Mutex>& lock);
@@ -94,11 +80,10 @@ public:
 
   XBT_ATTRIB_DEPRECATED("Use notify_one() instead")
   void notify() { notify_one(); }
+};
 
-private:
-  smx_cond_t cond_;
+using ConditionVariablePtr = ConditionVariable::Ptr;
 
-};
 }} // namespace simgrid::s4u
 
 #endif /* SIMGRID_S4U_COND_VARIABLE_HPP */
index ae29352..3200255 100644 (file)
@@ -4,18 +4,17 @@
 #include <xbt/ex.hpp>
 #include <xbt/log.hpp>
 
+#include "src/simix/smx_synchro_private.h"
 #include "simgrid/s4u/conditionVariable.hpp"
 #include "simgrid/simix.h"
 
 namespace simgrid {
 namespace s4u {
 
-ConditionVariable::ConditionVariable()  : cond_(simcall_cond_init()){
-    
-}
-
-ConditionVariable::~ConditionVariable() {
-  SIMIX_cond_unref(cond_);
+ConditionVariablePtr ConditionVariable::createConditionVariable()
+{
+  smx_cond_t cond = simcall_cond_init();
+  return ConditionVariablePtr(&cond->cond_, false);
 }
 
 /**
@@ -73,5 +72,15 @@ void ConditionVariable::notify_all() {
   simcall_cond_broadcast(cond_);
 }
 
+void intrusive_ptr_add_ref(ConditionVariable* cond)
+{
+  intrusive_ptr_add_ref(cond->cond_);
+}
+
+void intrusive_ptr_release(ConditionVariable* cond)
+{
+  intrusive_ptr_release(cond->cond_);
+}
+
 }
 }
index 143e0ab..b4fd81c 100644 (file)
@@ -238,9 +238,8 @@ smx_cond_t SIMIX_cond_init(void)
 {
   XBT_IN("()");
   simgrid::simix::Process p;
-  smx_cond_t cond = xbt_new0(s_smx_cond_t, 1);
+  smx_cond_t cond = new s_smx_cond();
   cond->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup));
-  cond->mutex = nullptr;
   cond->refcount_ = 1;
   XBT_OUT();
   return cond;
@@ -383,9 +382,8 @@ void intrusive_ptr_release(s_smx_cond_t *cond)
   if (count == 0) {
     xbt_assert(xbt_swag_size(cond->sleeping) == 0,
                 "Cannot destroy conditional since someone is still using it");
-
     xbt_swag_free(cond->sleeping);
-    xbt_free(cond);
+    delete cond;
   }
 }
 
index 338a0b4..f312483 100644 (file)
@@ -10,6 +10,7 @@
 #include <atomic>
 
 #include <simgrid/s4u/mutex.hpp>
+#include <simgrid/s4u/conditionVariable.hpp>
 
 #include "xbt/base.h"
 #include "xbt/swag.h"
@@ -62,9 +63,12 @@ private:
 }
 
 typedef struct s_smx_cond {
-  smx_mutex_t mutex;
-  xbt_swag_t sleeping;          /* list of sleeping process */
-  std::atomic_int_fast32_t refcount_;
+  s_smx_cond() : cond_(this) {}
+
+  std::atomic_int_fast32_t refcount_ { 1 };
+  smx_mutex_t mutex = nullptr;
+  xbt_swag_t sleeping = nullptr;  /* list of sleeping process */
+  simgrid::s4u::ConditionVariable cond_;
 } s_smx_cond_t;
 
 typedef struct s_smx_sem {
@@ -72,8 +76,6 @@ typedef struct s_smx_sem {
   xbt_swag_t sleeping;          /* list of sleeping process */
 } s_smx_sem_t;
 
-
-
 XBT_PRIVATE void SIMIX_post_synchro(smx_synchro_t synchro);
 XBT_PRIVATE void SIMIX_synchro_stop_waiting(smx_process_t process, smx_simcall_t simcall);
 XBT_PRIVATE void SIMIX_synchro_destroy(smx_synchro_t synchro);