Why does QueryPerformanceCounter/QueryPerformanceFrequency fail?

performancecounter, windows

Solution

Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?

This won't occur on any system that runs Windows XP or later.

That is correct, perhaps with the slight change in phrasing:

This can occur on any system that runs Windows XP or later.

There are circumstances where `QueryPerformanceFrequency` returns false. You can Google for people experiencing the problem.

i had the problem today (on Windows 7):

Int64 freq;
//...
QueryPerformanceFrequency(@freq);

The function call fails (returns false), and `GetLastError` returns:

ERROR_NOACCESS
   998 (0x3E6)
   Invalid access to memory location.

Alignment Matters

The issue happens if your `Int64` memory address is not double-word (4-byte) aligned. For example, if you use a compiler that defaults to `Byte` or `Word` alignment for objects, or structures, or class member variables. In this case, `QueryPerformanceCounter` will return false.

Note: It's entirely possible that `QueryPerformanceCounter` only happens to work with double-word (4-byte) alignment, and might actually require quad-word (8-byte) alignment. The Windows x64 calling convention documentation is silent on the subject.

It is also possible that the CPU hardware is silently fixing up 4-byte alignment to 8-byte alignment, where it won't do the same for 1, 2, 3, 5, 6, or 7 byte alignment. It is also possible that this new drive system, if operable, could render the Red October undetectable to our SOSUS warning nets in the Atlantic.

tl;dr

Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?

The function can fail with error code `ERROR_NOACCESS` (Invalid access to memory location) if the variable to not double-word (8-byte) aligned.

Bonus Chatter

The documentation:

Return value

If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. On systems that run Windows XP or later, the function will always succeed and will thus never return zero.

Problem

There is an article on MSDN talking about `QueryPerformanceCounter`: Acquiring high-resolution time stamps Towards the bottom is an FAQ section with an interesting question: Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero? This won't occur on any system that runs Windows XP or later. That answer is correct, except that it is wrong. There are circumstances where QueryPerformanceFrequency will return `false`. I will be self answering this.

Original source