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 */
#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 {
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
{
}
+/** @brief Create a new barrier
+ *
+ * See @ref s4u_raii.
+ */
+BarrierPtr Barrier::create(unsigned int expected_processes)
+{
+ return BarrierPtr(new Barrier(expected_processes));
+}
+
/**
* Wait functions
*/
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