Posted by: Sue Loh

No, no, no, before you even say it, I'm not writing this in response to any of Jack Crenshaw's columns.  Actually this time it's more to augment them.  You see his columns do make one very true point (more than one, but only one I'm commenting on here):  People who call GetTickCount, such a trivial function at first glance, sometimes use it wrong.  Because it's not quite as trivial as people take it for.

And actually for this post I owe the content to Sergio Cherskov, who is also on the Windows CE team.  It seems Sergio is a bit of a guardian angel, and keeps an eye out for improper usages of this API within our team.  Separately we've been discussing how to do this in a more automated fashion, but that's not trivial either.  Anyway Sergio wanted to share some tips for using GetTickCount.  He's also working to get this called out more explicitly in our documentation.  The remainder of this post is his:

Can you please follow-up with another blog “addition” for GetTickCount() and truly explain the way we want EVERYONE (including our internal developers) to use this function.

Basically, the subtraction ALWAYS works, even if the rollover occurred, and ALWAYS gives the correct difference and number of clock ticks passed between two tick values.  The return value is unsigned integer (DWORD) and that’s what gives it that nice property.  What does NOT work is COMPARING tick values directly – one should always compare ONLY the differences.  If developer sticks with comparing differences and is able to service difference before second rollover (i.e. before another 49.7 days come up), everything should be fine.

Sooo, here’s the code that ALWAYS works, even in the presence of the rollover (subtraction math still works, i.e. 0 – (-1) = 0 + 1 = 1 which in unsigned math amounts to pretty much the same thing: 0x000000 – 0xffffffff = 1.)

#define         DELTA_TICKS    some_value_here

// initialized somewhere in the code
DWORD           dwStartTick = GetTickCount();
DWORD          dwEndTick = GetTickCount() + DELTA_TICKS;


// fails at rollover (note, this was Sue’s sample)
BOOL    bad_fn_comparing_direct_tick_values()
{
        if ( GetTickCount() > dwEndTick )
                return ( TRUE);
        return (FALSE);
}


// ALWAYS works (we need a sample code like this evangelized to everyone)
BOOL good_fn_compares_tick_differences()
{
        if ( (GetTickCount() – dwStartTick) > DELTA_TICKS)
                return ( TRUE);
        return (FALSE);
}