The problem you asked most directly: if (t.QuadPart < time_.QuadPart) should be as follows: if (t.QuadPart - time_.QuadPart < 0)
The reason for this is that you want to search for packaging in relative time, not absolute time. Relative time will wrap time units (1ull <63) after the call to QPC. Absolute time can be completed (1ull <63) units of time after a reboot, but it can turn around at any other time when it looked like it was undefined.
QPC is slightly distorted on some systems (for example, earlier RDTSC-based QPCs on early multi-core processors), so it might be advisable to allow small negative deltas like this: if (t.QuadPart - time_.QuadPart < -1000000) // time binding
The actual wrapper will create very large negative time deltas so that it is safe. This is not necessary for modern systems, but a reliable microsoft is rarely a good idea.
... However, the big problem there with timing is that ticks_to_wait , ticks_passed and ticks_left are int, not LARGE_INT or as long as they should be. This makes the most of this code wrapping if any significant time periods are involved - and “significant” in this context depends on the platform, it can be on the order of 1 second in several cases (rarely these days) or even less on some hypothetical system of the future.
Other problems:
if (time_.QuadPart != 0)
Zero is not a special meaning and should not be construed as such. I assume the code combines QPCs by returning a time with zero return QPCs equal to zero. The return value is not a 64-bit time passed by the pointer, it is a BOOL that QPC actually returns.
Also, this Sleep (0) loop is stupid - it seems to be configured to behave correctly only at a certain level of rivalry and a specific processor performance on threads. If you need permission, which is a terrible idea, and if you don't need resolution, then this whole function should have been the only challenge to sleep.
source share