Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when GetTickCount() wraps?

If a thread is doing something like this:

const DWORD interval = 20000;
DWORD ticks = GetTickCount();
while(true)
{
    DoTasksThatTakeVariableTime();

    if( GetTickCount() - ticks > interval )
    {
        DoIntervalTasks();
        ticks = GetTickCount();
    }
}

Eventually, ticks is going to wrap when the value doesn't fit in a DWORD.

I've been discussing this with a colleague. One of us believes the code will still behave 'nicely' when the wrap occurs, because the subtraction operation will also wrap. The other of us, believes it won't always work, especially if the interval is large.

Who's right, and why?

Thanks.

like image 320
Scott Langham Avatar asked Apr 07 '09 22:04

Scott Langham


1 Answers

From the docs:

The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days. To avoid this problem, use GetTickCount64. Otherwise, check for an overflow condition when comparing times.

However, DWORD is unsigned - so you should be okay. 0 - "very big number" = "small number" (assuming you don't have any overflow checking active, of course). I had a previous edit which suggested you'd get a negative number, but that was before I took into account that DWORD is unsigned.

You'll still have a problem if the operation takes just under 49.7 days though. That may not be an issue for you ;)

One way to test would be to stub out the GetTickCount() method so you could write unit tests where you explicitly make it wrap. Then again, if you're really only doubting the arithmetic part, you can easily write unit tests for that :) Really, the fact that the number is coming from a system clock is pretty much irrelevant so long as you know the behaviour when it wraps - and that's specified in the documentation.

like image 166
Jon Skeet Avatar answered Sep 20 '22 15:09

Jon Skeet