Multiprocessor TimerQueueTimer precision question

G

Gavin Stark

On a single processor machine I can get a callback at very
close to a requested 100ms timer. However, when I run the
same code on a MULTI processor (or even MP capable) system
I get anywhere from 94ms to 154ms results. In the
application I have we are using a very precise IRIG/GPS
timing card to read the "current" time so we know that we
are truly seeing these variances. (the sample code I post
below is using the built in clock -- its just for test
purposes and produces nearly the same results)

I know there is a 10/15ms limit on timers (10ms for SP and
15ms for MP) depending on the HAL/hardware. However I did
not expect a 100ms request to be so "off" on a MP machine.
I need to get a 10Hz "callback" but this is sometimes as
low as 6Hz (150ms)

HELP!

The code below represnets a "boiling down" of the code I am
really having problems with. I know the code below has
"other" problems but it simply demonstrates the core
problem I'd like some help with.

Thank you,
Gavin Stark
P.S. To e-mail direct remove the underscores in my posted
email and reverse the username portion.

<-- begin code -->

#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "memory.h"
#include "windows.h"
#include "time.h"

typedef BOOL ( CALLBACK CreateTimerQueueTimerProc ) (
PHANDLE, HANDLE, WAITORTIMERCALLBACKFUNC, PVOID, DWORD,
DWORD, ULONG );
typedef BOOL ( CALLBACK DeleteTimerQueueTimerProc ) (
HANDLE, HANDLE, HANDLE );


VOID CALLBACK Win32TimerQueueProc(PVOID lpParameter,
BOOLEAN TimerOrWaitFired)
{
SYSTEMTIME myWin32SystemTime;

// get the system time
::GetSystemTime(&myWin32SystemTime);

ULONG currentMilliseconds = myWin32SystemTime.wSecond *
1000 + myWin32SystemTime.wMilliseconds;

SYSTEMTIME* myLastWin32SystemTime = (SYSTEMTIME*)lpParameter;

ULONG lastMilliseconds = myLastWin32SystemTime->wSecond *
1000 + myLastWin32SystemTime->wMilliseconds;
::printf("%d\n", currentMilliseconds - lastMilliseconds );

*myLastWin32SystemTime = myWin32SystemTime;
}


int main( int argc, char** argv)
{
HMODULE hKernel32 = ::LoadLibrary("kernel32.dll");

CreateTimerQueueTimerProc* pCreateTimerQueueTimerProc =
(CreateTimerQueueTimerProc*) ::GetProcAddress( hKernel32,
"CreateTimerQueueTimer" );

if( !pCreateTimerQueueTimerProc )
{
::printf( "timer code will not function - system must be
W2K or later" );
return 1;
}

DWORD timeDelta = 100;

SYSTEMTIME myLastWin32SystemTime;

HANDLE myTimer;
(*pCreateTimerQueueTimerProc)( &myTimer,
NULL,
Win32TimerQueueProc,
&myLastWin32SystemTime,
timeDelta,
timeDelta,
0 );

::Sleep(50000);

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top