Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Various sonar cleanups
[simgrid.git] / src / kernel / activity / MutexImpl.hpp
index 5ab4b5d..8bf71be 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -9,11 +9,10 @@
 #include "simgrid/s4u/Mutex.hpp"
 #include "src/kernel/activity/ActivityImpl.hpp"
 #include "src/kernel/actor/ActorImpl.hpp"
+#include "xbt/asserts.h"
 #include <boost/intrusive/list.hpp>
 
-namespace simgrid {
-namespace kernel {
-namespace activity {
+namespace simgrid::kernel::activity {
 
 /** Mutex Acquisition: the act / process of acquiring the mutex.
  *
@@ -41,21 +40,25 @@ namespace activity {
  * of a set if some transitions may become disabled in between, while you don't have to reconsider them if you can reuse
  * your previous computations).
  */
-class XBT_PUBLIC MutexAcquisitionImpl
-    : public ActivityImpl_T<MutexAcquisitionImpl> { // Acquisition: n. The act or process of acquiring.
+class XBT_PUBLIC MutexAcquisitionImpl : public ActivityImpl_T<MutexAcquisitionImpl> {
   actor::ActorImpl* issuer_ = nullptr;
   MutexImpl* mutex_         = nullptr;
+  int recursive_depth_      = 1;
+  // TODO: use granted_ this instead of owner_ == self to test().
+  // This is mandatory to get double-lock on non-recursive locks to properly deadlock
+  bool granted_ = false;
+
+  friend MutexImpl;
 
 public:
   MutexAcquisitionImpl(actor::ActorImpl* issuer, MutexImpl* mutex) : issuer_(issuer), mutex_(mutex) {}
-  MutexImplPtr get_mutex() { return mutex_; }
-  actor::ActorImpl* get_issuer() { return issuer_; }
+  MutexImplPtr get_mutex() const { return mutex_; }
+  actor::ActorImpl* get_issuer() const { return issuer_; }
+  void grant() { granted_ = true; }
+  bool is_granted() const { return granted_; }
 
   bool test(actor::ActorImpl* issuer = nullptr) override;
   void wait_for(actor::ActorImpl* issuer, double timeout) override;
-  void post() override
-  { /*no surf action*/
-  }
   void finish() override;
   void set_exception(actor::ActorImpl* issuer) override
   { /* nothing to do */
@@ -66,15 +69,16 @@ class XBT_PUBLIC MutexImpl {
   std::atomic_int_fast32_t refcount_{1};
   s4u::Mutex piface_;
   actor::ActorImpl* owner_ = nullptr;
-  // List of sleeping actors:
-  std::deque<MutexAcquisitionImplPtr> sleeping_;
+  std::deque<MutexAcquisitionImplPtr> ongoing_acquisitions_;
   static unsigned next_id_;
-  unsigned id_;
+  unsigned id_ = next_id_++;
+  bool is_recursive_  = false;
+  int recursive_depth = 0;
 
   friend MutexAcquisitionImpl;
 
 public:
-  MutexImpl() : piface_(this), id_(next_id_++) {}
+  explicit MutexImpl(bool recursive = false) : piface_(this), is_recursive_(recursive) {}
   MutexImpl(MutexImpl const&) = delete;
   MutexImpl& operator=(MutexImpl const&) = delete;
 
@@ -83,9 +87,6 @@ public:
   void unlock(actor::ActorImpl* issuer);
   unsigned get_id() const { return id_; }
 
-  MutexImpl* ref();
-  void unref();
-
   actor::ActorImpl* get_owner() const { return owner_; }
 
   // boost::intrusive_ptr<Mutex> support:
@@ -97,13 +98,15 @@ public:
 
   friend void intrusive_ptr_release(MutexImpl* mutex)
   {
-    if (mutex->refcount_.fetch_sub(1) == 1)
+    if (mutex->refcount_.fetch_sub(1) == 1) {
+      xbt_assert(mutex->ongoing_acquisitions_.empty(), "The destroyed mutex still had ongoing acquisitions");
+      xbt_assert(mutex->owner_ == nullptr, "The destroyed mutex is still owned by actor %s",
+                 mutex->owner_->get_cname());
       delete mutex;
+    }
   }
 
-  s4u::Mutex& mutex() { return piface_; }
+  s4u::Mutex& get_iface() { return piface_; }
 };
-} // namespace activity
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::activity
 #endif