From: Arnaud Giersch Date: Sat, 13 Mar 2021 21:25:04 +0000 (+0100) Subject: Add SemaphoreImpl::piface_ (mimic MutexImpl). X-Git-Tag: v3.27~153^2~7 X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/993a22f9b7f34d3a536bfe6a49a31405461dea5d Add SemaphoreImpl::piface_ (mimic MutexImpl). Also make constructor private to enforce usage of create(), and fix bogus destructor. Like for Mutex, could not manage to make ~Semaphore() private. --- diff --git a/include/simgrid/forward.h b/include/simgrid/forward.h index 72889a3570..1eef471696 100644 --- a/include/simgrid/forward.h +++ b/include/simgrid/forward.h @@ -86,8 +86,8 @@ class File; class Semaphore; /** Smart pointer to a simgrid::s4u::Semaphore */ using SemaphorePtr = boost::intrusive_ptr; -XBT_PUBLIC void intrusive_ptr_release(Semaphore* m); -XBT_PUBLIC void intrusive_ptr_add_ref(Semaphore* m); +XBT_PUBLIC void intrusive_ptr_release(const Semaphore* m); +XBT_PUBLIC void intrusive_ptr_add_ref(const Semaphore* m); class Disk; } // namespace s4u diff --git a/include/simgrid/s4u/Semaphore.hpp b/include/simgrid/s4u/Semaphore.hpp index 6c93a8bc57..b100ba560d 100644 --- a/include/simgrid/s4u/Semaphore.hpp +++ b/include/simgrid/s4u/Semaphore.hpp @@ -29,21 +29,20 @@ namespace s4u { * */ class XBT_PUBLIC Semaphore { - kernel::activity::SemaphoreImpl* const pimpl_; - std::atomic_int_fast32_t refcount_{0}; + friend kernel::activity::SemaphoreImpl; - friend void intrusive_ptr_add_ref(Semaphore* sem); - friend void intrusive_ptr_release(Semaphore* sem); + kernel::activity::SemaphoreImpl* const pimpl_; -public: - explicit Semaphore(unsigned int initial_capacity); - ~Semaphore(); + friend void intrusive_ptr_add_ref(const Semaphore* sem); + friend void intrusive_ptr_release(const Semaphore* sem); + explicit Semaphore(kernel::activity::SemaphoreImpl* sem) : pimpl_(sem) {} #ifndef DOXYGEN Semaphore(Semaphore const&) = delete; // No copy constructor. Use SemaphorePtr instead Semaphore& operator=(Semaphore const&) = delete; // No direct assignment either. Use SemaphorePtr instead #endif +public: /** Constructs a new semaphore */ static SemaphorePtr create(unsigned int initial_capacity); diff --git a/src/kernel/activity/SemaphoreImpl.cpp b/src/kernel/activity/SemaphoreImpl.cpp index 98d38be483..fbfffa1cf7 100644 --- a/src/kernel/activity/SemaphoreImpl.cpp +++ b/src/kernel/activity/SemaphoreImpl.cpp @@ -43,6 +43,19 @@ void SemaphoreImpl::release() } } +/** Increase the refcount for this semaphore */ +SemaphoreImpl* SemaphoreImpl::ref() +{ + intrusive_ptr_add_ref(this); + return this; +} + +/** Decrease the refcount for this mutex */ +void SemaphoreImpl::unref() +{ + intrusive_ptr_release(this); +} + } // namespace activity } // namespace kernel } // namespace simgrid diff --git a/src/kernel/activity/SemaphoreImpl.hpp b/src/kernel/activity/SemaphoreImpl.hpp index 3be684e36c..33793ce403 100644 --- a/src/kernel/activity/SemaphoreImpl.hpp +++ b/src/kernel/activity/SemaphoreImpl.hpp @@ -18,11 +18,12 @@ namespace activity { class XBT_PUBLIC SemaphoreImpl { std::atomic_int_fast32_t refcount_{1}; + s4u::Semaphore piface_; unsigned int value_; actor::SynchroList sleeping_; /* list of sleeping actors*/ public: - explicit SemaphoreImpl(unsigned int value) : value_(value){}; + explicit SemaphoreImpl(unsigned int value) : piface_(this), value_(value){}; SemaphoreImpl(SemaphoreImpl const&) = delete; SemaphoreImpl& operator=(SemaphoreImpl const&) = delete; @@ -35,6 +36,9 @@ public: unsigned int get_capacity() const { return value_; } bool is_used() const { return not sleeping_.empty(); } + SemaphoreImpl* ref(); + void unref(); + friend void intrusive_ptr_add_ref(SemaphoreImpl* sem) { XBT_ATTRIB_UNUSED auto previous = sem->refcount_.fetch_add(1); @@ -42,9 +46,13 @@ public: } friend void intrusive_ptr_release(SemaphoreImpl* sem) { - if (sem->refcount_.fetch_sub(1) == 1) + if (sem->refcount_.fetch_sub(1) == 1) { + xbt_assert(not sem->is_used(), "Cannot destroy semaphore since someone is still using it"); delete sem; + } } + + s4u::Semaphore& sem() { return piface_; } }; } // namespace activity } // namespace kernel diff --git a/src/s4u/s4u_Semaphore.cpp b/src/s4u/s4u_Semaphore.cpp index 7e3a567cc5..b2482eda54 100644 --- a/src/s4u/s4u_Semaphore.cpp +++ b/src/s4u/s4u_Semaphore.cpp @@ -13,17 +13,10 @@ namespace simgrid { namespace s4u { -Semaphore::Semaphore(unsigned int initial_capacity) : pimpl_(new kernel::activity::SemaphoreImpl(initial_capacity)) {} - -Semaphore::~Semaphore() -{ - xbt_assert(not pimpl_->is_used(), "Cannot destroy semaphore since someone is still using it"); - delete pimpl_; -} - SemaphorePtr Semaphore::create(unsigned int initial_capacity) { - return SemaphorePtr(new Semaphore(initial_capacity)); + auto* sem = new kernel::activity::SemaphoreImpl(initial_capacity); + return SemaphorePtr(&sem->sem(), false); } void Semaphore::acquire() @@ -51,19 +44,17 @@ bool Semaphore::would_block() const return kernel::actor::simcall([this] { return pimpl_->would_block(); }); } -void intrusive_ptr_add_ref(Semaphore* sem) +/* refcounting of the intrusive_ptr is delegated to the implementation object */ +void intrusive_ptr_add_ref(const Semaphore* sem) { xbt_assert(sem); - sem->refcount_.fetch_add(1, std::memory_order_relaxed); + sem->pimpl_->ref(); } -void intrusive_ptr_release(Semaphore* sem) +void intrusive_ptr_release(const Semaphore* sem) { xbt_assert(sem); - if (sem->refcount_.fetch_sub(1, std::memory_order_release) == 1) { - std::atomic_thread_fence(std::memory_order_acquire); - delete sem; - } + sem->pimpl_->unref(); } } // namespace s4u @@ -73,7 +64,7 @@ void intrusive_ptr_release(Semaphore* sem) /** @brief creates a semaphore object of the given initial capacity */ sg_sem_t sg_sem_init(int initial_value) { - return new simgrid::s4u::Semaphore(initial_value); + return simgrid::s4u::Semaphore::create(initial_value).detach(); } /** @brief locks on a semaphore object */ @@ -101,7 +92,7 @@ int sg_sem_get_capacity(const_sg_sem_t sem) void sg_sem_destroy(const_sg_sem_t sem) { - delete sem; + intrusive_ptr_release(sem); } /** @brief returns a boolean indicating if this semaphore would block at this very specific time