diff options
author | Jordi Olivares Provencio <jordi.olivares-provencio@mongodb.com> | 2022-03-16 12:10:51 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-16 12:55:06 +0000 |
commit | 8f472181ea556fc01a1de53ab960e7b5d610b74b (patch) | |
tree | 7f119ec0cb152df1c4c19578888af308cc00fbf7 /src/mongo/db/concurrency | |
parent | e102dbba6cd1f5b99991089b90e841007bef16d7 (diff) | |
download | mongo-8f472181ea556fc01a1de53ab960e7b5d610b74b.tar.gz |
SERVER-64170 Refactor static variables into decorations
Diffstat (limited to 'src/mongo/db/concurrency')
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency_test.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_manager.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_manager.h | 16 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_state.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/concurrency/locker.h | 9 |
5 files changed, 44 insertions, 28 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency_test.cpp b/src/mongo/db/concurrency/d_concurrency_test.cpp index 9c1e131fdf6..9b359b9b6c4 100644 --- a/src/mongo/db/concurrency/d_concurrency_test.cpp +++ b/src/mongo/db/concurrency/d_concurrency_test.cpp @@ -70,18 +70,18 @@ const auto kMaxClockJitterMillis = Milliseconds(0); class UseGlobalThrottling { public: explicit UseGlobalThrottling(OperationContext* opCtx, int numTickets) : _opCtx(opCtx) { - _holder = std::make_unique<SemaphoreTicketHolder>(numTickets); - _opCtx->lockState()->setGlobalThrottling(_holder.get(), _holder.get()); + auto lockManager = LockManager::get(_opCtx); + lockManager->setTicketHolders(std::make_unique<SemaphoreTicketHolder>(numTickets), + std::make_unique<SemaphoreTicketHolder>(numTickets)); } ~UseGlobalThrottling() noexcept(false) { // Reset the global setting as we're about to destroy the ticket holder. - _opCtx->lockState()->setGlobalThrottling(nullptr, nullptr); - ASSERT_EQ(_holder->used(), 0); + auto lockManager = LockManager::get(_opCtx); + lockManager->setTicketHolders(nullptr, nullptr); } private: OperationContext* _opCtx; - std::unique_ptr<TicketHolder> _holder; }; diff --git a/src/mongo/db/concurrency/lock_manager.cpp b/src/mongo/db/concurrency/lock_manager.cpp index 0737febeb25..5650d282ee6 100644 --- a/src/mongo/db/concurrency/lock_manager.cpp +++ b/src/mongo/db/concurrency/lock_manager.cpp @@ -47,6 +47,7 @@ #include "mongo/db/service_context.h" #include "mongo/logv2/log.h" #include "mongo/util/assert_util.h" +#include "mongo/util/concurrency/ticketholder.h" #include "mongo/util/decorable.h" #include "mongo/util/str.h" #include "mongo/util/timer.h" @@ -878,6 +879,24 @@ void LockManager::getLockInfoBSON(const std::map<LockerId, BSONObj>& lockToClien _buildLocksArray(lockToClientMap, false, this, &lockInfoArr); } +void LockManager::setTicketHolders(std::unique_ptr<TicketHolder> reading, + std::unique_ptr<TicketHolder> writing) { + _readingTicketholder = std::move(reading); + _writingTicketholder = std::move(writing); +} + +TicketHolder* LockManager::getTicketHolder(LockMode mode) { + switch (mode) { + case MODE_IS: + case MODE_S: + return _readingTicketholder.get(); + case MODE_IX: + return _writingTicketholder.get(); + default: + return nullptr; + } +} + void LockManager::_buildLocksArray(const std::map<LockerId, BSONObj>& lockToClientMap, bool forLogging, LockManager* mutableThis, diff --git a/src/mongo/db/concurrency/lock_manager.h b/src/mongo/db/concurrency/lock_manager.h index e54524489c1..594e42057b8 100644 --- a/src/mongo/db/concurrency/lock_manager.h +++ b/src/mongo/db/concurrency/lock_manager.h @@ -49,6 +49,7 @@ namespace mongo { class OperationContext; class ServiceContext; +class TicketHolder; /** * Entry point for the lock manager scheduling functionality. Don't use it directly, but @@ -167,6 +168,18 @@ public: void getLockInfoBSON(const std::map<LockerId, BSONObj>& lockToClientMap, BSONObjBuilder* result); + /** + * Sets the TicketHolder implementation to use to obtain tickets from 'reading' (for MODE_S and + * MODE_IS), and from 'writing' (for MODE_IX) in order to throttle database access. There is no + * throttling for MODE_X, as there can only ever be a single locker using this mode. The + * throttling is intended to defend against large drops in throughput under high load due to too + * much concurrency. + */ + void setTicketHolders(std::unique_ptr<TicketHolder> readTickets, + std::unique_ptr<TicketHolder> writeTickets); + + TicketHolder* getTicketHolder(LockMode mode); + private: // The lockheads need access to the partitions friend struct LockHead; @@ -237,5 +250,8 @@ private: static const unsigned _numPartitions; Partition* _partitions; + + std::unique_ptr<TicketHolder> _readingTicketholder; + std::unique_ptr<TicketHolder> _writingTicketholder; }; } // namespace mongo diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp index 14d51efd41a..d1f6059ea6c 100644 --- a/src/mongo/db/concurrency/lock_state.cpp +++ b/src/mongo/db/concurrency/lock_state.cpp @@ -286,22 +286,10 @@ void CondVarLockGrantNotification::notify(ResourceId resId, LockResult result) { _cond.notify_all(); } -namespace { -TicketHolder* ticketHolders[LockModesCount] = {}; -} // namespace - - // // Locker // -/* static */ -void Locker::setGlobalThrottling(class TicketHolder* reading, class TicketHolder* writing) { - ticketHolders[MODE_S] = reading; - ticketHolders[MODE_IS] = reading; - ticketHolders[MODE_IX] = writing; -} - LockerImpl::LockerImpl() : _id(idCounter.addAndFetch(1)), _wuowNestingLevel(0), _threadId(stdx::this_thread::get_id()) {} @@ -371,7 +359,8 @@ void LockerImpl::reacquireTicket(OperationContext* opCtx) { bool LockerImpl::_acquireTicket(OperationContext* opCtx, LockMode mode, Date_t deadline) { const bool reader = isSharedLockMode(mode); - auto holder = shouldAcquireTicket() ? ticketHolders[mode] : nullptr; + auto lockManager = getGlobalLockManager(); + auto holder = shouldAcquireTicket() ? lockManager->getTicketHolder(mode) : nullptr; if (holder) { _clientState.store(reader ? kQueuedReader : kQueuedWriter); @@ -1080,7 +1069,8 @@ void LockerImpl::releaseTicket() { } void LockerImpl::_releaseTicket() { - auto holder = shouldAcquireTicket() ? ticketHolders[_modeForTicket] : nullptr; + auto ticketManager = getGlobalLockManager(); + auto holder = shouldAcquireTicket() ? ticketManager->getTicketHolder(_modeForTicket) : nullptr; if (holder) { holder->release(); } diff --git a/src/mongo/db/concurrency/locker.h b/src/mongo/db/concurrency/locker.h index 37b6dbeedb8..bba99d01fdb 100644 --- a/src/mongo/db/concurrency/locker.h +++ b/src/mongo/db/concurrency/locker.h @@ -68,15 +68,6 @@ public: } /** - * Require global lock attempts to obtain tickets from 'reading' (for MODE_S and MODE_IS), - * and from 'writing' (for MODE_IX), which must have static lifetimes. There is no throttling - * for MODE_X, as there can only ever be a single locker using this mode. The throttling is - * intended to defend against large drops in throughput under high load due to too much - * concurrency. - */ - static void setGlobalThrottling(class TicketHolder* reading, class TicketHolder* writing); - - /** * State for reporting the number of active and queued reader and writer clients. */ enum ClientState { kInactive, kActiveReader, kActiveWriter, kQueuedReader, kQueuedWriter }; |