From 27316923d34bf700f4928c83c5b40d5c4817bb3c Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 10 Sep 2022 04:16:50 +0200 Subject: [PATCH] Moved ThreadPool to core. Also it can change it's thread count now when it has time for it. --- .../thread_pool => core/os}/thread_pool.cpp | 105 ++++++++++++++-- .../thread_pool => core/os}/thread_pool.h | 13 +- .../os}/thread_pool_execute_job.cpp | 0 .../os}/thread_pool_execute_job.h | 0 .../os}/thread_pool_job.cpp | 0 .../thread_pool => core/os}/thread_pool_job.h | 0 core/register_core_types.cpp | 30 +++-- .../classes}/ThreadPool.xml | 0 .../classes}/ThreadPoolExecuteJob.xml | 0 .../classes}/ThreadPoolJob.xml | 0 doc/engine/props.md | 3 +- doc/engine/props_2d.md | 3 +- doc/engine/terraman.md | 4 +- doc/engine/terraman_2d.md | 2 +- doc/engine/voxelman.md | 3 +- modules/material_maker/nodes/mm_material.cpp | 4 +- modules/props/SCsub | 4 - modules/props/jobs/prop_texture_job.cpp | 108 ----------------- modules/props/jobs/prop_texture_job.h | 49 +------- modules/props/prop_instance_job.cpp | 108 ----------------- modules/props/prop_instance_job.h | 52 +------- modules/props/prop_instance_merger.cpp | 16 +-- modules/props/singleton/prop_cache.cpp | 4 +- modules/props_2d/SCsub | 4 - modules/props_2d/jobs/prop_2d_texture_job.cpp | 108 ----------------- modules/props_2d/jobs/prop_2d_texture_job.h | 49 +------- modules/props_2d/prop_2d_instance_job.cpp | 109 ----------------- modules/props_2d/prop_2d_instance_job.h | 53 +-------- modules/props_2d/prop_2d_instance_merger.cpp | 16 +-- modules/props_2d/singleton/prop_2d_cache.cpp | 4 +- modules/terraman/SCsub | 3 - modules/terraman/world/jobs/terrain_job.cpp | 111 +---------------- modules/terraman/world/jobs/terrain_job.h | 51 +------- modules/terraman/world/terrain_chunk.cpp | 22 +--- modules/terraman_2d/SCsub | 3 - .../terraman_2d/world/jobs/terrain_2d_job.cpp | 109 ----------------- .../terraman_2d/world/jobs/terrain_2d_job.h | 51 +------- .../terraman_2d/world/terrain_2d_chunk.cpp | 22 +--- modules/thread_pool/.gitignore | 8 -- modules/thread_pool/LICENSE | 19 --- modules/thread_pool/SCsub | 27 ----- modules/thread_pool/config.py | 19 --- modules/thread_pool/register_types.cpp | 48 -------- modules/thread_pool/register_types.h | 31 ----- modules/voxelman/SCsub | 3 - modules/voxelman/world/jobs/voxel_job.cpp | 112 +----------------- modules/voxelman/world/jobs/voxel_job.h | 51 +------- modules/voxelman/world/voxel_chunk.cpp | 16 +-- scene/main/scene_tree.cpp | 3 + 49 files changed, 153 insertions(+), 1407 deletions(-) rename {modules/thread_pool => core/os}/thread_pool.cpp (85%) rename {modules/thread_pool => core/os}/thread_pool.h (95%) rename {modules/thread_pool => core/os}/thread_pool_execute_job.cpp (100%) rename {modules/thread_pool => core/os}/thread_pool_execute_job.h (100%) rename {modules/thread_pool => core/os}/thread_pool_job.cpp (100%) rename {modules/thread_pool => core/os}/thread_pool_job.h (100%) rename {modules/thread_pool/doc_classes => doc/classes}/ThreadPool.xml (100%) rename {modules/thread_pool/doc_classes => doc/classes}/ThreadPoolExecuteJob.xml (100%) rename {modules/thread_pool/doc_classes => doc/classes}/ThreadPoolJob.xml (100%) delete mode 100644 modules/thread_pool/.gitignore delete mode 100644 modules/thread_pool/LICENSE delete mode 100644 modules/thread_pool/SCsub delete mode 100644 modules/thread_pool/config.py delete mode 100644 modules/thread_pool/register_types.cpp delete mode 100644 modules/thread_pool/register_types.h diff --git a/modules/thread_pool/thread_pool.cpp b/core/os/thread_pool.cpp similarity index 85% rename from modules/thread_pool/thread_pool.cpp rename to core/os/thread_pool.cpp index c68621ece..7f2bbcede 100644 --- a/modules/thread_pool/thread_pool.cpp +++ b/core/os/thread_pool.cpp @@ -41,6 +41,7 @@ bool ThreadPool::get_use_threads() const { } void ThreadPool::set_use_threads(const bool value) { _use_threads = value; + _dirty = true; } int ThreadPool::get_thread_count() const { @@ -48,6 +49,7 @@ int ThreadPool::get_thread_count() const { } void ThreadPool::set_thread_count(const bool value) { _thread_count = value; + _dirty = true; } int ThreadPool::get_thread_fallback_count() const { @@ -55,6 +57,7 @@ int ThreadPool::get_thread_fallback_count() const { } void ThreadPool::set_thread_fallback_count(const bool value) { _thread_fallback_count = value; + _dirty = true; } float ThreadPool::get_max_work_per_frame_percent() const { @@ -62,6 +65,7 @@ float ThreadPool::get_max_work_per_frame_percent() const { } void ThreadPool::set_max_work_per_frame_percent(const bool value) { _max_work_per_frame_percent = value; + _dirty = true; } float ThreadPool::get_max_time_per_frame() const { @@ -69,6 +73,42 @@ float ThreadPool::get_max_time_per_frame() const { } void ThreadPool::set_max_time_per_frame(const bool value) { _max_time_per_frame = value; + _dirty = true; +} + +bool ThreadPool::is_working() const { + _THREAD_SAFE_LOCK_ + + if (_queue.size() > 0) { + _THREAD_SAFE_UNLOCK_ + + return true; + } + + for (int i = 0; i < _threads.size(); ++i) { + if (_threads[i]->job.is_valid()) { + _THREAD_SAFE_UNLOCK_ + return true; + } + } + + _THREAD_SAFE_UNLOCK_ + + return false; +} + +bool ThreadPool::is_working_no_lock() const { + if (_queue.size() > 0) { + return true; + } + + for (int i = 0; i < _threads.size(); ++i) { + if (_threads[i]->job.is_valid()) { + return true; + } + } + + return false; } bool ThreadPool::has_job(const Ref &job) { @@ -189,11 +229,15 @@ void ThreadPool::_worker_thread_func(void *user_data) { } } -void ThreadPool::register_update() { - SceneTree::get_singleton()->connect("idle_frame", this, "update"); -} - void ThreadPool::update() { + if (_dirty) { + apply_settings(); + } + + if (_use_threads) { + return; + } + if (_queue.size() == 0) { return; } @@ -219,9 +263,7 @@ void ThreadPool::update() { } } -ThreadPool::ThreadPool() { - _instance = this; - +void ThreadPool::register_core_settings() { _use_threads = GLOBAL_DEF("thread_pool/use_threads", true); _thread_count = GLOBAL_DEF("thread_pool/thread_count", -1); _thread_fallback_count = GLOBAL_DEF("thread_pool/thread_fallback_count", 4); @@ -251,7 +293,43 @@ ThreadPool::ThreadPool() { if (_thread_count <= 0) { _thread_count = _thread_fallback_count; } + } + _dirty = true; + + apply_settings(); +} + +void ThreadPool::apply_settings() { + if (!_dirty) { + return; + } + + _THREAD_SAFE_LOCK_ + + if (is_working_no_lock()) { + _THREAD_SAFE_UNLOCK_ + return; + } + + _dirty = false; + + for (int i = 0; i < _threads.size(); ++i) { + ThreadPoolContext *context = _threads[i]; + + CRASH_COND(context->job.is_valid()); + + context->running = false; + context->semaphore->post(); + context->thread->wait_to_finish(); + memdelete(context->thread); + memdelete(context->semaphore); + memdelete(context); + } + + _threads.resize(0); + + if (_use_threads) { _threads.resize(_thread_count); for (int i = 0; i < _threads.size(); ++i) { @@ -265,9 +343,14 @@ ThreadPool::ThreadPool() { _threads.write[i] = context; } - } else { - call_deferred("register_update"); } + + _THREAD_SAFE_UNLOCK_ +} + +ThreadPool::ThreadPool() { + _instance = this; + _dirty = false; } ThreadPool::~ThreadPool() { @@ -315,12 +398,14 @@ void ThreadPool::_bind_methods() { ClassDB::bind_method(D_METHOD("set_max_time_per_frame", "value"), &ThreadPool::set_max_time_per_frame); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_time_per_frame"), "set_max_time_per_frame", "get_max_time_per_frame"); + ClassDB::bind_method(D_METHOD("is_working"), &ThreadPool::is_working); + ClassDB::bind_method(D_METHOD("is_working_no_lock"), &ThreadPool::is_working_no_lock); + ClassDB::bind_method(D_METHOD("has_job", "job"), &ThreadPool::has_job); ClassDB::bind_method(D_METHOD("add_job", "job"), &ThreadPool::add_job); ClassDB::bind_method(D_METHOD("cancel_job", "job"), &ThreadPool::cancel_job); ClassDB::bind_method(D_METHOD("cancel_job_wait", "job"), &ThreadPool::cancel_job_wait); - ClassDB::bind_method(D_METHOD("register_update"), &ThreadPool::register_update); ClassDB::bind_method(D_METHOD("update"), &ThreadPool::update); } diff --git a/modules/thread_pool/thread_pool.h b/core/os/thread_pool.h similarity index 95% rename from modules/thread_pool/thread_pool.h rename to core/os/thread_pool.h index d957a622d..ed9abbcdb 100644 --- a/modules/thread_pool/thread_pool.h +++ b/core/os/thread_pool.h @@ -25,9 +25,9 @@ SOFTWARE. */ -#include "core/object/object.h" -#include "core/containers/vector.h" #include "core/containers/list.h" +#include "core/containers/vector.h" +#include "core/object/object.h" #include "core/os/semaphore.h" #include "core/os/thread.h" @@ -72,6 +72,9 @@ public: float get_max_time_per_frame() const; void set_max_time_per_frame(const bool value); + bool is_working() const; + bool is_working_no_lock() const; + bool has_job(const Ref &job); void add_job(const Ref &job); @@ -81,9 +84,12 @@ public: void _thread_finished(ThreadPoolContext *context); static void _worker_thread_func(void *user_data); - void register_update(); void update(); + void register_core_settings(); + + void apply_settings(); + ThreadPool(); ~ThreadPool(); @@ -93,6 +99,7 @@ protected: private: static ThreadPool *_instance; + bool _dirty; bool _use_threads; int _thread_count; int _thread_fallback_count; diff --git a/modules/thread_pool/thread_pool_execute_job.cpp b/core/os/thread_pool_execute_job.cpp similarity index 100% rename from modules/thread_pool/thread_pool_execute_job.cpp rename to core/os/thread_pool_execute_job.cpp diff --git a/modules/thread_pool/thread_pool_execute_job.h b/core/os/thread_pool_execute_job.h similarity index 100% rename from modules/thread_pool/thread_pool_execute_job.h rename to core/os/thread_pool_execute_job.h diff --git a/modules/thread_pool/thread_pool_job.cpp b/core/os/thread_pool_job.cpp similarity index 100% rename from modules/thread_pool/thread_pool_job.cpp rename to core/os/thread_pool_job.cpp diff --git a/modules/thread_pool/thread_pool_job.h b/core/os/thread_pool_job.h similarity index 100% rename from modules/thread_pool/thread_pool_job.h rename to core/os/thread_pool_job.h diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index e9422d39c..510069f7e 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -31,14 +31,14 @@ #include "register_core_types.h" #include "core/bind/core_bind.h" -#include "core/object/class_db.h" -#include "core/string/compressed_translation.h" +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/containers/packed_data_container.h" #include "core/core_string_names.h" #include "core/crypto/aes_context.h" #include "core/crypto/crypto.h" #include "core/crypto/hashing_context.h" -#include "core/config/engine.h" -#include "core/object/func_ref.h" +#include "core/input/input.h" #include "core/input/input_map.h" #include "core/io/config_file.h" #include "core/io/dtls_server.h" @@ -65,13 +65,17 @@ #include "core/math/geometry.h" #include "core/math/random_number_generator.h" #include "core/math/triangle_mesh.h" -#include "core/input/input.h" +#include "core/object/class_db.h" +#include "core/object/func_ref.h" +#include "core/object/undo_redo.h" #include "core/os/main_loop.h" #include "core/os/time.h" -#include "core/containers/packed_data_container.h" -#include "core/config/project_settings.h" +#include "core/string/compressed_translation.h" #include "core/string/translation.h" -#include "core/object/undo_redo.h" + +#include "core/os/thread_pool.h" +#include "core/os/thread_pool_execute_job.h" +#include "core/os/thread_pool_job.h" #include "core/bind/logger_bind.h" #include "core/log/logger_backend.h" @@ -92,6 +96,7 @@ static _ClassDB *_classdb = nullptr; static _Marshalls *_marshalls = nullptr; static _JSON *_json = nullptr; static _PLogger *_plogger = nullptr; +static ThreadPool *thread_pool = NULL; static IP *ip = nullptr; @@ -232,6 +237,8 @@ void register_core_types() { _marshalls = memnew(_Marshalls); _json = memnew(_JSON); _plogger = memnew(_PLogger); + + thread_pool = memnew(ThreadPool); } void register_core_settings() { @@ -243,6 +250,8 @@ void register_core_settings() { GLOBAL_DEF("network/ssl/certificates", ""); ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt")); + + ThreadPool::get_singleton()->register_core_settings(); } void register_core_singletons() { @@ -262,6 +271,9 @@ void register_core_singletons() { ClassDB::register_class(); ClassDB::register_class