summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency
diff options
context:
space:
mode:
authorJordi Olivares Provencio <jordi.olivares-provencio@mongodb.com>2022-03-16 12:10:51 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-16 12:55:06 +0000
commit8f472181ea556fc01a1de53ab960e7b5d610b74b (patch)
tree7f119ec0cb152df1c4c19578888af308cc00fbf7 /src/mongo/db/concurrency
parente102dbba6cd1f5b99991089b90e841007bef16d7 (diff)
downloadmongo-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.cpp10
-rw-r--r--src/mongo/db/concurrency/lock_manager.cpp19
-rw-r--r--src/mongo/db/concurrency/lock_manager.h16
-rw-r--r--src/mongo/db/concurrency/lock_state.cpp18
-rw-r--r--src/mongo/db/concurrency/locker.h9
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 };