From 73382ccaaf4ed5534b97beb5e56a9116c7a1e773 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Mon, 4 Jul 2016 11:34:12 +0200 Subject: [PATCH] [s4u] Allocate Mutex on the heap and return MutexPtr --- .../s4u/actions-comm/s4u_actions-comm.cpp | 9 ++-- examples/s4u/mutex/s4u_mutex.cpp | 10 ++--- include/simgrid/s4u/mutex.hpp | 44 ++++++++----------- src/s4u/s4u_mutex.cpp | 17 +++++-- src/simix/smx_synchro.cpp | 2 +- src/simix/smx_synchro_private.h | 6 +++ 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/examples/s4u/actions-comm/s4u_actions-comm.cpp b/examples/s4u/actions-comm/s4u_actions-comm.cpp index 826d6c97ca..0f6477978b 100644 --- a/examples/s4u/actions-comm/s4u_actions-comm.cpp +++ b/examples/s4u/actions-comm/s4u_actions-comm.cpp @@ -163,11 +163,11 @@ static void action_wait(const char *const *action) /* FIXME: that's a poor man's implementation: we should take the message exchanges into account */ static void action_barrier(const char *const *action) { - static simgrid::s4u::Mutex *mutex = NULL; + static simgrid::s4u::MutexPtr mutex = nullptr; static simgrid::s4u::ConditionVariable *cond = NULL; static int processes_arrived_sofar = 0; - if (mutex == NULL) { // first arriving on the barrier - mutex = new simgrid::s4u::Mutex(); + if (mutex == nullptr) { // first arriving on the barrier + mutex = simgrid::s4u::Mutex::createMutex(); cond = new simgrid::s4u::ConditionVariable(); processes_arrived_sofar = 0; } @@ -189,8 +189,7 @@ static void action_barrier(const char *const *action) processes_arrived_sofar--; if (processes_arrived_sofar<=0) { delete cond; - delete mutex; - mutex = NULL; + mutex = nullptr; } } diff --git a/examples/s4u/mutex/s4u_mutex.cpp b/examples/s4u/mutex/s4u_mutex.cpp index 51989fa997..c9073e4398 100644 --- a/examples/s4u/mutex/s4u_mutex.cpp +++ b/examples/s4u/mutex/s4u_mutex.cpp @@ -14,13 +14,13 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category"); -static void worker(simgrid::s4u::Mutex mutex, int& result) +static void worker(simgrid::s4u::MutexPtr mutex, int& result) { // Do the calculation simgrid::s4u::this_actor::execute(1000); // lock the mutex before enter in the critical section - std::lock_guard lock(mutex); + std::lock_guard lock(*mutex); XBT_INFO("Hello s4u, I'm ready to compute"); // And finaly add it to the results @@ -28,12 +28,12 @@ static void worker(simgrid::s4u::Mutex mutex, int& result) XBT_INFO("I'm done, good bye"); } -static void workerLockGuard(simgrid::s4u::Mutex mutex, int& result) +static void workerLockGuard(simgrid::s4u::MutexPtr mutex, int& result) { simgrid::s4u::this_actor::execute(1000); // Simply use the std::lock_guard like this - std::lock_guard lock(mutex); + std::lock_guard lock(*mutex); // then you are in a safe zone XBT_INFO("Hello s4u, I'm ready to compute"); @@ -45,7 +45,7 @@ static void workerLockGuard(simgrid::s4u::Mutex mutex, int& result) static void master() { int result = 0; - simgrid::s4u::Mutex mutex; + simgrid::s4u::MutexPtr mutex = simgrid::s4u::Mutex::createMutex(); for (int i = 0; i < NB_ACTOR * 2 ; i++) { // To create a worker use the static method simgrid::s4u::Actor. diff --git a/include/simgrid/s4u/mutex.hpp b/include/simgrid/s4u/mutex.hpp index e6a1ed548a..5b0f7f5f4f 100644 --- a/include/simgrid/s4u/mutex.hpp +++ b/include/simgrid/s4u/mutex.hpp @@ -21,46 +21,38 @@ class ConditionVariable; XBT_PUBLIC_CLASS Mutex { friend ConditionVariable; +private: + friend simgrid::simix::Mutex; + simgrid::simix::Mutex* mutex_; + Mutex(simgrid::simix::Mutex* mutex) : mutex_(mutex) {} public: - Mutex() : - mutex_(simcall_mutex_init()) {} - Mutex(simgrid::simix::Mutex* mutex) : mutex_(SIMIX_mutex_ref(mutex)) {} - ~Mutex() - { - SIMIX_mutex_unref(mutex_); - } - // Copy+move (with the copy-and-swap idiom): - Mutex(Mutex const& mutex) : mutex_(SIMIX_mutex_ref(mutex.mutex_)) {} - friend void swap(Mutex& first, Mutex& second) + friend void intrusive_ptr_add_ref(Mutex* mutex) { - using std::swap; - swap(first.mutex_, second.mutex_); + xbt_assert(mutex); + SIMIX_mutex_ref(mutex->mutex_); } - Mutex& operator=(Mutex mutex) + friend void intrusive_ptr_release(Mutex* mutex) { - swap(*this, mutex); - return *this; - } - Mutex(Mutex&& mutex) : mutex_(nullptr) - { - swap(*this, mutex); + xbt_assert(mutex); + SIMIX_mutex_unref(mutex->mutex_); } + using Ptr = boost::intrusive_ptr; - bool valid() const - { - return mutex_ != nullptr; - } + // No copy: + Mutex(Mutex const&) = delete; + Mutex& operatori(Mutex const&) = delete; + + static Ptr createMutex(); public: void lock(); void unlock(); bool try_lock(); - -private: - simgrid::simix::Mutex* mutex_; }; +using MutexPtr = Mutex::Ptr; + }} // namespace simgrid::s4u #endif /* SIMGRID_S4U_MUTEX_HPP */ diff --git a/src/s4u/s4u_mutex.cpp b/src/s4u/s4u_mutex.cpp index e64bfd4f60..3b1d9f156b 100644 --- a/src/s4u/s4u_mutex.cpp +++ b/src/s4u/s4u_mutex.cpp @@ -6,24 +6,33 @@ #include "xbt/log.h" #include "src/msg/msg_private.h" -#include "src/simix/smx_network_private.h" +#include "src/simix/smx_synchro_private.h" #include "simgrid/s4u/mutex.hpp" namespace simgrid { namespace s4u { -void Mutex::lock() { +void Mutex::lock() +{ simcall_mutex_lock(mutex_); } -void Mutex::unlock() { +void Mutex::unlock() +{ simcall_mutex_unlock(mutex_); } -bool Mutex::try_lock() { +bool Mutex::try_lock() +{ return simcall_mutex_trylock(mutex_); } +MutexPtr Mutex::createMutex() +{ + smx_mutex_t mutex = simcall_mutex_init(); + return MutexPtr(&mutex->mutex(), false); +} + } } diff --git a/src/simix/smx_synchro.cpp b/src/simix/smx_synchro.cpp index 305fc32c0f..143e0abde6 100644 --- a/src/simix/smx_synchro.cpp +++ b/src/simix/smx_synchro.cpp @@ -98,7 +98,7 @@ void SIMIX_synchro_finish(smx_synchro_t synchro) namespace simgrid { namespace simix { -Mutex::Mutex() +Mutex::Mutex() : mutex_(this) { XBT_IN("(%p)", this); // Useful to initialize sleeping swag: diff --git a/src/simix/smx_synchro_private.h b/src/simix/smx_synchro_private.h index 73f87c1867..338a0b488c 100644 --- a/src/simix/smx_synchro_private.h +++ b/src/simix/smx_synchro_private.h @@ -9,6 +9,8 @@ #include +#include + #include "xbt/base.h" #include "xbt/swag.h" #include "xbt/xbt_os_thread.h" @@ -48,8 +50,12 @@ public: if (count == 0) delete mutex; } + + simgrid::s4u::Mutex& mutex() { return mutex_; } + private: std::atomic_int_fast32_t refcount_ { 1 }; + simgrid::s4u::Mutex mutex_; }; } -- 2.20.1