From b748f0ad5f92c16163dadc82d0fe43ac4cc7fdfa Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Wed, 5 Aug 2026 23:50:41 -0400 Subject: [PATCH] [thread, adpf] Adjustments on current affinitty cascade falls --- src/common/adpf.cpp | 55 ++++++++++++++++++++++++++----------------- src/common/thread.cpp | 4 ++-- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/common/adpf.cpp b/src/common/adpf.cpp index bfcd0d311f..a627375dd3 100644 --- a/src/common/adpf.cpp +++ b/src/common/adpf.cpp @@ -119,30 +119,29 @@ void CloseLocked(SessionState& state) { } } -bool OpenLocked(Session session, SessionState& state) { +// Builds a session for the given thread list without touching any existing one, so a refusal +// costs nothing. +AHintSession* CreateSessionFor(Session session, const std::vector& threads) { const Api& api = Resolve(); const s64 target = session == Session::Render ? g_target_ns.load(std::memory_order_relaxed) : 0; std::vector ids; - ids.reserve(state.threads.size()); - for (const pid_t tid : state.threads) { + ids.reserve(threads.size()); + for (const pid_t tid : threads) { ids.push_back(static_cast(tid)); } - state.handle = api.create_session(api.manager, ids.data(), ids.size(), target); - if (state.handle == nullptr && target == 0) { - state.handle = - api.create_session(api.manager, ids.data(), ids.size(), DEFAULT_TARGET.count()); + AHintSession* handle = api.create_session(api.manager, ids.data(), ids.size(), target); + if (handle == nullptr && target == 0) { + handle = api.create_session(api.manager, ids.data(), ids.size(), DEFAULT_TARGET.count()); } - if (state.handle == nullptr) { - state.unsupported = true; - LOG_WARNING(Common, "Could not open a performance hint session, falling back"); - return false; + if (handle == nullptr) { + return nullptr; } - if (session == Session::Background) { - api.set_power_efficiency(state.handle, true); + if (session == Session::Background && api.set_power_efficiency != nullptr) { + api.set_power_efficiency(handle, true); } - return true; + return handle; } bool SyncLocked(Session session, SessionState& state) { @@ -150,19 +149,27 @@ bool SyncLocked(Session session, SessionState& state) { CloseLocked(state); return false; } - if (state.handle == nullptr) { - return OpenLocked(session, state); - } const Api& api = Resolve(); - if (api.set_threads != nullptr) { + if (state.handle != nullptr && api.set_threads != nullptr) { std::vector ids = state.threads; if (api.set_threads(state.handle, ids.data(), ids.size()) == 0) { return true; } } + + AHintSession* const replacement = CreateSessionFor(session, state.threads); + if (replacement == nullptr) { + if (state.handle == nullptr) { + state.unsupported = true; + } + LOG_WARNING(Common, "Could not open a performance hint session for {} threads, falling back", + state.threads.size()); + return false; + } CloseLocked(state); - return OpenLocked(session, state); + state.handle = replacement; + return true; } } // Anonymous namespace @@ -200,11 +207,17 @@ bool AddCurrentThread(Session session) { } SessionState& state = StateOf(session); - if (std::find(state.threads.begin(), state.threads.end(), tid) == state.threads.end()) { + const bool added = + std::find(state.threads.begin(), state.threads.end(), tid) == state.threads.end(); + if (added) { state.threads.push_back(tid); } if (!SyncLocked(session, state)) { - std::erase(state.threads, tid); + // The session in use survived the refusal and still holds the list without this thread, + // so only the addition has to be undone. + if (added) { + std::erase(state.threads, tid); + } return false; } return true; diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 89beaa96e3..383f033cf7 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -58,7 +58,7 @@ int LowestAllowedNice() { if (getrlimit(RLIMIT_NICE, &limit) != 0) { return 0; } - if (limit.rlim_cur == RLIM_INFINITY) { + if (limit.rlim_cur >= 40) { return -20; } return 20 - static_cast(limit.rlim_cur); @@ -77,7 +77,7 @@ int NiceValueForPriority(Common::ThreadPriority priority) { default: return NICE_DEFAULT; } }(); - return (std::max)(wanted, LowestAllowedNice()); + return (std::max)(wanted, (std::min)(NICE_DEFAULT, LowestAllowedNice())); } } // Anonymous namespace #endif