Skip to content

Commit e41b3e6

Browse files
otfacebook-github-bot
authored andcommitted
ThrottledLifoSem::excessValueGuess()
Summary: See comment Reviewed By: uvdn7 Differential Revision: D79346374 fbshipit-source-id: d19588b71adc0a648cf4d8b1804d92c2e78c4fc8
1 parent b311341 commit e41b3e6

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

folly/synchronization/ThrottledLifoSem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ class ThrottledLifoSem {
139139
return static_cast<uint32_t>(state_.load() & kValueMask);
140140
}
141141

142+
// Returns the number of posts that are not assigned yet to existing
143+
// waiters. This can be negative if there are more waiters than posts.
144+
int64_t excessValueGuess() const {
145+
uint64_t state = state_.load(std::memory_order_relaxed);
146+
uint64_t value = state & kValueMask;
147+
uint64_t numWaiters = state >> kNumWaitersShift;
148+
return static_cast<int64_t>(value) - static_cast<int64_t>(numWaiters);
149+
}
150+
142151
private:
143152
friend class ThrottledLifoSemTestHelper;
144153

folly/synchronization/test/ThrottledLifoSemTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,30 @@ TEST(ThrottledLifoSem, TryPost) {
183183
EXPECT_EQ(sem.valueGuess(), 0);
184184
}
185185

186+
TEST(ThrottledLifoSem, ExcessValueGuess) {
187+
constexpr size_t kNumWaiters = 64;
188+
// Use a large wakeUpInterval so that waiters do not wake up immediately.
189+
folly::ThrottledLifoSem sem({.wakeUpInterval = std::chrono::milliseconds(1)});
190+
191+
std::vector<std::thread> threads;
192+
for (size_t i = 0; i < kNumWaiters; ++i) {
193+
threads.emplace_back([&] { sem.wait(); });
194+
}
195+
196+
folly::ThrottledLifoSemTestHelper::spinUntilWaiters(
197+
sem, kNumWaiters, /* assertExact */ true);
198+
199+
EXPECT_EQ(sem.excessValueGuess(), -static_cast<int64_t>(kNumWaiters));
200+
sem.post(kNumWaiters + 1);
201+
EXPECT_EQ(sem.excessValueGuess(), 1);
202+
// This should be > 1 but it is time-dependent so we cannot assert it.
203+
LOG(INFO) << "Value: " << sem.valueGuess();
204+
205+
for (auto& t : threads) {
206+
t.join();
207+
}
208+
}
209+
186210
TEST(ThrottledLifoSem, MPMCStress) {
187211
// Same number of producers and consumers.
188212
constexpr size_t kNumThreads = 16;

0 commit comments

Comments
 (0)