+namespace simgrid::kernel::activity {
+
+/** Mutex Acquisition: the act / process of acquiring the mutex.
+ *
+ * You can declare some interest on a mutex without being blocked waiting if it's already occupied.
+ * If it gets freed by its current owned, you become the new owner, even if you're still not blocked on it.
+ * Nobody can lock it behind your back or overpass you in the queue in any way, even if you're still not blocked on it.
+ *
+ * Afterward, when you do consider the lock, the test() or wait() operations are both non-blocking since you're the
+ * owner. People who declared interest in the mutex after you get stuck in the queue behind you.
+ *
+ *
+ * Splitting the locking process this way is interesting for symmetry with the other activities such as exec or
+ * communication that do have an async variant and could be mildly interesting to the users once exposed in S4U, but
+ * that's not the only reason. It's also very important to the MC world: the Mutex::lock_async() is always enabled
+ * (nothing can prevent you from adding yourself to the queue of potential owners) while Acquisition::wait() is
+ * persistent: it's not always enabled but once it gets enabled (because you're the owner), it remains enabled for ever.
+ *
+ * Mutex::lock() is not persistent: sometimes it's enabled if the mutex is free, and then it gets disabled if
+ * someone else locks the mutex, and then it becomes enabled again once the mutex is freed. This is why Mutex::lock()
+ * is not used in our MC computational model: we ban non-persistent transitions because they would make some
+ * computations much more complex.
+ *
+ * In particular, computing the extension of an unfolding's configuration is polynomial when you only have persistent
+ * transitions while it's O(2^n) when some of the transitions are non-persistent (you have to consider again all subsets
+ * 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> {
+ 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;