I'm writing an audio device driver which needs to process device interrupts in real-time. When the CPU enters C3 state, interrupts are delayed, causing problems to the driver. Is there a way for the driver to tell the OS not to enter idle C-states?
What I've found is that idle C-states can be disabled from user-space:
const DWORD DISABLED = 1;
const DWORD ENABLED = 0;
GUID *scheme;
PowerGetActiveScheme(NULL, &scheme);
PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED);
PowerSetActiveScheme(NULL, scheme);
However, it is a global setting, which can be overwritten by the user or another application (e.g. when the user changes the Power Plan).
What I need is something like PoRegisterSystemState, but not for S- and P-states, but for C-states. (ref: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/preventing-system-power-state-changes)
Is there any way to achieve this?
=====
It turns out there isn't a supported way to disable idle C-states from kernel space, and there isn't a service in user space to provide common API to do this. The way to control C-states is from "Processor Power Management" in "Change advanced power settings" dialog, through registry, or via C API PowerWriteACValueIndex / PowerWriteDCValueIndex.
The original problem was delayed interrupts in all but C1 idle state, so I needed to disable both C2, C3 and deeper idle states. The problem with disabling all idle C-states, including C1 (as shown in the example code PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED)) is that the CPU usage is reported as 100%, and some applications (DAWs) get confused.
The solution for my problem is to disable all but C1 idle state, which can be done by setting the following values in the Processor Power Management: - Processor idle threshold scaling -> Disable scaling; - Processor idle promote threshold -> 100%; - Processor idle demote threshold -> 100%.
Perhaps I'll create a service that does just that, that will use the PowerWriteACValueIndex / PowerWriteDCValueIndex API.