From c613ead5fa2361296cf8d9a80d4648492ff4e16f Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 29 Jul 2019 12:59:18 -0300 Subject: Added a spinlock template as well as a thread work pool class. Also, optimized shader compilation to happen on threads. --- core/thread_work_pool.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 core/thread_work_pool.h (limited to 'core/thread_work_pool.h') diff --git a/core/thread_work_pool.h b/core/thread_work_pool.h new file mode 100644 index 0000000000..165eb391e2 --- /dev/null +++ b/core/thread_work_pool.h @@ -0,0 +1,78 @@ +#ifndef THREAD_WORK_POOL_H +#define THREAD_WORK_POOL_H + +#include "core/os/memory.h" +#include "core/os/semaphore.h" +#include +#include +class ThreadWorkPool { + + std::atomic index; + + struct BaseWork { + std::atomic *index; + uint32_t max_elements; + virtual void work() = 0; + }; + + template + struct Work : public BaseWork { + C *instance; + M method; + U userdata; + virtual void work() { + + while (true) { + uint32_t work_index = index->fetch_add(1, std::memory_order_relaxed); + if (work_index >= max_elements) { + break; + } + (instance->*method)(work_index, userdata); + } + } + }; + + struct ThreadData { + std::thread *thread; + Semaphore start; + Semaphore completed; + std::atomic exit; + BaseWork *work; + }; + + ThreadData *threads = nullptr; + uint32_t thread_count = 0; + + static void _thread_function(ThreadData *p_thread); + +public: + template + void do_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { + + ERR_FAIL_COND(!threads); //never initialized + + index.store(0); + + Work *w = memnew((Work)); + w->instance = p_instance; + w->userdata = p_userdata; + w->method = p_method; + w->index = &index; + w->max_elements = p_elements; + + for (uint32_t i = 0; i < thread_count; i++) { + threads[i].work = w; + threads[i].start.post(); + } + for (uint32_t i = 0; i < thread_count; i++) { + threads[i].completed.wait(); + threads[i].work = nullptr; + } + } + + void init(int p_thread_count = -1); + void finish(); + ~ThreadWorkPool(); +}; + +#endif // THREAD_POOL_H -- cgit v1.2.3