Skip to content

Commit

Permalink
Use WorkerThreadPool for Server threads
Browse files Browse the repository at this point in the history
* Servers now use WorkerThreadPool for background computation.
* This helps keep the number of threads used fixed at all times.
* It also ensures everything works on HTML5 with threads.
* And makes it easier to support disabling threads for also HTML5.

The only downside of this is that GLES3 threads likely no longer work because every time the render thread is called, the thread context is different. This needs to be researched how to fix. Maybe if GLES3 is used, threaded rendering server should be disabled for the time being?
  • Loading branch information
reduz committed May 12, 2023
1 parent 20ed51a commit d2efed2
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 201 deletions.
65 changes: 15 additions & 50 deletions servers/physics_server_2d_wrap_mt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,18 @@

#include "core/os/os.h"

void PhysicsServer2DWrapMT::thread_exit() {
exit.set();
}

void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
physics_server_2d->step(p_delta);
step_sem.post();
}

void PhysicsServer2DWrapMT::_thread_callback(void *_instance) {
PhysicsServer2DWrapMT *vsmt = reinterpret_cast<PhysicsServer2DWrapMT *>(_instance);

vsmt->thread_loop();
}

void PhysicsServer2DWrapMT::thread_loop() {
server_thread = Thread::get_caller_id();

physics_server_2d->init();

exit.clear();
step_thread_up.set();
while (!exit.is_set()) {
// flush commands one by one, until exit is requested
command_queue.wait_and_flush();
}

command_queue.flush_all(); // flush all

physics_server_2d->finish();
physics_server_2d->step(p_delta);
command_queue.flush_all();
server_thread = Thread::UNASSIGNED_ID;
}

/* EVENT QUEUING */

void PhysicsServer2DWrapMT::step(real_t p_step) {
if (create_thread) {
command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step);
task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer2DWrapMT::thread_step).bind(p_step), true);
} else {
command_queue.flush_all(); //flush all pending from other threads
physics_server_2d->step(p_step);
Expand All @@ -77,10 +52,9 @@ void PhysicsServer2DWrapMT::step(real_t p_step) {

void PhysicsServer2DWrapMT::sync() {
if (create_thread) {
if (first_frame) {
first_frame = false;
} else {
step_sem.wait(); //must not wait if a step was not issued
if (task_id != WorkerThreadPool::INVALID_TASK_ID) {
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id);
task_id = WorkerThreadPool::INVALID_TASK_ID;
}
}
physics_server_2d->sync();
Expand All @@ -95,24 +69,15 @@ void PhysicsServer2DWrapMT::end_sync() {
}

void PhysicsServer2DWrapMT::init() {
if (create_thread) {
//OS::get_singleton()->release_rendering_thread();
thread.start(_thread_callback, this);
while (!step_thread_up.is_set()) {
OS::get_singleton()->delay_usec(1000);
}
} else {
physics_server_2d->init();
}
physics_server_2d->init();
}

void PhysicsServer2DWrapMT::finish() {
if (thread.is_started()) {
command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit);
thread.wait_to_finish();
} else {
physics_server_2d->finish();
if (task_id != WorkerThreadPool::INVALID_TASK_ID) {
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id);
task_id = WorkerThreadPool::INVALID_TASK_ID;
}
physics_server_2d->finish();
}

PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) :
Expand All @@ -123,12 +88,12 @@ PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");

if (!p_create_thread) {
server_thread = Thread::get_caller_id();
server_thread = Thread::MAIN_ID;
} else {
server_thread = 0;
server_thread = Thread::UNASSIGNED_ID;
}

main_thread = Thread::get_caller_id();
main_thread = Thread::MAIN_ID;
}

PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() {
Expand Down
12 changes: 2 additions & 10 deletions servers/physics_server_2d_wrap_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define PHYSICS_SERVER_2D_WRAP_MT_H

#include "core/config/project_settings.h"
#include "core/object/worker_thread_pool.h"
#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/safe_refcount.h"
Expand All @@ -49,23 +50,14 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D {
mutable CommandQueueMT command_queue;

static void _thread_callback(void *_instance);
void thread_loop();

Thread::ID server_thread;
Thread::ID main_thread;
SafeFlag exit;
Thread thread;
SafeFlag step_thread_up;
bool create_thread = false;
WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID;

Semaphore step_sem;
void thread_step(real_t p_delta);

void thread_exit();

bool first_frame = true;

Mutex alloc_mutex;
int pool_max_size = 0;

public:
Expand Down
65 changes: 15 additions & 50 deletions servers/physics_server_3d_wrap_mt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,18 @@

#include "core/os/os.h"

void PhysicsServer3DWrapMT::thread_exit() {
exit = true;
}

void PhysicsServer3DWrapMT::thread_step(real_t p_delta) {
physics_server_3d->step(p_delta);
step_sem.post();
}

void PhysicsServer3DWrapMT::_thread_callback(void *_instance) {
PhysicsServer3DWrapMT *vsmt = reinterpret_cast<PhysicsServer3DWrapMT *>(_instance);

vsmt->thread_loop();
}

void PhysicsServer3DWrapMT::thread_loop() {
server_thread = Thread::get_caller_id();

physics_server_3d->init();

exit = false;
step_thread_up = true;
while (!exit) {
// flush commands one by one, until exit is requested
command_queue.wait_and_flush();
}

command_queue.flush_all(); // flush all

physics_server_3d->finish();
physics_server_3d->step(p_delta);
command_queue.flush_all();
server_thread = Thread::UNASSIGNED_ID;
}

/* EVENT QUEUING */

void PhysicsServer3DWrapMT::step(real_t p_step) {
if (create_thread) {
command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step);
task_id = WorkerThreadPool::get_singleton()->add_task(callable_mp(this, &PhysicsServer3DWrapMT::thread_step).bind(p_step), true);
} else {
command_queue.flush_all(); //flush all pending from other threads
physics_server_3d->step(p_step);
Expand All @@ -77,10 +52,9 @@ void PhysicsServer3DWrapMT::step(real_t p_step) {

void PhysicsServer3DWrapMT::sync() {
if (create_thread) {
if (first_frame) {
first_frame = false;
} else {
step_sem.wait(); //must not wait if a step was not issued
if (task_id != WorkerThreadPool::INVALID_TASK_ID) {
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id);
task_id = WorkerThreadPool::INVALID_TASK_ID;
}
}
physics_server_3d->sync();
Expand All @@ -95,24 +69,15 @@ void PhysicsServer3DWrapMT::end_sync() {
}

void PhysicsServer3DWrapMT::init() {
if (create_thread) {
//OS::get_singleton()->release_rendering_thread();
thread.start(_thread_callback, this);
while (!step_thread_up) {
OS::get_singleton()->delay_usec(1000);
}
} else {
physics_server_3d->init();
}
physics_server_3d->init();
}

void PhysicsServer3DWrapMT::finish() {
if (thread.is_started()) {
command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit);
thread.wait_to_finish();
} else {
physics_server_3d->finish();
if (task_id != WorkerThreadPool::INVALID_TASK_ID) {
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id);
task_id = WorkerThreadPool::INVALID_TASK_ID;
}
physics_server_3d->finish();
}

PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) :
Expand All @@ -123,12 +88,12 @@ PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");

if (!p_create_thread) {
server_thread = Thread::get_caller_id();
server_thread = Thread::MAIN_ID;
} else {
server_thread = 0;
server_thread = Thread::UNASSIGNED_ID;
}

main_thread = Thread::get_caller_id();
main_thread = Thread::MAIN_ID;
}

PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() {
Expand Down
12 changes: 2 additions & 10 deletions servers/physics_server_3d_wrap_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define PHYSICS_SERVER_3D_WRAP_MT_H

#include "core/config/project_settings.h"
#include "core/object/worker_thread_pool.h"
#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
#include "servers/physics_server_3d.h"
Expand All @@ -48,23 +49,14 @@ class PhysicsServer3DWrapMT : public PhysicsServer3D {
mutable CommandQueueMT command_queue;

static void _thread_callback(void *_instance);
void thread_loop();

Thread::ID server_thread;
Thread::ID main_thread;
volatile bool exit = false;
Thread thread;
volatile bool step_thread_up = false;
bool create_thread = false;
WorkerThreadPool::TaskID task_id = WorkerThreadPool::INVALID_TASK_ID;

Semaphore step_sem;
void thread_step(real_t p_delta);

void thread_exit();

bool first_frame = true;

Mutex alloc_mutex;
int pool_max_size = 0;

public:
Expand Down
Loading

0 comments on commit d2efed2

Please sign in to comment.