Performance Monitor Decoding Base Priority Counter [Windows 10]

So in perf mon I can attach a base priority counter to a process such as google chrome. This shows its priority as "8". If i look in task manager google chrome have "normal priority".

My question is, does any table exists that show that a 8 in perf mon is the same as normal priority?

EDIT: I just noticed the process idle have priority 0. But according to this

https://docs.microsoft.com/en-us/windows/desktop/procthread/scheduling-priorities

"Only the zero-page thread can have a priority of zero."

I'm so confused by this :<


Solution 1:

This table used to be fairly easy to find at microsoft.com and countless other places.

enter image description here

The "Base priority" column in Task Manager is showing you the process class (called "process priority class" in some docs). Note that Task Manager (at least in Windows 10) labels the "Idle" priority class as "Low" (probably to avoid confusion with the idle process, etc.).

The process class is used only to initialize the priority of threads created within the process. Every thread is created with the "normal" thread priority. If the process is of the "normal" process class, then that means the thread has a base priority of 8.

(Oddly, the CreateProcess API takes an argument for the process class, but CreateThread does not. To create a thread with other than the "normal" thread priority, you have to create the thread and then change its priority later with SetThreadPriority.)

Programs can change the priorities of their own threads within their process class. In a "normal" process, setting a thread to THREAD_PRIORITY_HIGHEST sets that thread's base priority to 10. If you change the priority class of a process (say with Task Manager) then every thread's base priority changes according to the table.

There are a lot of "name anomalies" in this table. "Highest" is not the highest thread priority, "lowest" is not the lowest, "idle" does not mean you are not or will not be doing anything, and "realtime" does not guarantee scheduling behavior suitable for real-time work (it's just more predictable than the non-realtime classes, partly because it's above them all, and partly because automatic priority adjustment is turned off in the "realtime" class).

For processes, one is supposed to use the process classes to indicate how important - or not - it is for each process to get CPU time, relative to a "normal" process. And within each process, the developer is supposed to set the thread priorities similarly, relative to a "normal" thread within the process. In practice, very few developers ever bother. (And they should. For example, a compute-bound task like video rendering should be set to a lower-than-normal priority, to avoid interfering with interactive use of the system.)

And the "idle" process class, and the "idle" thread priority within a process, does not mean nothing will be done by that process or that thread. It just means the thread or the process is willing to live with CPU cycles that nobody else wants.

You'll notice that there is no "0" on the table. Ordinary applications cannot request running at priority 0 through the normal APIs. Only kernel mode threads can run at priority zero. As you've found, that is reserved for the zero page thread - or threads; there may be more than one on a NUMA machine.

Regarding the idle process - it and its threads are special cases. Every thread object has a "priority" member, and for the idle threads these are set to 0. However the idle threads' priority members are never actually used for anything, and there is no ready queue for the idle threads. Instead, if the OS scheduler can't find any other thread to run on an available CPU, it simply picks the idle thread for that CPU. (Every CPU has its own dedicated idle thread.) So although it seems to have priority 0, it's scheduled as if it had priority negative 1. Even a priority 0 thread will take precedence over the idle thread.

The term "idle" has at least one other common meaning in Windows. A process can "register for idle detection". "Idle" in this case means there has been no user input (keyboard or mouse) and no more than 10% usage of any CPU or any disk in the last fifteen minutes. Windows can initiate various "housekeeping" or "cleanup" tasks, such as file placement optimization, when this sort of "idle" is detected. The code that runs in response to these does not necessarily run in the idle process class or at idle thread priority. You may have seen a little command-line method to request running of "idle tasks":

C:\> Rundll32.exe advapi32.dll,ProcessIdleTasks

and this is what that's referring to. It has nothing to do with the idle process or with the so-called "idle" process or thread priority.

I wrote an answer with more detail about how the scheduler uses thread priorities to make its selections here.

Reference: https://docs.google.com/viewer?url=https%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F1%2F4%2F0%2F14045a9e-c978-47d1-954b-92b9fd877995%2F97807356648739_samplechapters.pdf This is a set of excerpts from Windows Internals 6th Ed. by Solomon, Russinovich, et al. The material you want begins on page 62 of the PDF, actual book page number 408.