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.
This commit is contained in:
Vojtech Bubnik 2023-06-08 14:18:13 +02:00
parent 8b255e8e9b
commit da3b2f3905
2 changed files with 32 additions and 8 deletions

View File

@ -211,6 +211,12 @@ bool is_main_thread_active()
return get_main_thread_id() == boost::this_thread::get_id(); 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. // 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. // 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() void name_tbb_thread_pool_threads_set_locale()
@ -274,16 +280,16 @@ void set_current_thread_qos()
#endif // __APPLE__ #endif // __APPLE__
} }
void TBBLocalesSetter::on_scheduler_entry(bool is_worker) void ThreadData::tbb_worker_thread_set_c_locales()
{ {
// static std::atomic<int> cnt = 0; // static std::atomic<int> cnt = 0;
// std::cout << "TBBLocalesSetter Entering " << cnt ++ << " ID " << std::this_thread::get_id() << "\n"; // 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 locales of the worker thread to "C".
set_c_locales(); set_c_locales();
// OSX specific: Elevate QOS on Apple Silicon. // OSX specific: Elevate QOS on Apple Silicon.
set_current_thread_qos(); set_current_thread_qos();
is_locales_sets = true; m_tbb_worker_thread_c_locales_set = true;
} }
} }

View File

@ -4,6 +4,7 @@
#include <utility> #include <utility>
#include <string> #include <string>
#include <thread> #include <thread>
#include <random>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <tbb/task_scheduler_observer.h> #include <tbb/task_scheduler_observer.h>
@ -67,6 +68,27 @@ template<class Fn> inline boost::thread create_thread(Fn &&fn)
return create_thread(attrs, std::forward<Fn>(fn)); return create_thread(attrs, std::forward<Fn>(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 // 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. // 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 // 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: public:
TBBLocalesSetter() { this->observe(true); } TBBLocalesSetter() { this->observe(true); }
~TBBLocalesSetter() override { this->observe(false); }; ~TBBLocalesSetter() override { this->observe(false); };
void on_scheduler_entry(bool /* is_worker */) override { thread_data().tbb_worker_thread_set_c_locales(); }
void on_scheduler_entry(bool is_worker) override;
private:
tbb::enumerable_thread_specific<bool, tbb::cache_aligned_allocator<bool>, tbb::ets_key_usage_type::ets_key_per_instance> m_is_locales_sets{ false };
}; };
} }