diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-12-09 15:37:09 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-12-09 20:22:58 -0500 |
commit | 5b44e4b489ef6a8eca4e48d3124665f404cc2c92 (patch) | |
tree | af2c6ada1948aa2c0f1a2de6ccab527f8c666912 /src/mongo/db | |
parent | 604fc8c629b4cd90a3fbd84e53eb4c892878a318 (diff) | |
download | mongo-5b44e4b489ef6a8eca4e48d3124665f404cc2c92.tar.gz |
SERVER-16482 Do not look further in the conflict queue if X lock was just granted
This is a small optimization, which would help with the LM cost in the
presence of X-lock conflicts, such as the MMAP V1 collection lock.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/concurrency/lock_mgr_new.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/mongo/db/concurrency/lock_mgr_new.cpp b/src/mongo/db/concurrency/lock_mgr_new.cpp index ac64ce1fc6b..887461167ef 100644 --- a/src/mongo/db/concurrency/lock_mgr_new.cpp +++ b/src/mongo/db/concurrency/lock_mgr_new.cpp @@ -732,7 +732,17 @@ namespace { } } - // Grant any conflicting requests, which might now be unblocked + // Grant any conflicting requests, which might now be unblocked. Note that the loop below + // slightly violates fairness in that it will grant *all* compatible requests on the line + // even though there might be conflicting ones interspersed between them. For example, + // consider an X lock was just freed and the conflict queue looked like this: + // + // IS -> IS -> X -> X -> S -> IS + // + // In strict FIFO, we should grant the first two IS modes and then stop when we reach the + // first X mode (the third request on the queue). However, the loop below would actually + // grant all IS + S modes and once they all drain it will grant X. + LockRequest* iterNext = NULL; for (LockRequest* iter = lock->conflictList._front; @@ -745,7 +755,9 @@ namespace { // the granted queue. iterNext = iter->next; - if (conflicts(iter->mode, lock->grantedModes)) continue; + if (conflicts(iter->mode, lock->grantedModes)) { + continue; + } iter->status = LockRequest::STATUS_GRANTED; @@ -760,6 +772,12 @@ namespace { } iter->notify->notify(lock->resourceId, LOCK_OK); + + // Small optimization - nothing is compatible with MODE_X, so no point in looking + // further in the conflict queue. + if (iter->mode == MODE_X) { + break; + } } // This is a convenient place to check that the state of the two request queues is in sync |