From d0de60dc33df75fbcacb53a09568b14d0fd48cb9 Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 12 Jun 2023 17:09:55 +0200 Subject: Multithreaded world generation with Perlin --- src/Compute/Queue.hpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/Compute/Queue.hpp (limited to 'src/Compute/Queue.hpp') diff --git a/src/Compute/Queue.hpp b/src/Compute/Queue.hpp new file mode 100644 index 0000000..6aba1ab --- /dev/null +++ b/src/Compute/Queue.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace MC::Compute { + +template +class Queue { +public: + explicit Queue(uint workers) : m_control(std::make_shared()) { + for (uint w = 0; w < workers; w++) { + std::thread thread{[=]() { Queue::run_thread(m_control); }}; + thread.detach(); + } + }; + + void add(I id, std::function execute) { + std::scoped_lock work_lock(m_control->work.mutex); + m_control->work.jobs.push_back({id, std::move(execute)}); + } + + struct Result { + I id{}; + X res; + }; + + std::vector done() { + std::vector done_results; + + std::scoped_lock result_lock(m_control->results.mutex); + for (auto r : m_control->results.results) { + done_results.push_back(r); + } + m_control->results.results.clear(); + return done_results; + } + +private: + struct Job { + I id; + std::function execute; + }; + + struct Work { + std::mutex mutex; + std::vector jobs; + }; + + struct Results { + std::mutex mutex; + std::vector results; + }; + + struct Control { + Work work; + Results results; + }; + + [[noreturn]] static void run_thread(std::shared_ptr control) { + using namespace std::chrono_literals; + + while (true) { + bool nothing_to_do = true; + Job job; + { + std::scoped_lock work_lock(control->work.mutex); + if (!control->work.jobs.empty()) { + job = control->work.jobs.back(); + control->work.jobs.pop_back(); + nothing_to_do = false; + } + } + + if (nothing_to_do) { + std::this_thread::sleep_for(100ms); + continue; + } + + auto res = job.execute(); + { + std::scoped_lock result_lock(control->results.mutex); + control->results.results.push_back({job.id, res}); + } + } + } + + std::shared_ptr m_control; +}; + +} -- cgit 1.4.1