Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
further improve the doc of s4u::Mutex
authorMartin Quinson <martin.quinson@loria.fr>
Sun, 7 Aug 2016 16:35:56 +0000 (18:35 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Sun, 7 Aug 2016 16:35:56 +0000 (18:35 +0200)
doc/doxygen/module-s4u.doc
doc/doxygen/uhood_switch.doc
include/simgrid/s4u/Mutex.hpp
src/s4u/s4u_mutex.cpp

index 324edb0..213049a 100644 (file)
@@ -10,9 +10,31 @@ SimGrid will be possible in S4U.
         that path unless you know what you are doing.  If unsure,
         proceed to @ref MSG_API instead.
 
-
 Unsurprisingly, the S4U interface matches the concepts presented in 
 @ref starting_components "the introduction". You should read this page
 first, to not get lost in the amount of classes provided here.
 
+@section s4u_raii Memory Management of S4U objects
+
+For sake of simplicity, we use
+[RAII](https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)
+everywhere in S4U. This is an idiom where resources are automatically
+managed through the context. Provided that you never manipulate
+objects of type Foo directly but always FooPtr references, you will
+never have to explicitely release the resource that you use nor to
+free the memory of unused objects.
+
+Here is a little example:
+
+@code{cpp}
+void myFunc() 
+{
+  simgrid::s4u::MutexPtr mutex = simgrid::s4u::Mutex::createMutex(); // Too bad we cannot use `new` here
+
+  mutex->lock();   // use the mutex as a simple reference
+  //  bla bla
+  mutex->unlock(); 
+  
+} // The mutex will get automatically freed because the only existing reference gets out of scope
+@endcode
 */
index bc6b8f3..43fac9b 100644 (file)
@@ -621,79 +621,6 @@ instead of one to do the same job (one in `kernelAsync()` and one in
 
 ## Mutexes and condition variables
 
-## Mutexes
-
-SimGrid has had a C-based API for mutexes and condition variables for
-some time.  These mutexes are different from the standard
-system-level mutex (`std::mutex`, `pthread_mutex_t`, etc.) because
-they work at simulation-level.  Locking on a simulation mutex does
-not block the thread directly but makes a simcall
-(`simcall_mutex_lock()`) which asks the simulation kernel to wake the calling
-actor when it can get ownership of the mutex. Blocking directly at the
-OS level would deadlock the simulation.
-
-Reusing the C++ standard API for our simulation mutexes has many
-benefits:
-
- * it makes it easier for people familiar with the `std::mutex` to
-   understand and use SimGrid mutexes;
-
- * we can benefit from a proven API;
-
- * we can reuse from generic library code in SimGrid.
-
-We defined a reference-counted `Mutex` class for this (which supports
-the [`Lockable`](http://en.cppreference.com/w/cpp/concept/Lockable)
-requirements, see
-[`[thread.req.lockable.req]`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf#page=1175)
-in the C++14 standard):
-
-@code{cpp}
-class Mutex {
-  friend ConditionVariable;
-private:
-  friend simgrid::simix::Mutex;
-  simgrid::simix::Mutex* mutex_;
-  Mutex(simgrid::simix::Mutex* mutex) : mutex_(mutex) {}
-public:
-
-  friend void intrusive_ptr_add_ref(Mutex* mutex);
-  friend void intrusive_ptr_release(Mutex* mutex);
-  using Ptr = boost::intrusive_ptr<Mutex>;
-
-  // No copy:
-  Mutex(Mutex const&) = delete;
-  Mutex& operator=(Mutex const&) = delete;
-
-  static Ptr createMutex();
-
-public:
-  void lock();
-  void unlock();
-  bool try_lock();
-};
-@endcode
-
-The methods are simply wrappers around existing simcalls:
-
-@code{cpp}
-void Mutex::lock()
-{
-  simcall_mutex_lock(mutex_);
-}
-@endcode
-
-Using the same API as `std::mutex` (`Lockable`) means we can use existing
-C++-standard code such as `std::unique_lock<Mutex>` or
-`std::lock_guard<Mutex>` for exception-safe mutex handling[^lock]:
-
-@code{cpp}
-{
-  std::lock_guard<simgrid::s4u::Mutex> lock(*mutex);
-  sum += 1;
-}
-@endcode
-
 ### Condition Variables
 
 Similarly SimGrid already had simulation-level condition variables
index 0b3ebc8..93db75e 100644 (file)
@@ -28,6 +28,9 @@ class ConditionVariable;
  * Instead, you should use the present class, that is a drop-in replacement of
  * [std::mutex](http://en.cppreference.com/w/cpp/thread/mutex).
  *
+ * As for any S4U object, Mutexes are using the @ref "RAII idiom" s4u_raii for memory management.
+ * Use createMutex() to get a ::MutexPtr to a newly created mutex and only manipulate ::MutexPtr.
+ *
  */
 XBT_PUBLIC_CLASS Mutex {
 friend ConditionVariable;
index ba83148..4f2cce6 100644 (file)
 namespace simgrid {
 namespace s4u {
 
+/** @brief Blocks the calling actor until the mutex can be obtained */
 void Mutex::lock()
 {
   simcall_mutex_lock(mutex_);
 }
 
+/** @brief Release the ownership of the mutex, unleashing a blocked actor (if any)
+ *
+ * Will fail if the calling actor does not own the mutex.
+ */
 void Mutex::unlock()
 {
   simcall_mutex_unlock(mutex_);
 }
 
+/** @brief Acquire the mutex if it's free, and return false (without blocking) if not */
 bool Mutex::try_lock()
 {
   return simcall_mutex_trylock(mutex_);
 }
 
+/** @brief Create a new mutex
+ *
+ * See @ref s4u_raii.
+ */
 MutexPtr Mutex::createMutex()
 {
   smx_mutex_t mutex = simcall_mutex_init();