renderer task-scheduler: ++thread safety

Currently, tasks are expected to be triggered from the main thread.
This ensures preventing the popping of a thread from a worker thread.

Previously, there was a potential deadlock problem...
This commit is contained in:
Hermet Park 2023-08-21 16:13:17 +09:00 committed by Hermet Park
parent cd71c66703
commit 8f9bdebd35

View file

@ -106,9 +106,12 @@ struct TaskSchedulerImpl
vector<thread> threads; vector<thread> threads;
vector<TaskQueue> taskQueues; vector<TaskQueue> taskQueues;
atomic<uint32_t> idx{0}; atomic<uint32_t> idx{0};
thread::id tid;
TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt) TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt)
{ {
tid = this_thread::get_id();
for (unsigned i = 0; i < threadCnt; ++i) { for (unsigned i = 0; i < threadCnt; ++i) {
threads.emplace_back([&, i] { run(i); }); threads.emplace_back([&, i] { run(i); });
} }
@ -143,12 +146,23 @@ struct TaskSchedulerImpl
{ {
//Async //Async
if (threadCnt > 0) { if (threadCnt > 0) {
auto tid = this_thread::get_id();
if (tid == this->tid) {
task->prepare(); task->prepare();
auto i = idx++; auto i = idx++;
for (unsigned n = 0; n < threadCnt; ++n) { for (unsigned n = 0; n < threadCnt; ++n) {
if (taskQueues[(i + n) % threadCnt].tryPush(task)) return; if (taskQueues[(i + n) % threadCnt].tryPush(task)) return;
} }
taskQueues[i % threadCnt].push(task); taskQueues[i % threadCnt].push(task);
//Not thread-safety now, it's requested from a worker-thread
} else {
for (unsigned i = 0; i < threadCnt; ++i) {
if (tid == threads[i].get_id()) {
task->prepare();
(*task)(i + 1);
}
}
}
//Sync //Sync
} else { } else {
task->run(0); task->run(0);