From 159a5c7b713bf93d9f40cd2f3c1657d02f48f2f9 Mon Sep 17 00:00:00 2001 From: "Antonio S. Musumeci" Date: Fri, 10 Apr 2026 17:32:51 -0400 Subject: [PATCH] thread_pool: skip spurious wakeups in hill-climb monitor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pthread_cond_timedwait can return early due to spurious wakeups. When this happens the throughput delta covers a shorter-than-expected interval, producing an artificially low sample. Two consecutive spurious wakes would cause the EMA to decline twice, crossing the decline_threshold and triggering a false direction reversal — the monitor would shrink the pool when throughput was actually stable. Record the wall-clock time before sleeping and discard any sample where the elapsed time is less than half the target interval. The _stop check runs first so shutdown is never delayed. Co-Authored-By: Claude Opus 4.6 (1M context) --- vendored/libfuse/include/thread_pool.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vendored/libfuse/include/thread_pool.hpp b/vendored/libfuse/include/thread_pool.hpp index aa7982a7..4df0304f 100644 --- a/vendored/libfuse/include/thread_pool.hpp +++ b/vendored/libfuse/include/thread_pool.hpp @@ -566,6 +566,7 @@ ThreadPool::monitor_routine(void *arg_) { // Sleep for one sample interval, but wake immediately if the // destructor signals _monitor_cond. + std::uint64_t t0 = _now_usecs(); { struct timespec abs_ts; clock_gettime(CLOCK_MONOTONIC,&abs_ts); @@ -587,6 +588,14 @@ ThreadPool::monitor_routine(void *arg_) if(btp->_stop.load(std::memory_order_acquire)) break; + // Skip spurious wakeups. A short interval yields an + // artificially low throughput delta that would cause the EMA + // to decline and potentially trigger a false direction + // reversal in the hill-climber. + std::uint64_t elapsed = _now_usecs() - t0; + if(elapsed < (std::uint64_t)interval / 2) + continue; + std::uint64_t completed = btp->_tasks_completed.load(std::memory_order_relaxed); std::uint64_t raw_throughput = completed - prev_completed; prev_completed = completed;