|
|
|
@ -160,14 +160,18 @@ TYPED_TEST(ThreadPoolTest, CanStartLotsOfClosures) { |
|
|
|
|
ASSERT_EQ(runcount.load(), pow(2, branch_factor + 1) - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TYPED_TEST(ThreadPoolTest, ScalesWhenBackloggedFromSingleThreadLocalQueue) { |
|
|
|
|
class WorkStealingThreadPoolTest : public ::testing::Test {}; |
|
|
|
|
|
|
|
|
|
// TODO(hork): This is currently a pathological case for the original thread
|
|
|
|
|
// pool, it gets wedged in ~3% of runs when new threads fail to start. When that
|
|
|
|
|
// is fixed, or the implementation is deleted, make this a typed test again.
|
|
|
|
|
TEST_F(WorkStealingThreadPoolTest, ScalesWhenBackloggedFromGlobalQueue) { |
|
|
|
|
int pool_thread_count = 8; |
|
|
|
|
TypeParam p(pool_thread_count); |
|
|
|
|
WorkStealingThreadPool p(pool_thread_count); |
|
|
|
|
grpc_core::Notification signal; |
|
|
|
|
// Ensures the pool is saturated before signaling closures to continue.
|
|
|
|
|
std::atomic<int> waiters{0}; |
|
|
|
|
std::atomic<bool> signaled{false}; |
|
|
|
|
p.Run([&]() { |
|
|
|
|
for (int i = 0; i < pool_thread_count; i++) { |
|
|
|
|
p.Run([&]() { |
|
|
|
|
waiters.fetch_add(1); |
|
|
|
@ -183,22 +187,21 @@ TYPED_TEST(ThreadPoolTest, ScalesWhenBackloggedFromSingleThreadLocalQueue) { |
|
|
|
|
signaled.store(true); |
|
|
|
|
signal.Notify(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
p.Quiesce(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class WorkStealingThreadPoolTest : public ::testing::Test {}; |
|
|
|
|
|
|
|
|
|
// TODO(hork): This is currently a pathological case for the original thread
|
|
|
|
|
// pool, it gets wedged in ~3% of runs when new threads fail to start. When that
|
|
|
|
|
// is fixed, or the implementation is deleted, make this a typed test again.
|
|
|
|
|
TEST_F(WorkStealingThreadPoolTest, ScalesWhenBackloggedFromGlobalQueue) { |
|
|
|
|
TEST_F(WorkStealingThreadPoolTest, |
|
|
|
|
ScalesWhenBackloggedFromSingleThreadLocalQueue) { |
|
|
|
|
int pool_thread_count = 8; |
|
|
|
|
WorkStealingThreadPool p(pool_thread_count); |
|
|
|
|
grpc_core::Notification signal; |
|
|
|
|
// Ensures the pool is saturated before signaling closures to continue.
|
|
|
|
|
std::atomic<int> waiters{0}; |
|
|
|
|
std::atomic<bool> signaled{false}; |
|
|
|
|
p.Run([&]() { |
|
|
|
|
for (int i = 0; i < pool_thread_count; i++) { |
|
|
|
|
p.Run([&]() { |
|
|
|
|
waiters.fetch_add(1); |
|
|
|
@ -214,6 +217,7 @@ TEST_F(WorkStealingThreadPoolTest, ScalesWhenBackloggedFromGlobalQueue) { |
|
|
|
|
signaled.store(true); |
|
|
|
|
signal.Notify(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
p.Quiesce(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|