diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index f50450525..bd5042a0b 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -152,7 +152,7 @@ int Main(void) Application::DeclareZonesDir(Application::GetSysconfDir() + "/icinga2/zones.d"); Application::DeclareRunAsUser(ICINGA_USER); Application::DeclareRunAsGroup(ICINGA_GROUP); - Application::DeclareConcurrency(boost::thread::hardware_concurrency()); + Application::DeclareConcurrency(Utility::PhysicalConcurrency()); if (!ScriptGlobal::Exists("UseVfork")) #ifdef __APPLE__ diff --git a/lib/base/application.cpp b/lib/base/application.cpp index 36ea62365..106410642 100644 --- a/lib/base/application.cpp +++ b/lib/base/application.cpp @@ -1339,7 +1339,7 @@ void Application::DeclareConcurrency(int ncpus) */ int Application::GetConcurrency(void) { - Value defaultConcurrency = boost::thread::hardware_concurrency(); + static Value defaultConcurrency = Utility::PhysicalConcurrency(); return ScriptGlobal::Get("Concurrency", &defaultConcurrency); } diff --git a/lib/base/unix.hpp b/lib/base/unix.hpp index 9fe8b7d2e..ab9881aad 100644 --- a/lib/base/unix.hpp +++ b/lib/base/unix.hpp @@ -41,6 +41,7 @@ #include #include #include +#include typedef int SOCKET; #define INVALID_SOCKET (-1) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 82470822f..29c98e139 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -1936,3 +1936,69 @@ String Utility::GetIcingaDataPath(void) } #endif /* _WIN32 */ + +int Utility::PhysicalConcurrency(void) +{ +#if BOOST_VERSION >= 106100 + return boost::thread::physical_concurrency(); +#elif defined(__linux__) + std::ifstream fp("/proc/cpuinfo"); + std::string line; + bool htFlag = false; + + while (std::getline(fp, line)) { + std::vector tokens; + boost::algorithm::split(tokens, line, boost::is_any_of(":")); + + if (tokens.size() != 2) + continue; + + String key = tokens[0].Trim(); + String value = tokens[1].Trim(); + + if (key != "flags") + continue; + + std::vector flags; + boost::algorithm::split(flags, value, boost::is_any_of(" ")); + + if (std::find(flags.begin(), flags.end(), "ht") != flags.end()) { + htFlag = true; + break; + } + } + + return boost::thread::hardware_concurrency() / (htFlag ? 2 : 1); +#elif defined(_WIN32) + DWORD size = 0; + + GetLogicalProcessorInformation(NULL, &size); + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return boost::thread::hardware_concurrency(); + + std::vector info(size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); + + if (GetLogicalProcessorInformation(&info.front(), &size) == FALSE) + return boost::thread::hardware_concurrency(); + + int ncpus = 0; + + BOOST_FOREACH(const SYSTEM_LOGICAL_PROCESSOR_INFORMATION& slpi, info) { + if (slpi.Relationship == RelationProcessorCore) + ncpus++; + } + + return ncpus; +#elif defined(__APPLE__) + int ncpus; + size_t size = sizeof(ncpus); + + if (sysctlbyname("hw.physicalcpu", &ncpus, &size, NULL, 0) == 0) + return ncpus; + else + return boost::thread::hardware_concurrency(); +#else /* __APPLE__ */ + return boost::thread::hardware_concurrency(); +#endif /* __APPLE__ */ +} diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index 0e1fcc29f..36885292a 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -153,6 +153,8 @@ public: static void IncrementTime(double); #endif /* I2_DEBUG */ + static int PhysicalConcurrency(void); + private: Utility(void); static void CollectPaths(const String& path, std::vector& paths);