From 5c586bf7478b7041dda53bfb921f4bdd514f1cf5 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Tue, 15 Jul 2025 15:32:15 +0800 Subject: [PATCH] Windows: use EcoQoS for ThreadPriority::Background The SetThreadInformation API allows threads to be scheduled on the most efficient cores on the most efficient frequency. Using this API for ThreadPriority::Background should make clangd-based IDEs a little less CPU hungry. --- llvm/lib/Support/Windows/Threading.inc | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/llvm/lib/Support/Windows/Threading.inc b/llvm/lib/Support/Windows/Threading.inc index d862dbd7f71c9..571e0960a6888 100644 --- a/llvm/lib/Support/Windows/Threading.inc +++ b/llvm/lib/Support/Windows/Threading.inc @@ -107,6 +107,35 @@ void llvm::get_thread_name(SmallVectorImpl &Name) { } SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) { + + // SetThreadInformation is only available on Windows 8 and later. Since we still + // support compilation on Windows 7, we load the function dynamically. + typedef BOOL(WINAPI * SetThreadInformation_t)( + HANDLE hThread, THREAD_INFORMATION_CLASS ThreadInformationClass, + _In_reads_bytes_(ThreadInformationSize) PVOID ThreadInformation, + ULONG ThreadInformationSize); + static const auto pfnSetThreadInformation = + (SetThreadInformation_t)GetProcAddress( + GetModuleHandle(TEXT("kernel32.dll")), "SetThreadInformation"); + + if (pfnSetThreadInformation) { + auto setThreadInformation = [](ULONG ControlMaskAndStateMask) { + THREAD_POWER_THROTTLING_STATE state{}; + state.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION; + state.ControlMask = ControlMaskAndStateMask; + state.StateMask = ControlMaskAndStateMask; + return pfnSetThreadInformation(GetCurrentThread(), ThreadPowerThrottling, + &state, sizeof(state)); + }; + + // Use EcoQoS for ThreadPriority::Background available (running on most + // efficent cores at the most efficient cpu frequency): + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadinformation + // https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service + setThreadInformation(Priority == ThreadPriority::Background ? THREAD_POWER_THROTTLING_EXECUTION_SPEED + : 0); + } + // https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority // Begin background processing mode. The system lowers the resource scheduling // priorities of the thread so that it can perform background work without