Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[s4u] Allocate Mutex on the heap and return MutexPtr
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 4 Jul 2016 09:34:12 +0000 (11:34 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Wed, 6 Jul 2016 08:29:22 +0000 (10:29 +0200)
examples/s4u/actions-comm/s4u_actions-comm.cpp
examples/s4u/mutex/s4u_mutex.cpp
include/simgrid/s4u/mutex.hpp
src/s4u/s4u_mutex.cpp
src/simix/smx_synchro.cpp
src/simix/smx_synchro_private.h

index 826d6c9..0f64779 100644 (file)
@@ -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;
   }
 }
 
index 51989fa..c9073e4 100644 (file)
 
 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<simgrid::s4u::Mutex> lock(mutex);
+  std::lock_guard<simgrid::s4u::Mutex> 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<simgrid::s4u::Mutex> lock(mutex);
+  std::lock_guard<simgrid::s4u::Mutex> 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.
index e6a1ed5..5b0f7f5 100644 (file)
@@ -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<Mutex>;
 
-  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 */
index e64bfd4..3b1d9f1 100644 (file)
@@ -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);
+}
+
 }
 }
index 305fc32..143e0ab 100644 (file)
@@ -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:
index 73f87c1..338a0b4 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <atomic>
 
+#include <simgrid/s4u/mutex.hpp>
+
 #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_;
 };
 
 }