From a31219731e799d8a2a3dd328800b243c4adb1591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Ospina=20De=20Los=20R=C3=ADos?= Date: Tue, 16 Apr 2024 15:50:36 +0200 Subject: [PATCH] Store all control classes in one variable & initialize/destroy on governor --- src/tbb/global_control.cpp | 41 +++++++++++++++++++++++--------------- src/tbb/governor.cpp | 4 ++++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/tbb/global_control.cpp b/src/tbb/global_control.cpp index 5559e0c7dc..65ad198934 100644 --- a/src/tbb/global_control.cpp +++ b/src/tbb/global_control.cpp @@ -28,8 +28,7 @@ #include #include -#include -#include +#include namespace tbb { namespace detail { @@ -141,20 +140,30 @@ class alignas(max_nfs_size) lifetime_control : public control_storage { } }; -static std::array, 4> controls; -static std::once_flag control_storage_flag; +struct control_storage_instance { + allowed_parallelism_control allowed_parallelism_ctl; + stack_size_control stack_size_ctl; + terminate_on_exception_control terminate_on_exception_ctl; + lifetime_control lifetime_ctl; +}; +static control_storage_instance* control_storage_instance_ptr = nullptr; +static control_storage *controls[4] = {nullptr, nullptr, nullptr, nullptr}; + +void global_control_acquire() { + control_storage_instance_ptr = new control_storage_instance{}; + controls[0] = &control_storage_instance_ptr->allowed_parallelism_ctl; + controls[1] = &control_storage_instance_ptr->stack_size_ctl; + controls[2] = &control_storage_instance_ptr->terminate_on_exception_ctl; + controls[3] = &control_storage_instance_ptr->lifetime_ctl; +} -void global_control_init() { - controls[0] = std::unique_ptr(new allowed_parallelism_control{}); - controls[1] = std::unique_ptr(new stack_size_control{}); - controls[2] = std::unique_ptr(new terminate_on_exception_control{}); - controls[3] = std::unique_ptr(new lifetime_control{}); +void global_control_release() { + for (auto& ptr : controls) + ptr = nullptr; + delete control_storage_instance_ptr; } void global_control_lock() { - std::call_once(control_storage_flag, []() { - global_control_init(); - }); for (auto& ctl : controls) { ctl->my_list_mutex.lock(); } @@ -197,7 +206,7 @@ struct global_control_impl { static void create(d1::global_control& gc) { __TBB_ASSERT_RELEASE(gc.my_param < d1::global_control::parameter_max, nullptr); - control_storage* const c = controls[gc.my_param].get(); + control_storage* const c = controls[gc.my_param]; spin_mutex::scoped_lock lock(c->my_list_mutex); if (c->my_list.empty() || c->is_first_arg_preferred(gc.my_value, c->my_active_value)) { @@ -210,7 +219,7 @@ struct global_control_impl { static void destroy(d1::global_control& gc) { __TBB_ASSERT_RELEASE(gc.my_param < d1::global_control::parameter_max, nullptr); - control_storage* const c = controls[gc.my_param].get(); + control_storage* const c = controls[gc.my_param]; // Concurrent reading and changing global parameter is possible. spin_mutex::scoped_lock lock(c->my_list_mutex); __TBB_ASSERT(gc.my_param == d1::global_control::scheduler_handle || !c->my_list.empty(), nullptr); @@ -233,7 +242,7 @@ struct global_control_impl { static bool remove_and_check_if_empty(d1::global_control& gc) { __TBB_ASSERT_RELEASE(gc.my_param < d1::global_control::parameter_max, nullptr); - control_storage* const c = controls[gc.my_param].get(); + control_storage* const c = controls[gc.my_param]; spin_mutex::scoped_lock lock(c->my_list_mutex); __TBB_ASSERT(!c->my_list.empty(), nullptr); @@ -243,7 +252,7 @@ struct global_control_impl { #if TBB_USE_ASSERT static bool is_present(d1::global_control& gc) { __TBB_ASSERT_RELEASE(gc.my_param < d1::global_control::parameter_max, nullptr); - control_storage* const c = controls[gc.my_param].get(); + control_storage* const c = controls[gc.my_param]; spin_mutex::scoped_lock lock(c->my_list_mutex); auto it = c->my_list.find(&gc); diff --git a/src/tbb/governor.cpp b/src/tbb/governor.cpp index 1a66f5decd..b9d6da0f38 100644 --- a/src/tbb/governor.cpp +++ b/src/tbb/governor.cpp @@ -42,6 +42,8 @@ namespace detail { namespace r1 { void clear_address_waiter_table(); +void global_control_acquire(); +void global_control_release(); //! global_control.cpp contains definition bool remove_and_check_if_empty(d1::global_control& gc); @@ -60,6 +62,7 @@ namespace system_topology { //------------------------------------------------------------------------ void governor::acquire_resources () { + global_control_acquire(); #if __TBB_USE_POSIX int status = theTLS.create(auto_terminate); #else @@ -85,6 +88,7 @@ void governor::release_resources () { system_topology::destroy(); dynamic_unlink_all(); + global_control_release(); } rml::tbb_server* governor::create_rml_server ( rml::tbb_client& client ) {