1 /* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "src/kernel/activity/MutexImpl.hpp"
7 #include "src/kernel/activity/SynchroRaw.hpp"
10 #include "simgrid/modelchecker.h"
11 #include "src/mc/mc_safety.hpp"
12 #define MC_CHECK_NO_DPOR() \
13 xbt_assert(not MC_is_active() || mc::reduction_mode != mc::ReductionMode::dpor, \
14 "Mutex is currently not supported with DPOR, use --cfg=model-check/reduction:none")
16 #define MC_CHECK_NO_DPOR() (void)0
19 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_mutex, ker_synchro, "Mutex kernel-space implementation");
25 void MutexImpl::lock(actor::ActorImpl* issuer)
27 XBT_IN("(%p; %p)", this, issuer);
31 /* FIXME: check if the host is active ? */
32 /* Somebody using the mutex, use a synchronization to get host failures */
33 RawImplPtr synchro(new RawImpl([this, issuer]() { this->remove_sleeping_actor(*issuer); }));
34 (*synchro).set_host(issuer->get_host()).start();
35 synchro->register_simcall(&issuer->simcall_);
36 sleeping_.push_back(*issuer);
41 issuer->simcall_answer();
46 /** Tries to lock the mutex for a actor
48 * @param issuer the actor that tries to acquire the mutex
49 * @return whether we managed to lock the mutex
51 bool MutexImpl::try_lock(actor::ActorImpl* issuer)
53 XBT_IN("(%p, %p)", this, issuer);
66 /** Unlock a mutex for a actor
68 * Unlocks the mutex and gives it to a actor waiting for it.
69 * If the unlocker is not the owner of the mutex nothing happens.
70 * If there are no actor waiting, it sets the mutex as free.
72 void MutexImpl::unlock(actor::ActorImpl* issuer)
74 XBT_IN("(%p, %p)", this, issuer);
75 xbt_assert(locked_, "Cannot release that mutex: it was not locked.");
76 xbt_assert(issuer == owner_, "Cannot release that mutex: it was locked by %s (pid:%ld), not by you.",
77 owner_->get_cname(), owner_->get_pid());
79 if (not sleeping_.empty()) {
80 /* Give the ownership to the first waiting actor */
81 owner_ = &sleeping_.front();
82 sleeping_.pop_front();
83 owner_->waiting_synchro_ = nullptr;
84 owner_->simcall_answer();
86 /* nobody to wake up */
92 /** Increase the refcount for this mutex */
93 MutexImpl* MutexImpl::ref()
95 intrusive_ptr_add_ref(this);
99 /** Decrease the refcount for this mutex */
100 void MutexImpl::unref()
102 intrusive_ptr_release(this);
105 } // namespace activity
106 } // namespace kernel
107 } // namespace simgrid