Skip to content

Commit acf6eca

Browse files
committed
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.
1 parent be200e2 commit acf6eca

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

llvm/lib/Support/Windows/Threading.inc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,38 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
107107
}
108108

109109
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
110+
111+
// SetThreadInformation is only available on Windows 8 and later. Since we still
112+
// support compilation on Windows 7, we load the function dynamically.
113+
typedef BOOL(WINAPI * SetThreadInformation_t)(
114+
HANDLE hThread, THREAD_INFORMATION_CLASS ThreadInformationClass,
115+
_In_reads_bytes_(ThreadInformationSize) PVOID ThreadInformation,
116+
ULONG ThreadInformationSize);
117+
static const auto pfnSetThreadInformation =
118+
(SetThreadInformation_t)GetProcAddress(
119+
GetModuleHandle(TEXT("kernel32.dll")), "SetThreadInformation");
120+
121+
if (pfnSetThreadInformation) {
122+
auto setThreadInformation = [](ULONG ControlMaskAndStateMask) {
123+
THREAD_POWER_THROTTLING_STATE state{};
124+
state.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION;
125+
state.ControlMask = ControlMask;
126+
state.StateMask = StateMask;
127+
return pfnSetThreadInformation(GetCurrentThread(), ThreadPowerThrottling,
128+
&state, sizeof(state));
129+
};
130+
131+
// Use EcoQoS for ThreadPriority::Background available (running on most
132+
// efficent cores at the most efficient cpu frequency):
133+
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadinformation
134+
// https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
135+
if (Priority == ThreadPriority::Background) {
136+
setThreadInformation(THREAD_POWER_THROTTLING_EXECUTION_SPEED);
137+
} else {
138+
setThreadInformation(0);
139+
}
140+
}
141+
110142
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
111143
// Begin background processing mode. The system lowers the resource scheduling
112144
// priorities of the thread so that it can perform background work without

0 commit comments

Comments
 (0)