Why does QueryPerformanceCounter/QueryPerformanceFrequency fail?

Ian Boyd

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.

Ian Boyd

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.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related