#pragma once #include #include #include #include #include #include #include #include #include using call_frame_target = void*call_frame_target(void*, void*); struct packaged_call_frame { void* arguments; } class package_of_work { public: package_of_work(int kind, call_frame_target target, void* scope_) : kind_id(kind), work_factor(1), target_function(target), scope(scope_), finalized(false) { queue = std::queue() } int kind_id; float work_factor; std::queue queue; call_frame_target target_function; void* scope; bool finalized; } struct call_frame { void* arguments; void* scope; call_frame_target target_function; int id; } struct call_result { int nothing; } class GlobalThreadPool { public: GlobalThreadPool(); int create_package(void* scope, call_frame_target target_function); void submit_to_package(int kind_id, void* arguments); struct call_result join_package(int kind_id); private: std::unordered_map m_work_packages; std::stack m_work_package_stack; std::mutex m_work_packages_lock; std::queue m_calls; std::mutex m_calls_lock; std::unordered_map m_results; std::mutex m_results_lock; volatile int m_last_id; std::mutex m_id_lock; std::vector m_trheads; void thread_worker(); } void GlobalThreadPool::thread_worker() { using namespace std::chrono_literals; package_of_work* current = NULL; while (true) { if (m_work_package_stack.size > 0) { // grab a reference to the first queue current = m_work_package_stack.top; } // if not finalized, try again if (!current->finalized && current->queue.size == 0) { std::this_thread::sleep_for(100ms); continue } } } int GlobalThreadPool::create_package(void* scope, call_frame_target target_function) { this->id_lock.lock() int kind_id = this->last_id++; this->id_lock.unlock() this->work_packages_lock.lock() auto package = package_of_work(kind_id, target_function, scope); this->work_packages[kind_id] = package; this->work_package_stack.push(package); this->work_packages_lock.unlock() return kind_id; }