Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[s4u] Use simix simix::Mutex refcount support for s4u::Mutex
authorGabriel Corona <gabriel.corona@loria.fr>
Wed, 15 Jun 2016 14:44:44 +0000 (16:44 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Wed, 15 Jun 2016 14:44:44 +0000 (16:44 +0200)
examples/s4u/mutex/s4u_mutex.cpp
include/simgrid/s4u/mutex.hpp
src/s4u/s4u_mutex.cpp
src/simix/smx_process.cpp

index 10c4f98..222deae 100644 (file)
@@ -16,40 +16,39 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
 
 //Create an actor as a c++ functor
 class Worker {
-simgrid::s4u::Mutex *pMtx;
+  simgrid::s4u::Mutex mutex_;
 int *pResults;
 public:
-  Worker(int  *res, simgrid::s4u::Mutex *mtx) : pMtx(mtx),  pResults(res) {};
+  Worker(int  *res, simgrid::s4u::Mutex mutex) :
+    mutex_(std::move(mutex)),  pResults(res) {};
   // Define the code of the actor
   void operator()() {
     // Do the calculation
     simgrid::s4u::this_actor::execute(1000);
 
-    // lock the mutex before enter in th critical section
-    pMtx->lock();
+    // lock the mutex before enter in the critical section
+    std::lock_guard<simgrid::s4u::Mutex> lock(mutex_);
     XBT_INFO("Hello s4u, I'm ready to compute");
 
     // And finaly add it to the results
     *pResults += 1;
     XBT_INFO("I'm done, good bye");
-
-    //Then unlock the mutex, so other threads will be able to update their results
-    pMtx->unlock();
   }
 };
 
 // This class is an example of how to use lock_guard with simgrid mutex
 class WorkerLockGuard {
-simgrid::s4u::Mutex *pMtx;
+  simgrid::s4u::Mutex mutex_;
 int *pResults;
 public:
-  WorkerLockGuard(int  *res, simgrid::s4u::Mutex *mtx) : pMtx(mtx),  pResults(res) {};
+  WorkerLockGuard(int  *res, simgrid::s4u::Mutex mutex) :
+    mutex_(std::move(mutex)),  pResults(res) {};
   void operator()() {
 
     simgrid::s4u::this_actor::execute(1000);
 
     // Simply use the std::lock_guard like this
-    std::lock_guard<simgrid::s4u::Mutex> lock(*pMtx);
+    std::lock_guard<simgrid::s4u::Mutex> lock(mutex_);
 
     // then you are in a safe zone
     XBT_INFO("Hello s4u, I'm ready to compute");
@@ -63,16 +62,20 @@ class MainActor {
 public:
   void operator()() {
     int *res = new int;
-    simgrid::s4u::Mutex *mtx = new simgrid::s4u::Mutex();
+    simgrid::s4u::Mutex mutex;
     *res = 0;
     simgrid::s4u::Actor* workers[NB_ACTOR*2];
 
     for (int i = 0; i < NB_ACTOR * 2 ; i++) {
       // To create a worker use the static method simgrid::s4u::Actor.
       if((i % 2) == 0 )
-        workers[i] = new simgrid::s4u::Actor("worker", simgrid::s4u::Host::by_name("Jupiter"), WorkerLockGuard(res,mtx));
+        workers[i] = new simgrid::s4u::Actor("worker",
+          simgrid::s4u::Host::by_name("Jupiter"),
+          WorkerLockGuard(res, mutex));
       else
-        workers[i] = new simgrid::s4u::Actor("worker", simgrid::s4u::Host::by_name("Tremblay"), Worker(res,mtx));
+        workers[i] = new simgrid::s4u::Actor("worker",
+          simgrid::s4u::Host::by_name("Tremblay"),
+          Worker(res,mutex));
     }
 
     for (int i = 0; i < NB_ACTOR ; i++) {
@@ -81,7 +84,6 @@ public:
 
     simgrid::s4u::this_actor::sleep(10);
     XBT_INFO("Results is -> %d", *res);
-    delete mtx;
   }
 };
 
index 52accd1..da7c3df 100644 (file)
@@ -6,30 +6,55 @@
 #ifndef SIMGRID_S4U_MUTEX_HPP
 #define SIMGRID_S4U_MUTEX_HPP
 
+#include <utility>
+
+#include <boost/intrusive_ptr.hpp>
 #include <xbt/base.h>
 #include "simgrid/simix.h"
 
-
 namespace simgrid {
 namespace s4u {
 
 XBT_PUBLIC_CLASS Mutex {
 
 public:
-  Mutex();
-  ~Mutex() {};
-
-protected:
+  Mutex() :
+    mutex_(simcall_mutex_init()) {}
+  Mutex(simgrid::simix::Mutex* mutex) : mutex_(SIMIX_mutex_dup(mutex)) {}
+  ~Mutex()
+  {
+    SIMIX_mutex_destroy(mutex_);
+  }
+
+  // Copy+move (with the copy-and-swap idiom):
+  Mutex(Mutex const& mutex) : mutex_(SIMIX_mutex_dup(mutex.mutex_)) {}
+  friend void swap(Mutex& first, Mutex& second)
+  {
+    using std::swap;
+    swap(first.mutex_, second.mutex_);
+  }
+  Mutex& operator=(Mutex mutex)
+  {
+    swap(*this, mutex);
+    return *this;
+  }
+  Mutex(Mutex&& mutex) : mutex_(nullptr)
+  {
+    swap(*this, mutex);
+  }
+
+  bool valid() const
+  {
+    return mutex_ != nullptr;
+  }
 
 public:
-
   void lock();
   void unlock();
   bool try_lock();
 
 private:
-  std::shared_ptr<simgrid::simix::Mutex> _mutex;
-
+  simgrid::simix::Mutex* mutex_;
 };
 }} // namespace simgrid::s4u
 
index 20f6ee2..e64bfd4 100644 (file)
 
 #include "simgrid/s4u/mutex.hpp"
 
+namespace simgrid {
+namespace s4u {
 
-using namespace simgrid;
-
-s4u::Mutex::Mutex() {
-    smx_mutex_t smx_mutex = simcall_mutex_init();
-    _mutex = std::shared_ptr<simgrid::simix::Mutex>(smx_mutex, SIMIX_mutex_destroy  );
+void Mutex::lock() {
+  simcall_mutex_lock(mutex_);
 }
 
-void s4u::Mutex::lock() {
-  simcall_mutex_lock(_mutex.get());
+void Mutex::unlock() {
+  simcall_mutex_unlock(mutex_);
 }
 
-void s4u::Mutex::unlock() {
-  simcall_mutex_unlock(_mutex.get());
+bool Mutex::try_lock() {
+  return simcall_mutex_trylock(mutex_);
 }
 
-bool s4u::Mutex::try_lock() {
-  return simcall_mutex_trylock(_mutex.get());
+}
 }
index 836d2d0..b47211a 100644 (file)
@@ -136,9 +136,12 @@ namespace simix {
 Process::~Process()
 {
   delete this->context;
-  xbt_dict_free(&this->properties);
-  xbt_fifo_free(this->comms);
-  xbt_dynar_free(&this->on_exit);
+  if (this->properties)
+    xbt_dict_free(&this->properties);
+  if (this->comms != nullptr)
+    xbt_fifo_free(this->comms);
+  if (this->on_exit)
+    xbt_dynar_free(&this->on_exit);
 }
 
 void create_maestro(std::function<void()> code)