Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Servers truly Thread Safe #45852

Merged
merged 1 commit into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,8 +1244,8 @@ ProjectSettings::ProjectSettings() {

custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects");
GLOBAL_DEF("physics/2d/run_on_thread", false);
GLOBAL_DEF("physics/3d/run_on_thread", false);

GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1");
Expand Down
5 changes: 5 additions & 0 deletions core/templates/command_queue_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ class CommandQueueMT {
flush_one();
}

_FORCE_INLINE_ void flush_if_pending() {
if (unlikely(read_ptr_and_epoch != write_ptr_and_epoch)) {
flush_all();
}
}
void flush_all() {
//ERR_FAIL_COND(sync);
lock();
Expand Down
91 changes: 82 additions & 9 deletions core/templates/rid_owner.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ class RID_Alloc : public RID_AllocBase {

SpinLock spin_lock;

public:
RID make_rid(const T &p_value) {
_FORCE_INLINE_ RID _allocate_rid(const T *p_initializer) {
if (THREAD_SAFE) {
spin_lock.lock();
}
Expand Down Expand Up @@ -115,15 +114,22 @@ class RID_Alloc : public RID_AllocBase {
uint32_t free_chunk = free_index / elements_in_chunk;
uint32_t free_element = free_index % elements_in_chunk;

T *ptr = &chunks[free_chunk][free_element];
memnew_placement(ptr, T(p_value));
if (p_initializer) {
T *ptr = &chunks[free_chunk][free_element];
memnew_placement(ptr, T(*p_initializer));
}

uint32_t validator = (uint32_t)(_gen_id() & 0xFFFFFFFF);
uint32_t validator = (uint32_t)(_gen_id() & 0x7FFFFFFF);
uint64_t id = validator;
id <<= 32;
id |= free_index;

validator_chunks[free_chunk][free_element] = validator;

if (!p_initializer) {
validator_chunks[free_chunk][free_element] |= 0x80000000; //mark uninitialized bit
}

alloc_count++;

if (THREAD_SAFE) {
Expand All @@ -133,7 +139,20 @@ class RID_Alloc : public RID_AllocBase {
return _make_from_id(id);
}

_FORCE_INLINE_ T *getornull(const RID &p_rid) {
public:
RID make_rid(const T &p_value) {
return _allocate_rid(&p_value);
}

//allocate but don't initialize, use initialize_rid afterwards
RID allocate_rid() {
return _allocate_rid(nullptr);
}

_FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) {
if (p_rid == RID()) {
return nullptr;
}
if (THREAD_SAFE) {
spin_lock.lock();
}
Expand All @@ -151,10 +170,32 @@ class RID_Alloc : public RID_AllocBase {
uint32_t idx_element = idx % elements_in_chunk;

uint32_t validator = uint32_t(id >> 32);
if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {

if (unlikely(p_initialize)) {
if (unlikely(!(validator_chunks[idx_chunk][idx_element] & 0x80000000))) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
ERR_FAIL_V_MSG(nullptr, "Initializing already initialized RID");
}

if (unlikely((validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) != validator)) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
ERR_FAIL_V_MSG(nullptr, "Attempting to initialize the wrong RID");
return nullptr;
}

validator_chunks[idx_chunk][idx_element] &= 0x7FFFFFFF; //initialized

} else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
if (validator_chunks[idx_chunk][idx_element] & 0x80000000) {
ERR_FAIL_V_MSG(nullptr, "Attempting to use an uninitialized RID");
}
return nullptr;
}

Expand All @@ -166,6 +207,11 @@ class RID_Alloc : public RID_AllocBase {

return ptr;
}
void initialize_rid(RID p_rid, const T &p_value) {
T *mem = getornull(p_rid, true);
ERR_FAIL_COND(!mem);
memnew_placement(mem, T(p_value));
}

_FORCE_INLINE_ bool owns(const RID &p_rid) {
if (THREAD_SAFE) {
Expand All @@ -186,7 +232,7 @@ class RID_Alloc : public RID_AllocBase {

uint32_t validator = uint32_t(id >> 32);

bool owned = validator_chunks[idx_chunk][idx_element] == validator;
bool owned = (validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) == validator;

if (THREAD_SAFE) {
spin_lock.unlock();
Expand All @@ -213,7 +259,12 @@ class RID_Alloc : public RID_AllocBase {
uint32_t idx_element = idx % elements_in_chunk;

uint32_t validator = uint32_t(id >> 32);
if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
if (unlikely(validator_chunks[idx_chunk][idx_element] & 0x80000000)) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
ERR_FAIL_MSG("Attempted to free an uninitialized or invalid RID");
} else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
Expand Down Expand Up @@ -330,6 +381,14 @@ class RID_PtrOwner {
return alloc.make_rid(p_ptr);
}

_FORCE_INLINE_ RID allocate_rid() {
return alloc.allocate_rid();
}

_FORCE_INLINE_ void initialize_rid(RID p_rid, T *p_ptr) {
alloc.initialize_rid(p_rid, p_ptr);
}

_FORCE_INLINE_ T *getornull(const RID &p_rid) {
T **ptr = alloc.getornull(p_rid);
if (unlikely(!ptr)) {
Expand All @@ -338,6 +397,12 @@ class RID_PtrOwner {
return *ptr;
}

_FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
T **ptr = alloc.getornull(p_rid);
ERR_FAIL_COND(!ptr);
*ptr = p_new_ptr;
}

_FORCE_INLINE_ bool owns(const RID &p_rid) {
return alloc.owns(p_rid);
}
Expand Down Expand Up @@ -379,6 +444,14 @@ class RID_Owner {
return alloc.make_rid(p_ptr);
}

_FORCE_INLINE_ RID allocate_rid() {
return alloc.allocate_rid();
}

_FORCE_INLINE_ void initialize_rid(RID p_rid, const T &p_ptr) {
alloc.initialize_rid(p_rid, p_ptr);
}

_FORCE_INLINE_ T *getornull(const RID &p_rid) {
return alloc.getornull(p_rid);
}
Expand Down
10 changes: 3 additions & 7 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
#include "servers/physics_server_3d.h"
#include "servers/register_server_types.h"
#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_wrap_mt.h"
#include "servers/text_server.h"
#include "servers/xr_server.h"

Expand Down Expand Up @@ -1570,12 +1569,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {

/* Initialize Visual Server */

rendering_server = memnew(RenderingServerDefault);
if (OS::get_singleton()->get_render_thread_mode() != OS::RENDER_THREAD_UNSAFE) {
rendering_server = memnew(RenderingServerWrapMT(rendering_server,
OS::get_singleton()->get_render_thread_mode() ==
OS::RENDER_SEPARATE_THREAD));
}
rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD));

rendering_server->init();
rendering_server->set_render_loop_enabled(!disable_render_loop);
Expand Down Expand Up @@ -2451,6 +2445,7 @@ bool Main::iteration() {
for (int iters = 0; iters < advance.physics_steps; ++iters) {
uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();

PhysicsServer3D::get_singleton()->sync();
PhysicsServer3D::get_singleton()->flush_queries();

PhysicsServer2D::get_singleton()->sync();
Expand All @@ -2465,6 +2460,7 @@ bool Main::iteration() {

message_queue->flush();

PhysicsServer3D::get_singleton()->end_sync();
PhysicsServer3D::get_singleton()->step(physics_step * time_scale);

PhysicsServer2D::get_singleton()->end_sync();
Expand Down
8 changes: 4 additions & 4 deletions modules/bullet/bullet_physics_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1059,16 +1059,16 @@ real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) {
return body->get_linear_stiffness();
}

void BulletPhysicsServer3D::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) {
void BulletPhysicsServer3D::soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) {
SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_areaAngular_stiffness(p_stiffness);
body->set_angular_stiffness(p_stiffness);
}

real_t BulletPhysicsServer3D::soft_body_get_areaAngular_stiffness(RID p_body) {
real_t BulletPhysicsServer3D::soft_body_get_angular_stiffness(RID p_body) {
SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_areaAngular_stiffness();
return body->get_angular_stiffness();
}

void BulletPhysicsServer3D::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) {
Expand Down
4 changes: 2 additions & 2 deletions modules/bullet/bullet_physics_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ class BulletPhysicsServer3D : public PhysicsServer3D {
virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_linear_stiffness(RID p_body) override;

virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override;
virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_angular_stiffness(RID p_body) override;

virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_volume_stiffness(RID p_body) override;
Expand Down
3 changes: 2 additions & 1 deletion modules/bullet/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
# API Changed and bullet is disabled at the moment
return False
reduz marked this conversation as resolved.
Show resolved Hide resolved


def configure(env):
Expand Down
8 changes: 4 additions & 4 deletions modules/bullet/soft_body_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ void SoftBodyBullet::set_linear_stiffness(real_t p_val) {
}
}

void SoftBodyBullet::set_areaAngular_stiffness(real_t p_val) {
areaAngular_stiffness = p_val;
void SoftBodyBullet::set_angular_stiffness(real_t p_val) {
angular_stiffness = p_val;
if (bt_soft_body) {
mat0->m_kAST = areaAngular_stiffness;
mat0->m_kAST = angular_stiffness;
}
}

Expand Down Expand Up @@ -409,7 +409,7 @@ void SoftBodyBullet::setup_soft_body() {
bt_soft_body->generateBendingConstraints(2, mat0);

mat0->m_kLST = linear_stiffness;
mat0->m_kAST = areaAngular_stiffness;
mat0->m_kAST = angular_stiffness;
mat0->m_kVST = volume_stiffness;

// Clusters allow to have Soft vs Soft collision but doesn't work well right now
Expand Down
6 changes: 3 additions & 3 deletions modules/bullet/soft_body_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class SoftBodyBullet : public CollisionObjectBullet {
int simulation_precision = 5;
real_t total_mass = 1.;
real_t linear_stiffness = 0.5; // [0,1]
real_t areaAngular_stiffness = 0.5; // [0,1]
real_t angular_stiffness = 0.5; // [0,1]
real_t volume_stiffness = 0.5; // [0,1]
real_t pressure_coefficient = 0.; // [-inf,+inf]
real_t pose_matching_coefficient = 0.; // [0,1]
Expand Down Expand Up @@ -129,8 +129,8 @@ class SoftBodyBullet : public CollisionObjectBullet {
void set_linear_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; }

void set_areaAngular_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_areaAngular_stiffness() const { return areaAngular_stiffness; }
void set_angular_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_angular_stiffness() const { return angular_stiffness; }

void set_volume_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_volume_stiffness() const { return volume_stiffness; }
Expand Down
6 changes: 4 additions & 2 deletions modules/csg/csg_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ void CSGShape3D::set_use_collision(bool p_enable) {

if (use_collision) {
root_collision_shape.instance();
root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
root_collision_instance = PhysicsServer3D::get_singleton()->body_create();
PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space());
Expand Down Expand Up @@ -494,7 +495,8 @@ void CSGShape3D::_notification(int p_what) {

if (use_collision && is_root_shape()) {
root_collision_shape.instance();
root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
root_collision_instance = PhysicsServer3D::get_singleton()->body_create();
PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space());
Expand Down
5 changes: 3 additions & 2 deletions modules/gridmap/grid_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) {
//create octant because it does not exist
Octant *g = memnew(Octant);
g->dirty = true;
g->static_body = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
g->static_body = PhysicsServer3D::get_singleton()->body_create();
PhysicsServer3D::get_singleton()->body_set_mode(g->static_body, PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
Expand Down Expand Up @@ -491,7 +492,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Octant::MultimeshInstance mmi;

RID mm = RS::get_singleton()->multimesh_create();
RS::get_singleton()->multimesh_allocate(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D);
RS::get_singleton()->multimesh_allocate_data(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D);
RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid());

int idx = 0;
Expand Down
1 change: 0 additions & 1 deletion platform/uwp/os_uwp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include "platform/windows/windows_terminal_logger.h"
#include "servers/audio_server.h"
#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_wrap_mt.h"

#include <ppltasks.h>
#include <wrl.h>
Expand Down
1 change: 0 additions & 1 deletion platform/windows/os_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
#include "platform/windows/display_server_windows.h"
#include "servers/audio_server.h"
#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_wrap_mt.h"
#include "windows_terminal_logger.h"

#include <avrt.h>
Expand Down
2 changes: 1 addition & 1 deletion scene/2d/cpu_particles_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void CPUParticles2D::set_amount(int p_amount) {
}

particle_data.resize((8 + 4 + 4) * p_amount);
RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true);
RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true);

particle_order.resize(p_amount);
}
Expand Down
Loading