From: Kefu Chai Date: Mon, 22 Jun 2026 12:48:41 +0000 (+0800) Subject: test/common: reduce WebCache stress-test thread count X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7240994bf53deabdfaf137a74cf886693682f4e9;p=ceph.git test/common: reduce WebCache stress-test thread count WebCacheConcurrencyTest sized its thread pool as hardware_concurrency() * 100, which is 3200 on the 32-vCPU CI hosts. Linux runs that in a few seconds, but the Windows (mingw-llvm/libc++) build times out unittest_web_cache at the 1800s per-test limit on every PR. BasicAddSame reuses one key, so after the first insert every add() is a shared-lock hit: 3200 threads log hit=3200000 miss=1 and finish in ~4s. BasicAddUnique inserts a distinct key each iteration, so every add() misses and takes the exclusive lock. libc++'s std::shared_mutex wakes all waiting writers on every unlock, so N contending writers cost O(N^2) wakeups. At N=3200 that alone overruns the 1800s budget, which is where the failing run hangs. StampedeSyncCallOnce and StampedeMutex are exclusive-lock bound the same way. The tests only need enough threads to race; 4x oversubscription is enough. Cap the count via a shared helper. Signed-off-by: Kefu Chai --- diff --git a/src/test/common/test_web_cache.cc b/src/test/common/test_web_cache.cc index 524e4c0beb2..6bbcbdc4a15 100644 --- a/src/test/common/test_web_cache.cc +++ b/src/test/common/test_web_cache.cc @@ -446,6 +446,13 @@ TEST_F(WebCacheTest, SieveAllVisited) { } class WebCacheConcurrencyTest : public WebCacheTest { + protected: + // 4x oversubscription is enough to race the threads. The original *100 + // (3200 on CI) made exclusive-lock tests O(N^2) and timed out on Windows. + static unsigned stress_thread_count() { + return std::max(std::thread::hardware_concurrency() * 4, 32u); + } + void TearDown() override { if (_uut->perf() != nullptr) { JSONFormatter f(true); @@ -458,8 +465,7 @@ class WebCacheConcurrencyTest : public WebCacheTest { TEST_F(WebCacheConcurrencyTest, BasicAddSame) { reset_cache_system_mode(100); - const auto num_threads = - std::max(std::thread::hardware_concurrency() * 100, 100U); + const auto num_threads = stress_thread_count(); std::vector threads; for (size_t i = 0; i < num_threads; ++i) { threads.emplace_back([&]() { @@ -478,8 +484,7 @@ TEST_F(WebCacheConcurrencyTest, BasicAddSame) { TEST_F(WebCacheConcurrencyTest, BasicAddUnique) { reset_cache_system_mode(100); - const auto num_threads = - std::max(std::thread::hardware_concurrency() * 100, 100U); + const auto num_threads = stress_thread_count(); std::vector threads; for (size_t i = 0; i < num_threads; ++i) { threads.emplace_back([&]() { @@ -504,8 +509,7 @@ TEST_F(WebCacheConcurrencyTest, StampedeSyncCallOnce) { webcache::WebCache cache( _cct.get(), "test_web_cache", 100); std::atomic_int fetches = 0; - const auto num_threads = - std::max(std::thread::hardware_concurrency() * 100, 100U); + const auto num_threads = stress_thread_count(); std::vector threads; for (size_t i = 0; i < num_threads; ++i) { threads.emplace_back([&]() { @@ -542,8 +546,7 @@ TEST_F(WebCacheConcurrencyTest, StampedeMutex) { webcache::WebCache cache( _cct.get(), "test_web_cache", 100); std::atomic_int fetches = 0; - const auto num_threads = - std::max(std::thread::hardware_concurrency() * 100, 100U); + const auto num_threads = stress_thread_count(); std::vector threads; for (size_t i = 0; i < num_threads; ++i) { threads.emplace_back([&]() {