Skip to content

Commit

Permalink
SERVER-90863 Prevent calls to notifyOne if no waiters are present (#2…
Browse files Browse the repository at this point in the history
…2559)

GitOrigin-RevId: 5b453f2b6738227972bf3d1dec3f786fd3402b68
  • Loading branch information
mbroadst authored and MongoDB Bot committed May 28, 2024
1 parent 137395b commit 2538eab
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 15 deletions.
23 changes: 10 additions & 13 deletions src/mongo/util/concurrency/semaphore_ticketholder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,35 +86,32 @@ boost::optional<Ticket> SemaphoreTicketHolder::_waitForTicketUntilImpl(Operation
};

while (true) {
auto oldAvailable = _tickets.load();

if (boost::optional<Ticket> maybeTicket = _tryAcquireImpl(admCtx); maybeTicket) {
return std::move(*maybeTicket);
}

if (oldAvailable != _tickets.loadRelaxed()) {
continue;
}

Date_t deadline = nextDeadline();
auto canAcquire = _tickets.waitUntil(oldAvailable, deadline);
_waiterCount.fetchAndAdd(1);
_tickets.waitUntil(0, deadline);
_waiterCount.fetchAndSubtract(1);

if (interruptible) {
opCtx->checkForInterrupt();
}

if (canAcquire) {
if (boost::optional<Ticket> maybeTicket = _tryAcquireImpl(admCtx)) {
return std::move(*maybeTicket);
}
} else if (deadline == until) {
if (deadline == until) {
// We hit the end of our deadline, so return nothing.
return boost::none;
}
}
}

void SemaphoreTicketHolder::_releaseToTicketPoolImpl(AdmissionContext* admCtx) noexcept {
if (_tickets.fetchAndAdd(1) >= 0) {
// Notifying a futex costs a syscall. Since queued waiters guarantee that the `_waiterCount` is
// non-zero while they are waiting, we can avoid the needless cost if there are tickets and no
// queued waiters.
int32_t availableBeforeIncrementing = _tickets.fetchAndAdd(1);
if (availableBeforeIncrementing >= 0 && _waiterCount.load() > 0) {
_tickets.notifyOne();
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/mongo/util/concurrency/semaphore_ticketholder.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ class SemaphoreTicketHolder final : public TicketHolder {
ResizePolicy resizePolicy = ResizePolicy::kGradual);

int32_t available() const final;


int64_t queued() const final {
auto removed = _semaphoreStats.totalRemovedQueue.loadRelaxed();
auto added = _semaphoreStats.totalAddedQueue.loadRelaxed();
Expand All @@ -67,6 +65,7 @@ class SemaphoreTicketHolder final : public TicketHolder {
bool interruptible) final;

boost::optional<Ticket> _tryAcquireImpl(AdmissionContext* admCtx) final;

void _releaseToTicketPoolImpl(AdmissionContext* admCtx) noexcept final;

bool _resizeImpl(WithLock lock,
Expand All @@ -83,6 +82,7 @@ class SemaphoreTicketHolder final : public TicketHolder {

ResizePolicy _resizePolicy;
BasicWaitableAtomic<int32_t> _tickets;
Atomic<int32_t> _waiterCount{0};
QueueStats _semaphoreStats;
};

Expand Down

0 comments on commit 2538eab

Please sign in to comment.