void TaskSchedular::AsyncResume(Task* waitingOn, uint32 limit) { Task* toExec = nullptr; TaskRunner* runner = TaskRunner::AsyncGetRunner(); while(waitingOn->meta.refCount.load(std::memory_order_relaxed) > (int)limit) { if (toExec || (toExec = AsyncGetWork(runner, false)) ) { #ifdef NEX_TASK_SCHEDULAR_CHECKS if (TaskSchedular::_doAllowTraces) { OutStringStream str; str << "Waited: " << runner->_name << ", running task: " << toExec->_name; Trace(str.str()); } #endif toExec = TaskRunner::Execute(toExec); } } if (toExec) { #ifdef NEX_TASK_SCHEDULAR_CHECKS NEX_ASSERT(toExec->meta.state == Task::TASK_QUEUED || toExec->meta.state == Task::TASK_INIT); toExec->meta.state = Task::TASK_QUEUED; #endif runner->AddTask(toExec); } }
TEST (TaskPoolTest, TaskRunner) { auto fn = [](int x) { return std::make_pair(x, x * x); }; TaskRunner<std::pair<int, int>> tr; tr.AddTask(fn, 1); tr.AddTask(fn, 2); tr.AddTask(fn, 3); tr.AddTask(fn, 4); int count = 0; while (true) { auto f = tr.WaitForNextCompletedTask(); if (!f.valid()) break; ++count; std::pair<int, int> v = f.get(); ASSERT_EQ (v.first * v.first, v.second); } ASSERT_EQ(4, count); }
void TaskSchedular::AsyncAddChildTask(Task* task) { NEX_ASSERT(task); task->PrepareSubmit(); TaskRunner* runner = TaskRunner::AsyncGetRunner(); #ifdef NEX_TASK_SCHEDULAR_CHECKS if (TaskSchedular::_doAllowTraces) { OutStringStream str; str << "Thread: " << runner->_name << ", task queue: " << runner->requestQueue.Tail() << " via, " << task->_name; Trace(str.str()); } #endif runner->AddTask(task); #ifdef NEX_TASK_SCHEDULAR_CHECKS task->meta.state = Task::TASK_QUEUED; #endif runner->taskCount++; }