diff options
| author | untodesu <kirill@untode.su> | 2025-07-01 03:08:39 +0500 |
|---|---|---|
| committer | untodesu <kirill@untode.su> | 2025-07-01 03:08:39 +0500 |
| commit | 458e0005690ea9d579588a0a12368fc2c2c9a93a (patch) | |
| tree | 588a9ca6cb3c76d9193b5bd4601d64f0e50e8c8c /game/shared/threading.cc | |
| parent | c7b0c8e0286a1b2bb7ec55e579137dfc3b22eeb9 (diff) | |
| download | voxelius-458e0005690ea9d579588a0a12368fc2c2c9a93a.tar.bz2 voxelius-458e0005690ea9d579588a0a12368fc2c2c9a93a.zip | |
I hyper-focued on refactoring again
- I put a cool-sounding "we are number one" remix on repeat and straight
up grinded the entire repository to a better state until 03:09 AM. I
guess I have something wrong in my brain that makes me do this shit
Diffstat (limited to 'game/shared/threading.cc')
| -rw-r--r-- | game/shared/threading.cc | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/game/shared/threading.cc b/game/shared/threading.cc new file mode 100644 index 0000000..82bcad7 --- /dev/null +++ b/game/shared/threading.cc @@ -0,0 +1,111 @@ +#include "shared/pch.hh" + +#include "shared/threading.hh" + +#include "core/io/cmdline.hh" +#include "core/math/constexpr.hh" + +constexpr static const char* DEFAULT_POOL_SIZE_ARG = "4"; + +static BS::light_thread_pool* thread_pool; +static std::deque<Task*> task_deque; + +static void task_process(Task* task) +{ + task->set_status(task_status::PROCESSING); + task->process(); + + if(task->get_status() == task_status::PROCESSING) { + // If the task status is still PROCESSING + // it can be deduced it hasn't been cancelled + task->set_status(task_status::COMPLETED); + } +} + +task_status Task::get_status(void) const +{ + return m_status; +} + +void Task::set_status(task_status status) +{ + m_status = status; +} + +void threading::init(void) +{ + auto argument = io::cmdline::get("threads", DEFAULT_POOL_SIZE_ARG); + auto num_concurrent_threads = std::thread::hardware_concurrency(); + unsigned int thread_pool_size; + + if(num_concurrent_threads && !std::strcmp(argument, "max")) { + // Use the maximum available number of concurrent + // hardware threads provided by the implementation + thread_pool_size = num_concurrent_threads; + } else { + if(num_concurrent_threads) { + thread_pool_size = math::clamp<unsigned int>(std::strtoul(argument, nullptr, 10), 1U, num_concurrent_threads); + } else { + thread_pool_size = math::max<unsigned int>(std::strtoul(argument, nullptr, 10), 1U); + } + } + + spdlog::info("threading: using {} threads for pooling tasks", thread_pool_size); + + thread_pool = new BS::light_thread_pool(thread_pool_size); + + task_deque.clear(); +} + +void threading::shutdown(void) +{ + for(auto task : task_deque) { + auto status = task->get_status(); + if((status != task_status::CANCELLED) || (status != task_status::COMPLETED)) { + task->set_status(task_status::CANCELLED); + } + } + + thread_pool->purge(); + thread_pool->wait(); + + for(auto task : task_deque) + delete task; + task_deque.clear(); + + delete thread_pool; +} + +void threading::update(void) +{ + auto task_iter = task_deque.cbegin(); + + while(task_iter != task_deque.cend()) { + auto task_ptr = *task_iter; + auto status = task_ptr->get_status(); + + if(status == task_status::CANCELLED) { + delete task_ptr; + task_iter = task_deque.erase(task_iter); + continue; + } + + if(status == task_status::COMPLETED) { + task_ptr->finalize(); + delete task_ptr; + task_iter = task_deque.erase(task_iter); + continue; + } + + task_iter = std::next(task_iter); + } +} + +void threading::detail::submit_new(Task* task) +{ + task->set_status(task_status::ENQUEUED); + + static_cast<void>(thread_pool->submit_task(std::bind(&task_process, task))); + + task_deque.push_back(task); +} |
