From 0f319ee93c421be54854384e0e26cc78c00235be Mon Sep 17 00:00:00 2001 From: "Antonio S. Musumeci" Date: Sat, 18 Apr 2026 17:52:23 -0400 Subject: [PATCH] thread_pool: fast-path _process_func when no removal is pending Every task completion called _try_claim_and_remove_self, which acquires _scaling_mutex and _threads_mutex even when _remove_count is zero (the steady-state common case). Short tasks paid full mutex overhead per completion. Add a relaxed _remove_count.load before the locks; if it reads zero, skip the claim entirely. A stale zero just defers the claim to a later completion on any worker, matching the existing design where the claim is a cooperative race. --- vendored/libfuse/include/thread_pool.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vendored/libfuse/include/thread_pool.hpp b/vendored/libfuse/include/thread_pool.hpp index ea28693c..5f949978 100644 --- a/vendored/libfuse/include/thread_pool.hpp +++ b/vendored/libfuse/include/thread_pool.hpp @@ -546,7 +546,13 @@ ThreadPool::_process_func(Func &func_) // prevent the TOCTOU race with set_threads. During shutdown // (_stop set), _try_claim_and_remove_self returns false, so // the destructor still joins us. - if(_try_claim_and_remove_self(pthread_self())) + // + // Fast path: most tasks complete with no shrink pending, so avoid + // the double-lock acquisition in _try_claim_and_remove_self unless + // _remove_count looks non-zero. A stale zero read just defers the + // claim by one task — a later completion on any worker picks it up. + if(_remove_count.load(std::memory_order_relaxed) != 0 && + _try_claim_and_remove_self(pthread_self())) return EXIT; return CONTINUE;