X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/f84705b633d5ebb1f5e71eaeac8204014285f225..35a644bdf9d0c5603c9483f03f913e4a649638d6:/src/kernel/activity/MutexImpl.cpp diff --git a/src/kernel/activity/MutexImpl.cpp b/src/kernel/activity/MutexImpl.cpp index 74af186015..cac3e9524d 100644 --- a/src/kernel/activity/MutexImpl.cpp +++ b/src/kernel/activity/MutexImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-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. */ @@ -6,21 +6,11 @@ #include "src/kernel/activity/MutexImpl.hpp" #include "src/kernel/activity/Synchro.hpp" -#if SIMGRID_HAVE_MC -#include "simgrid/modelchecker.h" -#include "src/mc/mc_safety.hpp" -#define MC_CHECK_NO_DPOR() \ - xbt_assert(not MC_is_active() || mc::reduction_mode != mc::ReductionMode::dpor, \ - "Mutex is currently not supported with DPOR, use --cfg=model-check/reduction:none") -#else -#define MC_CHECK_NO_DPOR() (void)0 -#endif - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_mutex, ker_synchro, "Mutex kernel-space implementation"); -namespace simgrid { -namespace kernel { -namespace activity { +namespace simgrid::kernel::activity { + +/* -------- Acquisition -------- */ bool MutexAcquisitionImpl::test(actor::ActorImpl*) { @@ -40,27 +30,58 @@ void MutexAcquisitionImpl::wait_for(actor::ActorImpl* issuer, double timeout) // Already in the queue } } + void MutexAcquisitionImpl::finish() { xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size()); - smx_simcall_t simcall = simcalls_.front(); + actor::Simcall* simcall = simcalls_.front(); simcalls_.pop_front(); simcall->issuer_->waiting_synchro_ = nullptr; simcall->issuer_->simcall_answer(); } +/* -------- Mutex -------- */ + unsigned MutexImpl::next_id_ = 0; MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer) { - auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + /* If the mutex is recursive */ + if (is_recursive_) { + if (owner_ == issuer) { + recursive_depth++; + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + res->grant(); + return res; + } else if (owner_ == nullptr) { // Free + owner_ = issuer; + recursive_depth = 1; + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + res->grant(); + return res; + } + + for (auto acq : ongoing_acquisitions_) + if (acq->get_issuer() == issuer) { + acq->recursive_depth_++; + return acq; + } + + // Not yet in the ongoing acquisition list. Get in there + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + ongoing_acquisitions_.push_back(res); + return res; + } - if (owner_ != nullptr) { - /* Somebody is using the mutex; register the acquisition */ - sleeping_.push_back(res); - } else { + // Non-recursive mutex + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + if (owner_ == nullptr) { // Lock is free, take it owner_ = issuer; + recursive_depth = 1; + res->grant(); + } else { // Somebody is using the mutex; register the acquisition + ongoing_acquisitions_.push_back(res); } return res; } @@ -72,15 +93,14 @@ MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer) */ bool MutexImpl::try_lock(actor::ActorImpl* issuer) { - XBT_IN("(%p, %p)", this, issuer); - MC_CHECK_NO_DPOR(); - if (owner_ != nullptr) { - XBT_OUT(); - return false; + if (owner_ == issuer && is_recursive_) { + recursive_depth++; + return true; } + if (owner_ != nullptr) + return false; - owner_ = issuer; - XBT_OUT(); + owner_ = issuer; return true; } @@ -96,12 +116,20 @@ void MutexImpl::unlock(actor::ActorImpl* issuer) xbt_assert(issuer == owner_, "Cannot release that mutex: you're not the owner. %s is (pid:%ld).", owner_ != nullptr ? owner_->get_cname() : "(nobody)", owner_ != nullptr ? owner_->get_pid() : -1); - if (not sleeping_.empty()) { + if (is_recursive_) { + recursive_depth--; + if (recursive_depth > 0) // Still owning the lock + return; + } + + if (not ongoing_acquisitions_.empty()) { /* Give the ownership to the first waiting actor */ - auto acq = sleeping_.front(); - sleeping_.pop_front(); + auto acq = ongoing_acquisitions_.front(); + ongoing_acquisitions_.pop_front(); owner_ = acq->get_issuer(); + acq->grant(); + recursive_depth = acq->recursive_depth_; if (acq == owner_->waiting_synchro_) acq->finish(); // else, the issuer is not blocked on this acquisition so no need to release it @@ -113,6 +141,4 @@ void MutexImpl::unlock(actor::ActorImpl* issuer) XBT_OUT(); } -} // namespace activity -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::activity