From 528ea0d5875abd2c145310db861b66a12728c574 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 12 Dec 2023 15:46:13 +0900 Subject: [PATCH] renderer/scheduler: --binary size by 2.2kb replace the stl with own lightweight data structures. --- src/renderer/tvgTaskScheduler.cpp | 57 ++++++++++++++++--------------- src/renderer/tvgTaskScheduler.h | 3 ++ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/renderer/tvgTaskScheduler.cpp b/src/renderer/tvgTaskScheduler.cpp index 45b93cad..7a90e874 100644 --- a/src/renderer/tvgTaskScheduler.cpp +++ b/src/renderer/tvgTaskScheduler.cpp @@ -20,11 +20,11 @@ * SOFTWARE. */ -#include #include -#include #include #include +#include "tvgArray.h" +#include "tvgInlist.h" #include "tvgTaskScheduler.h" /************************************************************************/ @@ -34,7 +34,7 @@ namespace tvg { struct TaskQueue { - deque taskDeque; + Inlist taskDeque; mutex mtx; condition_variable ready; bool done = false; @@ -44,8 +44,6 @@ struct TaskQueue { unique_lock lock{mtx, try_to_lock}; if (!lock || taskDeque.empty()) return false; *task = taskDeque.front(); - taskDeque.pop_front(); - return true; } @@ -54,11 +52,9 @@ struct TaskQueue { { unique_lock lock{mtx, try_to_lock}; if (!lock) return false; - taskDeque.push_back(task); + taskDeque.back(task); } - ready.notify_one(); - return true; } @@ -82,8 +78,6 @@ struct TaskQueue { if (taskDeque.empty()) return false; *task = taskDeque.front(); - taskDeque.pop_front(); - return true; } @@ -91,12 +85,10 @@ struct TaskQueue { { { unique_lock lock{mtx}; - taskDeque.push_back(task); + taskDeque.back(task); } - ready.notify_one(); } - }; @@ -105,24 +97,33 @@ static thread_local bool _async = true; //toggle async tasking for each thread struct TaskSchedulerImpl { - uint32_t threadCnt; - vector threads; - vector taskQueues; + Array threads; + Array taskQueues; atomic idx{0}; - TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt) + TaskSchedulerImpl(unsigned threadCnt) { threads.reserve(threadCnt); + taskQueues.reserve(threadCnt); for (unsigned i = 0; i < threadCnt; ++i) { - threads.emplace_back([&, i] { run(i); }); + taskQueues.push(new TaskQueue); + threads.push(new thread([&, i] { run(i); })); } } ~TaskSchedulerImpl() { - for (auto& queue : taskQueues) queue.complete(); - for (auto& thread : threads) thread.join(); + for (auto tq = taskQueues.data; tq < taskQueues.end(); ++tq) { + (*tq)->complete(); + } + for (auto thread = threads.data; thread < threads.end(); ++thread) { + (*thread)->join(); + delete(*thread); + } + for (auto tq = taskQueues.data; tq < taskQueues.end(); ++tq) { + delete(*tq); + } } void run(unsigned i) @@ -132,14 +133,14 @@ struct TaskSchedulerImpl //Thread Loop while (true) { auto success = false; - for (unsigned x = 0; x < threadCnt * 2; ++x) { - if (taskQueues[(i + x) % threadCnt].tryPop(&task)) { + for (unsigned x = 0; x < threads.count * 2; ++x) { + if (taskQueues[(i + x) % threads.count]->tryPop(&task)) { success = true; break; } } - if (!success && !taskQueues[i].pop(&task)) break; + if (!success && !taskQueues[i]->pop(&task)) break; (*task)(i + 1); } } @@ -147,13 +148,13 @@ struct TaskSchedulerImpl void request(Task* task) { //Async - if (threadCnt > 0 && _async) { + if (threads.count > 0 && _async) { task->prepare(); auto i = idx++; - for (unsigned n = 0; n < threadCnt; ++n) { - if (taskQueues[(i + n) % threadCnt].tryPush(task)) return; + for (unsigned n = 0; n < threads.count; ++n) { + if (taskQueues[(i + n) % threads.count]->tryPush(task)) return; } - taskQueues[i % threadCnt].push(task); + taskQueues[i % threads.count]->push(task); //Sync } else { task->run(0); @@ -192,7 +193,7 @@ void TaskScheduler::request(Task* task) unsigned TaskScheduler::threads() { - if (inst) return inst->threadCnt; + if (inst) return inst->threads.count; return 0; } diff --git a/src/renderer/tvgTaskScheduler.h b/src/renderer/tvgTaskScheduler.h index 5d79fa54..b46acedd 100644 --- a/src/renderer/tvgTaskScheduler.h +++ b/src/renderer/tvgTaskScheduler.h @@ -26,6 +26,7 @@ #include #include #include "tvgCommon.h" +#include "tvgInlist.h" namespace tvg { @@ -50,6 +51,8 @@ private: bool pending = false; public: + INLIST_ITEM(Task); + virtual ~Task() = default; void done()