Core/TaskScheduler: Fix work ending condition

Use remaining task count instead of idle worker count, this avoids a race condition where a worker signals idle after being tasked with a new job
This commit is contained in:
SirLynix
2024-02-03 22:40:12 +01:00
parent 59e172c2ee
commit e3ad9be759
3 changed files with 34 additions and 31 deletions

View File

@@ -1,14 +1,17 @@
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/TaskScheduler.hpp>
#include <catch2/catch_test_macros.hpp>
#include <atomic>
#include <chrono>
#include <thread>
SCENARIO("TaskScheduler", "[CORE][TaskScheduler]")
{
for (std::size_t workerCount : { 0, 1, 2, 4 })
for (std::size_t workerCount : { 0, 1, 2, 4, 8 })
{
GIVEN("A task scheduler with " << workerCount << " workers")
{
Nz::TaskScheduler scheduler(4);
Nz::TaskScheduler scheduler(workerCount);
WHEN("We add a single task and wait for it")
{
@@ -19,6 +22,26 @@ SCENARIO("TaskScheduler", "[CORE][TaskScheduler]")
CHECK(executed);
}
WHEN("We add time-consuming tasks, they are split between workers")
{
std::atomic_uint count = 0;
Nz::HighPrecisionClock clock;
for (unsigned int i = 0; i < scheduler.GetWorkerCount(); ++i)
{
scheduler.AddTask([&]
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
count++;
});
}
scheduler.WaitForTasks();
Nz::Time elapsedTime = clock.GetElapsedTime();
CHECK(count == scheduler.GetWorkerCount());
CHECK(elapsedTime < Nz::Time::Milliseconds(120));
}
WHEN("We add a lot of tasks and wait for all of them")
{
constexpr std::size_t taskCount = 512;