From 6414ce3742eaf412664eda255e24ba4dcd2375ce Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 18 Feb 2020 11:39:17 +0100 Subject: [PATCH 1/6] Always use Configuration#Concurrency, not std::thread::hardware_concurrency() refs #7842 --- lib/base/io-engine.cpp | 5 +++-- lib/base/threadpool.hpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/base/io-engine.cpp b/lib/base/io-engine.cpp index 5dd3ee59c..056d3b9bf 100644 --- a/lib/base/io-engine.cpp +++ b/lib/base/io-engine.cpp @@ -1,5 +1,6 @@ /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ +#include "base/configuration.hpp" #include "base/exception.hpp" #include "base/io-engine.hpp" #include "base/lazy-init.hpp" @@ -84,10 +85,10 @@ boost::asio::io_context& IoEngine::GetIoContext() return m_IoContext; } -IoEngine::IoEngine() : m_IoContext(), m_KeepAlive(boost::asio::make_work_guard(m_IoContext)), m_Threads(decltype(m_Threads)::size_type(std::thread::hardware_concurrency() * 2u)), m_AlreadyExpiredTimer(m_IoContext) +IoEngine::IoEngine() : m_IoContext(), m_KeepAlive(boost::asio::make_work_guard(m_IoContext)), m_Threads(decltype(m_Threads)::size_type(Configuration::Concurrency * 2u)), m_AlreadyExpiredTimer(m_IoContext) { m_AlreadyExpiredTimer.expires_at(boost::posix_time::neg_infin); - m_CpuBoundSemaphore.store(std::thread::hardware_concurrency() * 3u / 2u); + m_CpuBoundSemaphore.store(Configuration::Concurrency * 3u / 2u); for (auto& thread : m_Threads) { thread = std::thread(&IoEngine::RunEventLoop, this); diff --git a/lib/base/threadpool.hpp b/lib/base/threadpool.hpp index af351cd7a..f8727034a 100644 --- a/lib/base/threadpool.hpp +++ b/lib/base/threadpool.hpp @@ -4,6 +4,7 @@ #define THREADPOOL_H #include "base/atomic.hpp" +#include "base/configuration.hpp" #include "base/exception.hpp" #include "base/logger.hpp" #include @@ -36,7 +37,7 @@ class ThreadPool public: typedef std::function WorkFunction; - ThreadPool(size_t threads = std::thread::hardware_concurrency() * 2u); + ThreadPool(size_t threads = Configuration::Concurrency * 2u); ~ThreadPool(); void Start(); From 288ad68649febb83ef68468ae55c4a6f63521ca0 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 27 Jan 2023 16:32:29 +0100 Subject: [PATCH 2/6] ThreadPool#ThreadPool(): remove unused parameter --- lib/base/threadpool.cpp | 4 ++-- lib/base/threadpool.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/base/threadpool.cpp b/lib/base/threadpool.cpp index 26787ab52..747d60820 100644 --- a/lib/base/threadpool.cpp +++ b/lib/base/threadpool.cpp @@ -5,8 +5,8 @@ using namespace icinga; -ThreadPool::ThreadPool(size_t threads) - : m_Threads(threads), m_Pending(0) +ThreadPool::ThreadPool() + : m_Threads(Configuration::Concurrency * 2u), m_Pending(0) { Start(); } diff --git a/lib/base/threadpool.hpp b/lib/base/threadpool.hpp index f8727034a..a8a9732f0 100644 --- a/lib/base/threadpool.hpp +++ b/lib/base/threadpool.hpp @@ -37,7 +37,7 @@ class ThreadPool public: typedef std::function WorkFunction; - ThreadPool(size_t threads = Configuration::Concurrency * 2u); + ThreadPool(); ~ThreadPool(); void Start(); From c953ba120659d3b8d5293ba1b5d7271d96945c0f Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 27 Jan 2023 16:34:11 +0100 Subject: [PATCH 3/6] Remove redundant ThreadPool#m_Threads --- lib/base/threadpool.cpp | 5 ++--- lib/base/threadpool.hpp | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/base/threadpool.cpp b/lib/base/threadpool.cpp index 747d60820..21f19fd42 100644 --- a/lib/base/threadpool.cpp +++ b/lib/base/threadpool.cpp @@ -5,8 +5,7 @@ using namespace icinga; -ThreadPool::ThreadPool() - : m_Threads(Configuration::Concurrency * 2u), m_Pending(0) +ThreadPool::ThreadPool() : m_Pending(0) { Start(); } @@ -21,7 +20,7 @@ void ThreadPool::Start() boost::unique_lock lock (m_Mutex); if (!m_Pool) { - m_Pool = decltype(m_Pool)(new boost::asio::thread_pool(m_Threads)); + m_Pool = decltype(m_Pool)(new boost::asio::thread_pool(Configuration::Concurrency * 2u)); } } diff --git a/lib/base/threadpool.hpp b/lib/base/threadpool.hpp index a8a9732f0..f9760bc8b 100644 --- a/lib/base/threadpool.hpp +++ b/lib/base/threadpool.hpp @@ -90,7 +90,6 @@ public: private: boost::shared_mutex m_Mutex; std::unique_ptr m_Pool; - size_t m_Threads; Atomic m_Pending; }; From 8fb5d53118e984e816fb8aeb975b1cc689d59900 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 May 2023 15:41:35 +0200 Subject: [PATCH 4/6] Track Configuration.Concurrency modifications --- lib/base/configuration.cpp | 2 ++ lib/base/configuration.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/lib/base/configuration.cpp b/lib/base/configuration.cpp index d163937e2..1be273faf 100644 --- a/lib/base/configuration.cpp +++ b/lib/base/configuration.cpp @@ -13,6 +13,7 @@ String Configuration::ApiBindPort{"5665"}; bool Configuration::AttachDebugger{false}; String Configuration::CacheDir; int Configuration::Concurrency{static_cast(std::thread::hardware_concurrency())}; +bool Configuration::ConcurrencyWasModified{false}; String Configuration::ConfigDir; String Configuration::DataDir; String Configuration::EventEngine; @@ -101,6 +102,7 @@ int Configuration::GetConcurrency() const void Configuration::SetConcurrency(int val, bool suppress_events, const Value& cookie) { HandleUserWrite("Concurrency", &Configuration::Concurrency, val, m_ReadOnly); + Configuration::ConcurrencyWasModified = true; } String Configuration::GetConfigDir() const diff --git a/lib/base/configuration.hpp b/lib/base/configuration.hpp index 560906596..a5aed01e8 100644 --- a/lib/base/configuration.hpp +++ b/lib/base/configuration.hpp @@ -118,6 +118,7 @@ public: static bool AttachDebugger; static String CacheDir; static int Concurrency; + static bool ConcurrencyWasModified; static String ConfigDir; static String DataDir; static String EventEngine; From 32eb1680f732b713b14bce1191805b74aa5590f7 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 May 2023 16:55:47 +0200 Subject: [PATCH 5/6] Configuration.Concurrency: default to 1 until Configuration freeze not to start many threads before the user could override their amount (-D). --- icinga-app/icinga.cpp | 4 ++++ lib/base/configuration.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index 6b4af7614..f5b6809bc 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -447,6 +447,10 @@ static int Main() Configuration::SetReadOnly(true); + if (!Configuration::ConcurrencyWasModified) { + Configuration::Concurrency = std::thread::hardware_concurrency(); + } + /* Ensure that all defined constants work in the way we expect them. */ HandleLegacyDefines(); diff --git a/lib/base/configuration.cpp b/lib/base/configuration.cpp index 1be273faf..31ae60488 100644 --- a/lib/base/configuration.cpp +++ b/lib/base/configuration.cpp @@ -12,7 +12,7 @@ String Configuration::ApiBindHost; String Configuration::ApiBindPort{"5665"}; bool Configuration::AttachDebugger{false}; String Configuration::CacheDir; -int Configuration::Concurrency{static_cast(std::thread::hardware_concurrency())}; +int Configuration::Concurrency{1}; bool Configuration::ConcurrencyWasModified{false}; String Configuration::ConfigDir; String Configuration::DataDir; From 3fae41ef2291ffa6b71de2d5ce4503cf824a7c77 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 23 May 2023 14:41:35 +0200 Subject: [PATCH 6/6] Restart thread pool after freezing Configuration The user (-D) or we could have changed Configuration.Concurrency, so correct the thread pool's thread amount. --- icinga-app/icinga.cpp | 2 ++ lib/base/threadpool.cpp | 18 +++++++++++++++++- lib/base/threadpool.hpp | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index f5b6809bc..5674a9ff2 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -451,6 +451,8 @@ static int Main() Configuration::Concurrency = std::thread::hardware_concurrency(); } + Application::GetTP().Restart(); + /* Ensure that all defined constants work in the way we expect them. */ HandleLegacyDefines(); diff --git a/lib/base/threadpool.cpp b/lib/base/threadpool.cpp index 21f19fd42..dc76e7b15 100644 --- a/lib/base/threadpool.cpp +++ b/lib/base/threadpool.cpp @@ -20,10 +20,15 @@ void ThreadPool::Start() boost::unique_lock lock (m_Mutex); if (!m_Pool) { - m_Pool = decltype(m_Pool)(new boost::asio::thread_pool(Configuration::Concurrency * 2u)); + InitializePool(); } } +void ThreadPool::InitializePool() +{ + m_Pool = decltype(m_Pool)(new boost::asio::thread_pool(Configuration::Concurrency * 2u)); +} + void ThreadPool::Stop() { boost::unique_lock lock (m_Mutex); @@ -33,3 +38,14 @@ void ThreadPool::Stop() m_Pool = nullptr; } } + +void ThreadPool::Restart() +{ + boost::unique_lock lock (m_Mutex); + + if (m_Pool) { + m_Pool->join(); + } + + InitializePool(); +} diff --git a/lib/base/threadpool.hpp b/lib/base/threadpool.hpp index f9760bc8b..d30fa694c 100644 --- a/lib/base/threadpool.hpp +++ b/lib/base/threadpool.hpp @@ -42,6 +42,7 @@ public: void Start(); void Stop(); + void Restart(); /** * Appends a work item to the work queue. Work items will be processed in FIFO order. @@ -91,6 +92,8 @@ private: boost::shared_mutex m_Mutex; std::unique_ptr m_Pool; Atomic m_Pending; + + void InitializePool(); }; }