diff options
-rw-r--r-- | xbmc/platform/linux/threads/ThreadImplLinux.cpp | 90 | ||||
-rw-r--r-- | xbmc/platform/linux/threads/ThreadImplLinux.h | 1 |
2 files changed, 13 insertions, 78 deletions
diff --git a/xbmc/platform/linux/threads/ThreadImplLinux.cpp b/xbmc/platform/linux/threads/ThreadImplLinux.cpp index f4810cfe5c..8c7edbb591 100644 --- a/xbmc/platform/linux/threads/ThreadImplLinux.cpp +++ b/xbmc/platform/linux/threads/ThreadImplLinux.cpp @@ -13,7 +13,7 @@ #include <algorithm> #include <array> -#include <limits.h> +#include <mutex> #include <sys/resource.h> #include <unistd.h> @@ -61,57 +61,11 @@ static pid_t gettid() #endif #endif -} // namespace - -static int s_maxPriority; -static bool s_maxPriorityIsSet{false}; - -// We need to return what the best number than can be passed -// to SetPriority is. It will basically be relative to the -// the main thread's nice level, inverted (since "higher" priority -// nice levels are actually lower numbers). -static int GetUserMaxPriority(int maxPriority) -{ - if (s_maxPriorityIsSet) - return s_maxPriority; +std::once_flag flag; - // if we're root, then we can do anything. So we'll allow - // max priority. - if (geteuid() == 0) - return maxPriority; +} // namespace - // get user max prio - struct rlimit limit; - if (getrlimit(RLIMIT_NICE, &limit) != 0) - { - // If we fail getting the limit for nice we just assume we can't raise the priority - return 0; - } - - const int appNice = getpriority(PRIO_PROCESS, getpid()); - const int rlimVal = limit.rlim_cur; - - // according to the docs, limit.rlim_cur shouldn't be zero, yet, here we are. - // if a user has no entry in limits.conf rlim_cur is zero. In this case the best - // nice value we can hope to achieve is '0' as a regular user - const int userBestNiceValue = (rlimVal == 0) ? 0 : (20 - rlimVal); - - // running the app with nice -n 10 -> - // e.g. +10 10 - 0 // default non-root user. - // e.g. +30 10 - -20 // if root with rlimits set. - // running the app default -> - // e.g. 0 0 - 0 // default non-root user. - // e.g. +20 0 - -20 // if root with rlimits set. - const int bestUserSetPriority = appNice - userBestNiceValue; // nice is inverted from prio. - - // static because we only need to check this once. - // we shouldn't expect a user to change RLIMIT_NICE while running - // and it won't work anyway for threads that already set their priority. - s_maxPriority = std::min(maxPriority, bestUserSetPriority); - s_maxPriorityIsSet = true; - - return s_maxPriority; -} +static int s_appPriority = getpriority(PRIO_PROCESS, getpid()); std::unique_ptr<IThreadImpl> IThreadImpl::CreateThreadImpl(std::thread::native_handle_type handle) { @@ -129,43 +83,23 @@ void CThreadImplLinux::SetThreadInfo(const std::string& name) pthread_setname_np(m_handle, name.c_str()); #endif - // get user max prio - const int maxPrio = ThreadPriorityToNativePriority(ThreadPriority::HIGHEST); - const int userMaxPrio = GetUserMaxPriority(maxPrio); - - // if the user does not have an entry in limits.conf the following - // call will fail - if (userMaxPrio > 0) - { - // start thread with nice level of application - const int appNice = getpriority(PRIO_PROCESS, getpid()); - if (setpriority(PRIO_PROCESS, m_threadID, appNice) != 0) - CLog::Log(LOGERROR, "[threads] failed to set priority: {}", strerror(errno)); - } + m_name = name; } bool CThreadImplLinux::SetPriority(const ThreadPriority& priority) { - // keep priority in bounds + std::call_once(flag, + []() { CLog::Log(LOGDEBUG, "[threads] app priority: '{}'", s_appPriority); }); + const int prio = ThreadPriorityToNativePriority(priority); - const int maxPrio = ThreadPriorityToNativePriority(ThreadPriority::HIGHEST); - const int minPrio = ThreadPriorityToNativePriority(ThreadPriority::LOWEST); - // get user max prio given max prio (will take the min) - const int userMaxPrio = GetUserMaxPriority(maxPrio); + const int newPriority = s_appPriority - prio; - // clamp to min and max priorities - const int adjustedPrio = std::clamp(prio, minPrio, userMaxPrio); + setpriority(PRIO_PROCESS, m_threadID, newPriority); - // nice level of application - const int appNice = getpriority(PRIO_PROCESS, getpid()); - const int newNice = appNice - adjustedPrio; + const int actualPriority = getpriority(PRIO_PROCESS, m_threadID); - if (setpriority(PRIO_PROCESS, m_threadID, newNice) != 0) - { - CLog::Log(LOGERROR, "[threads] failed to set priority: {}", strerror(errno)); - return false; - } + CLog::Log(LOGDEBUG, "[threads] name: '{}' priority: '{}'", m_name, actualPriority); return true; } diff --git a/xbmc/platform/linux/threads/ThreadImplLinux.h b/xbmc/platform/linux/threads/ThreadImplLinux.h index 986ffe5ef3..2307b3f5cb 100644 --- a/xbmc/platform/linux/threads/ThreadImplLinux.h +++ b/xbmc/platform/linux/threads/ThreadImplLinux.h @@ -23,4 +23,5 @@ public: private: pid_t m_threadID; + std::string m_name; }; |