summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIbrahn Sahir <ibrahn.sahir@gmail.com>2021-10-30 20:27:46 +0100
committerIbrahn Sahir <ibrahn.sahir@gmail.com>2021-11-01 19:19:25 +0000
commit151d2e34caff77b9b2ffcadea1e4fa0a7ddd450c (patch)
tree20007c3c0ddf14d3805458cec1cdb9cb794fe89b
parent1aef3a42b234b86c5db21d5a64509453e6bf145c (diff)
ThreadWorkPool no longer starts worker threads if given zero work.
-rw-r--r--core/templates/thread_work_pool.h24
-rw-r--r--servers/physics_2d/godot_step_2d.cpp6
-rw-r--r--servers/physics_3d/godot_step_3d.cpp6
3 files changed, 22 insertions, 14 deletions
diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h
index b242648bc8..19096c496a 100644
--- a/core/templates/thread_work_pool.h
+++ b/core/templates/thread_work_pool.h
@@ -73,6 +73,7 @@ class ThreadWorkPool {
ThreadData *threads = nullptr;
uint32_t thread_count = 0;
+ uint32_t threads_working = 0;
BaseWork *current_work = nullptr;
static void _thread_function(void *p_user);
@@ -94,7 +95,9 @@ public:
current_work = w;
- for (uint32_t i = 0; i < thread_count; i++) {
+ threads_working = MIN(p_elements, thread_count);
+
+ for (uint32_t i = 0; i < threads_working; i++) {
threads[i].work = w;
threads[i].start.post();
}
@@ -117,19 +120,32 @@ public:
void end_work() {
ERR_FAIL_COND(current_work == nullptr);
- for (uint32_t i = 0; i < thread_count; i++) {
+ for (uint32_t i = 0; i < threads_working; i++) {
threads[i].completed.wait();
threads[i].work = nullptr;
}
+ threads_working = 0;
memdelete(current_work);
current_work = nullptr;
}
template <class C, class M, class U>
void do_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
- begin_work(p_elements, p_instance, p_method, p_userdata);
- end_work();
+ switch (p_elements) {
+ case 0:
+ // Nothing to do, so do nothing.
+ break;
+ case 1:
+ // No value in pushing the work to another thread if it's a single job
+ // and we're going to wait for it to finish. Just run it right here.
+ (p_instance->*p_method)(0, p_userdata);
+ break;
+ default:
+ // Multiple jobs to do; commence threaded business.
+ begin_work(p_elements, p_instance, p_method, p_userdata);
+ end_work();
+ }
}
_FORCE_INLINE_ int get_thread_count() const { return thread_count; }
diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp
index 3010315571..84ec0e3c63 100644
--- a/servers/physics_2d/godot_step_2d.cpp
+++ b/servers/physics_2d/godot_step_2d.cpp
@@ -255,11 +255,7 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta, int p_iterations)
// Warning: _solve_island modifies the constraint islands for optimization purpose,
// their content is not reliable after these calls and shouldn't be used anymore.
- if (island_count > 1) {
- work_pool.do_work(island_count, this, &GodotStep2D::_solve_island, nullptr);
- } else if (island_count > 0) {
- _solve_island(0);
- }
+ work_pool.do_work(island_count, this, &GodotStep2D::_solve_island, nullptr);
{ //profile
profile_endtime = OS::get_singleton()->get_ticks_usec();
diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp
index a8654c617b..331d65df49 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/servers/physics_3d/godot_step_3d.cpp
@@ -359,11 +359,7 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta, int p_iterations)
// Warning: _solve_island modifies the constraint islands for optimization purpose,
// their content is not reliable after these calls and shouldn't be used anymore.
- if (island_count > 1) {
- work_pool.do_work(island_count, this, &GodotStep3D::_solve_island, nullptr);
- } else if (island_count > 0) {
- _solve_island(0);
- }
+ work_pool.do_work(island_count, this, &GodotStep3D::_solve_island, nullptr);
{ //profile
profile_endtime = OS::get_singleton()->get_ticks_usec();