From aa8f61bff22d7b6eff3642490c1a9dbad28137e5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 16 Apr 2026 14:50:43 +0200 Subject: [PATCH 1/2] Executor: Make thread creation failure non-fatal --- src/libexpr/parallel-eval.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libexpr/parallel-eval.cc b/src/libexpr/parallel-eval.cc index 0fe7820454b8..0e01e9d64939 100644 --- a/src/libexpr/parallel-eval.cc +++ b/src/libexpr/parallel-eval.cc @@ -32,8 +32,16 @@ Executor::Executor(const EvalSettings & evalSettings) { debug("executor using %d threads", evalCores); auto state(state_.lock()); + // FIXME: create worker threads on demand? for (size_t n = 0; n < evalCores; ++n) - createWorker(*state); + try { + createWorker(*state); + } catch (boost::thread_resource_error & e) { + if (n == 0) + throw Error("could not create any evaluator worker threads: %s", e.what()); + warn("could only create %d evaluator worker threads: %s", n, e.what()); + break; + } } Executor::~Executor() From 5c862d73286ace2348bd9c2559fba2a8370900c1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 16 Apr 2026 14:55:23 +0200 Subject: [PATCH 2/2] Limit default number of eval threads to 32 Scalability bottlenecks currently cause diminishing returns above this. It also prevents creating huge numbers of threads on machines with lots of cores. --- src/libexpr/parallel-eval.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libexpr/parallel-eval.cc b/src/libexpr/parallel-eval.cc index 0e01e9d64939..97c8ee79e13d 100644 --- a/src/libexpr/parallel-eval.cc +++ b/src/libexpr/parallel-eval.cc @@ -17,8 +17,10 @@ thread_local bool Executor::amWorkerThread{false}; unsigned int Executor::getEvalCores(const EvalSettings & evalSettings) { + /* Note: the default number of cores is currently limited to 32 + due to scalability bottlenecks. */ return evalSettings.evalProfilerMode != EvalProfilerMode::disabled ? 1 - : evalSettings.evalCores == 0UL ? Settings::getDefaultCores() + : evalSettings.evalCores == 0UL ? std::min(32U, Settings::getDefaultCores()) : evalSettings.evalCores; }