The author, Mark Russinovich, of the aforementioned book has graciously made the utility ClockRes available on his web site. Running this utility, I was able to determine that the clock interval on my x86 multiprocessor PC is 15.625000 ms. Interesting, but my curious mind wants to know more.
Even more graciously, Mark has made the source code for ClockRes available. The function used in ClockRes to determine the tick interval is GetSystemTimeAdjustment. This function serves two purposes:
1) provide information about how and if the system periodically adjusts the time-of-day clock and
2) provide the interval between two successive system clock interrupts (i.e. the tick interval). Actually, the second purpose is really part of the first, but from my driven perspective, it’s the primary purpose of this function.
Armed with this information, I can start to connect a few dots without inflicting too much cerebral pain. Specifically, it explains why the return value from API function GetSystemTimeAsFileTime doesn’t update as frequently as one might expect. Given that the return value has a resolution of 100-nanoseconds, one might think that this function would provide a nifty high resolution timer. But, no, its system time and system time is only updated at the rate of the tick interval. And, to connect the dots, the tick interval is the value returned by function GetSystemTimeAdjustment.
Of course the real reason why the tick interval is important is that it affects thread scheduling. The Windows scheduler gives each thread a “quantum” of time to execute before allowing another task, at the same priority level, to run. The quantum that the scheduler assigns to a thread is a multiple of the tick interval. The specific quantum value chosen for a specific thread is bit beyond where I want to go with this article.
For now, let’s just examine the default quantum value for a foreground thread in XPe. In this case the Windows scheduler assigns a quantum of 18 or 6 tick intervals (Yes, to convert quantum to tick intervals, one must divide by 3. I could throw in a gratuitous comment about obfuscation here, but the reason for the multiple is to allow the scheduler the ability to “charge” a thread for doing an operation which causes it to suspend.) This means that on my PC, a foreground thread is allowed to hog the processor for about 94 milliseconds before another task of the same priority level is given a chance.
For some applications, one might want to be able to change the quantum setting. Fortunately, within limitations, one can. However, I’ll need to take this subject on in my next blog as this is a lengthy subject all on its own.