From da3b2f3905d697369e1565680dc15cbae207f9fa Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Thu, 8 Jun 2023 14:18:13 +0200 Subject: [PATCH] Slic3r::ThreadData structure will now be available at each thread started by slicer. Initially the thread data provides thread specific random number generator and it supports switching the current thread locale to C. --- src/libslic3r/Thread.cpp | 12 +++++++++--- src/libslic3r/Thread.hpp | 28 +++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/Thread.cpp b/src/libslic3r/Thread.cpp index 924fbe922..f04075027 100644 --- a/src/libslic3r/Thread.cpp +++ b/src/libslic3r/Thread.cpp @@ -211,6 +211,12 @@ bool is_main_thread_active() return get_main_thread_id() == boost::this_thread::get_id(); } +static thread_local ThreadData s_thread_data; +ThreadData& thread_data() +{ + return s_thread_data; +} + // Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID. // Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator. void name_tbb_thread_pool_threads_set_locale() @@ -274,16 +280,16 @@ void set_current_thread_qos() #endif // __APPLE__ } -void TBBLocalesSetter::on_scheduler_entry(bool is_worker) +void ThreadData::tbb_worker_thread_set_c_locales() { // static std::atomic cnt = 0; // std::cout << "TBBLocalesSetter Entering " << cnt ++ << " ID " << std::this_thread::get_id() << "\n"; - if (bool& is_locales_sets = m_is_locales_sets.local(); !is_locales_sets) { + if (! m_tbb_worker_thread_c_locales_set) { // Set locales of the worker thread to "C". set_c_locales(); // OSX specific: Elevate QOS on Apple Silicon. set_current_thread_qos(); - is_locales_sets = true; + m_tbb_worker_thread_c_locales_set = true; } } diff --git a/src/libslic3r/Thread.hpp b/src/libslic3r/Thread.hpp index 19ad29801..61629addf 100644 --- a/src/libslic3r/Thread.hpp +++ b/src/libslic3r/Thread.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,27 @@ template inline boost::thread create_thread(Fn &&fn) return create_thread(attrs, std::forward(fn)); } +class ThreadData { +public: + std::mt19937& random_generator() { + if (! m_random_generator_initialized) { + std::random_device rd; + m_random_generator.seed(rd()); + m_random_generator_initialized = true; + } + return m_random_generator; + } + + void tbb_worker_thread_set_c_locales(); + +private: + std::mt19937 m_random_generator; + bool m_random_generator_initialized { false }; + bool m_tbb_worker_thread_c_locales_set { false }; +}; + +ThreadData& thread_data(); + // For unknown reasons and in sporadic cases when GCode export is processing, some participating thread // in tbb::parallel_pipeline has not set locales to "C", probably because this thread is newly spawned. // So in this class method on_scheduler_entry is called for every thread before it starts participating @@ -79,11 +101,7 @@ class TBBLocalesSetter : public tbb::task_scheduler_observer public: TBBLocalesSetter() { this->observe(true); } ~TBBLocalesSetter() override { this->observe(false); }; - - void on_scheduler_entry(bool is_worker) override; - -private: - tbb::enumerable_thread_specific, tbb::ets_key_usage_type::ets_key_per_instance> m_is_locales_sets{ false }; + void on_scheduler_entry(bool /* is_worker */) override { thread_data().tbb_worker_thread_set_c_locales(); } }; }