Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[s4u] Barrier refcounting
authorMillian Poquet <millian.poquet@inria.fr>
Mon, 24 Sep 2018 17:11:50 +0000 (19:11 +0200)
committerMillian Poquet <millian.poquet@inria.fr>
Mon, 24 Sep 2018 17:11:50 +0000 (19:11 +0200)
include/simgrid/forward.h
include/simgrid/s4u/Barrier.hpp
src/s4u/s4u_Barrier.cpp

index 38d662d..86a28bd 100644 (file)
@@ -24,6 +24,10 @@ XBT_PUBLIC void intrusive_ptr_release(Actor* actor);
 XBT_PUBLIC void intrusive_ptr_add_ref(Actor* actor);
 
 class Barrier;
+/** Smart pointer to a simgrid::s4u::Barrier */
+typedef boost::intrusive_ptr<Barrier> BarrierPtr;
+XBT_PUBLIC void intrusive_ptr_release(Barrier* m);
+XBT_PUBLIC void intrusive_ptr_add_ref(Barrier* m);
 
 class Comm;
 /** Smart pointer to a simgrid::s4u::Comm */
index 4b57898..b225d9f 100644 (file)
@@ -6,10 +6,12 @@
 #ifndef SIMGRID_S4U_BARRIER_HPP
 #define SIMGRID_S4U_BARRIER_HPP
 
-#include "simgrid/s4u/ConditionVariable.hpp"
+#include <simgrid/forward.h>
+#include <simgrid/s4u/ConditionVariable.hpp>
 #include <simgrid/chrono.hpp>
 #include <simgrid/s4u/Mutex.hpp>
 
+#include <atomic>
 #include <future>
 
 namespace simgrid {
@@ -22,13 +24,23 @@ private:
   unsigned int expected_processes_;
   unsigned int arrived_processes_ = 0;
 
+  /* refcounting */
+  std::atomic_int_fast32_t refcount_{0};
+
 public:
   explicit Barrier(unsigned int count);
   ~Barrier()              = default;
   Barrier(Barrier const&) = delete;
   Barrier& operator=(Barrier const&) = delete;
 
+  /** Constructs a new barrier */
+  static BarrierPtr create(unsigned int expected_processes);
+
   int wait();
+
+  /* refcounting */
+  friend XBT_PUBLIC void intrusive_ptr_add_ref(Barrier* barrier);
+  friend XBT_PUBLIC void intrusive_ptr_release(Barrier* barrier);
 };
 }
 } // namespace simgrid::s4u
index d19fb26..fb71bbb 100644 (file)
@@ -21,6 +21,15 @@ Barrier::Barrier(unsigned int expected_processes) : mutex_(Mutex::create()), con
 {
 }
 
+/** @brief Create a new barrier
+ *
+ * See @ref s4u_raii.
+ */
+BarrierPtr Barrier::create(unsigned int expected_processes)
+{
+    return BarrierPtr(new Barrier(expected_processes));
+}
+
 /**
  * Wait functions
  */
@@ -40,6 +49,21 @@ int Barrier::wait()
   mutex_->unlock();
   return 0;
 }
+
+void intrusive_ptr_add_ref(Barrier* barrier)
+{
+  xbt_assert(barrier);
+  barrier->refcount_.fetch_add(1, std::memory_order_relaxed);
+}
+
+void intrusive_ptr_release(Barrier* barrier)
+{
+  xbt_assert(barrier);
+  if (barrier->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
+    std::atomic_thread_fence(std::memory_order_acquire);
+    delete barrier;
+  }
+}
 } // namespace s4u
 } // namespace simgrid