X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/13cf919b6231022290ec292eb1fb48abbb39f8eb..35a644bdf9d0c5603c9483f03f913e4a649638d6:/src/kernel/activity/MutexImpl.cpp diff --git a/src/kernel/activity/MutexImpl.cpp b/src/kernel/activity/MutexImpl.cpp index 1c9235b95c..cac3e9524d 100644 --- a/src/kernel/activity/MutexImpl.cpp +++ b/src/kernel/activity/MutexImpl.cpp @@ -25,15 +25,11 @@ void MutexAcquisitionImpl::wait_for(actor::ActorImpl* issuer, double timeout) this->register_simcall(&issuer_->simcall_); // Block on that acquisition if (mutex_->get_owner() == issuer_) { // I'm the owner - post(); + finish(); } else { // Already in the queue } } -void MutexAcquisitionImpl::post() -{ - finish(); -} void MutexAcquisitionImpl::finish() { @@ -51,13 +47,41 @@ unsigned MutexImpl::next_id_ = 0; MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer) { - auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); - - if (owner_ != nullptr) { - /* Somebody is using the mutex; register the acquisition */ + /* 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); - } else { + return res; + } + + // 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; } @@ -69,14 +93,14 @@ MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer) */ bool MutexImpl::try_lock(actor::ActorImpl* issuer) { - XBT_IN("(%p, %p)", this, issuer); - 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; } @@ -92,14 +116,22 @@ 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 (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 = ongoing_acquisitions_.front(); ongoing_acquisitions_.pop_front(); owner_ = acq->get_issuer(); + acq->grant(); + recursive_depth = acq->recursive_depth_; if (acq == owner_->waiting_synchro_) - acq->post(); + acq->finish(); // else, the issuer is not blocked on this acquisition so no need to release it } else {