From 7cc0f347d3fc3ccfda6f9eec921f11e98b378bc6 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Sat, 17 Oct 2026 06:45:58 +0000 Subject: [PATCH] Give each thread of the threading checker its own index The tasks read the loop's variable, which had usually reached the thread count by the time they ran, so every thread was given the same index and the solving tests never ran with Newton off. When a task did start early it ran without Newton, and the test expected an empty set where the answer is the conditional set the equation defines; it failed once in a loaded full suite. Without Newton the roots are now expected not to be numbers. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- .../UnitTests/Core/Multithreading/SettingsAndThreads.cs | 6 ++++-- Sources/Tests/UnitTests/TestUtils.cs | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Sources/Tests/UnitTests/Core/Multithreading/SettingsAndThreads.cs b/Sources/Tests/UnitTests/Core/Multithreading/SettingsAndThreads.cs index 99a6eacfd..934c7945c 100644 --- a/Sources/Tests/UnitTests/Core/Multithreading/SettingsAndThreads.cs +++ b/Sources/Tests/UnitTests/Core/Multithreading/SettingsAndThreads.cs @@ -54,7 +54,8 @@ static void Solve(int num) => { var roots = "x2 + e^x + sin(x)".SolveEquation("x"); var set = (Set)roots.Simplify(); - Assert.Equal(num % 2 == 0, !set.IsSetEmpty); + // With Newton the roots are numbers; without, the equation is left as the set it defines. + Assert.Equal(num % 2 == 0, set is Set.FiniteSet { IsSetEmpty: false }); }); new ThreadingChecker(Solve).Run(); } @@ -123,7 +124,8 @@ static void Solve(int num) using var _ = MathS.Settings.AllowNewton.Set(num % 2 == 0); var roots = "x2 + e^x + sin(x)".SolveEquation("x"); var set = (Set)roots.Simplify(); - Assert.Equal(num % 2 == 0, !set.IsSetEmpty); + // With Newton the roots are numbers; without, the equation is left as the set it defines. + Assert.Equal(num % 2 == 0, set is Set.FiniteSet { IsSetEmpty: false }); } new ThreadingChecker(Solve).Run(); } diff --git a/Sources/Tests/UnitTests/TestUtils.cs b/Sources/Tests/UnitTests/TestUtils.cs index e5aca28a7..7eea6227a 100644 --- a/Sources/Tests/UnitTests/TestUtils.cs +++ b/Sources/Tests/UnitTests/TestUtils.cs @@ -135,14 +135,19 @@ public void Run(int iterCount = 1, int threadCount = 4) { var tasks = new Task[threadCount]; for (var i = 0; i < threadCount; i++) + { + // Each task's own index: the lambda read the loop's variable, which had usually reached + // threadCount by the time a task ran, so every thread was asked the same thing. + var index = i; tasks[i] = Task.Run( () => { var iterCountLocal = iterCount; for (var j = 0; j < iterCountLocal; j++) - action(i); + action(index); } ); + } Task.WaitAll(tasks); } }