From ab8d1c02d47e4f20d170ebde6d02994566a1357b Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 1 Mar 2021 23:07:25 +0100 Subject: [PATCH] Set idle priority for navmesh generation thread Support Linux, Windows, FreeBSD. --- components/CMakeLists.txt | 2 +- .../detournavigator/asyncnavmeshupdater.cpp | 2 + components/misc/thread.cpp | 73 +++++++++++++++++++ components/misc/thread.hpp | 11 +++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 components/misc/thread.cpp create mode 100644 components/misc/thread.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 822858c0b..ad2783b57 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -87,7 +87,7 @@ add_component_dir (esmterrain ) add_component_dir (misc - constants utf8stream stringops resourcehelpers rng messageformatparser weakcache + constants utf8stream stringops resourcehelpers rng messageformatparser weakcache thread ) add_component_dir (debug diff --git a/components/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 1ac928f07..bb78df764 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -4,6 +4,7 @@ #include "settings.hpp" #include +#include #include @@ -135,6 +136,7 @@ namespace DetourNavigator void AsyncNavMeshUpdater::process() noexcept { Log(Debug::Debug) << "Start process navigator jobs by thread=" << std::this_thread::get_id(); + Misc::setCurrentThreadIdlePriority(); while (!mShouldStop) { try diff --git a/components/misc/thread.cpp b/components/misc/thread.cpp new file mode 100644 index 000000000..8101779bc --- /dev/null +++ b/components/misc/thread.cpp @@ -0,0 +1,73 @@ +#include "thread.hpp" + +#include + +#include +#include + +#ifdef __linux__ + +#include +#include + +namespace Misc +{ + void setCurrentThreadIdlePriority() + { + sched_param param; + param.sched_priority = 0; + if (pthread_setschedparam(pthread_self(), SCHED_IDLE, ¶m) == 0) + Log(Debug::Verbose) << "Using idle priority for thread=" << std::this_thread::get_id(); + else + Log(Debug::Warning) << "Failed to set idle priority for thread=" << std::this_thread::get_id() << ": " << std::strerror(errno); + } +} + +#elif defined(WIN32) + +#undef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN + +#include + +namespace Misc +{ + void setCurrentThreadIdlePriority() + { + if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST)) + Log(Debug::Verbose) << "Using idle priority for thread=" << std::this_thread::get_id(); + else + Log(Debug::Warning) << "Failed to set idle priority for thread=" << std::this_thread::get_id() << ": " << GetLastError(); + } +} + +#elif defined(__FreeBSD__) + +#include +#include + +namespace Misc +{ + void setCurrentThreadIdlePriority() + { + rtprio prio; + prio.type = RTP_PRIO_IDLE; + prio.prio = RTP_PRIO_MAX; + if (rtprio_thread(RTP_SET, 0, &prio) == 0) + Log(Debug::Verbose) << "Using idle priority for thread=" << std::this_thread::get_id(); + else + Log(Debug::Warning) << "Failed to set idle priority for thread=" << std::this_thread::get_id() << ": " << std::strerror(errno); + } +} + +#else + +namespace Misc +{ + void setCurrentThreadIdlePriority() + { + Log(Debug::Warning) << "Idle thread priority is not supported on this system"; + } +} + +#endif diff --git a/components/misc/thread.hpp b/components/misc/thread.hpp new file mode 100644 index 000000000..191c43bba --- /dev/null +++ b/components/misc/thread.hpp @@ -0,0 +1,11 @@ +#ifndef OPENMW_COMPONENTS_MISC_THREAD_H +#define OPENMW_COMPONENTS_MISC_THREAD_H + +#include + +namespace Misc +{ + void setCurrentThreadIdlePriority(); +} + +#endif