QueryPerformanceCounter vs GetTickCount

Dear Toradex,

In past days we noticed the value retrieved from QueryPerformanceCounter() is weird. Once the device is restarted, it counts from 0, it is all right. After some time it can happen the returned value is much more bigger than expected. When I use the GetTickCount() function instead, the returned value seems to be all right all the time. I didn’t complete the testing yet so I can’t declare it is a bug, but I found the issue #9197 in your issue list. Unfortunatelly the issue is not described enough and is for OEMQueryPerformanceCounter() actually. Could you please help me and confirm the QueryPerformanceCounter() should be all right for Apalis T30, BSP 1.4, WinCE 7. Or maybe better, what should I double-check to get the returned value valid. The CPU runs on fixed 1GHz.

Thank you a lot

Best regards

Vlastimil

Dear @vpetrucha

QueryPerformanceCounter() stores the return value in a 64-bit union of type LARGE_INTEGER. Is it possible that you only look at the LowPart and don’t handle overflows properly? The overflow happens after 35min47sec, and then every 71min35sec again.

Can you please share the code you were using to reproduce the problem?

I had the following code running for more than an hour (on WEC7 V2.1b4), the performance counter pc_diff was always reported to be 1,000,000 ± 10, even with Dynamic Frequency Switching enabled. So I couldn’t find any issue.

// Measure performance counter once every second (timed by GetTickCount() )
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    LARGE_INTEGER   pc, prev_pc;
    int             pc_diff;
    DWORD           tick;
    DWORD           nextTick;
    BOOL            firstLoop = true;

    tick = GetTickCount();
    tick = tick - (tick %1000);
    nextTick = tick;
   
    for (;;)
    {
        nextTick += 1000;
        while ((tick = GetTickCount()) < nextTick)
        {}
        
        QueryPerformanceCounter(&pc);
        pc_diff = (int)(pc.QuadPart - prev_pc.QuadPart);
        prev_pc = pc;

        if (!firstLoop)
        {
            RETAILMSG(1, (L"%d\r\n", pc_diff));
            ASSERT((999000 < pc_diff) && (pc_diff < 1001000));
        }
        firstLoop = false;
    }
}

Regards, Andy

Hello Andy,

There was missing linker flag /subsystem:windowsce,7.00 in our project. It looks like the issue with QueryPerformanceCounter() dissapeared once the flag was added.

Regards

Vlastimil