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;
:rintf("%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 )
{
:rintf( "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;
}
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;
:rintf("%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 )
{
:rintf( "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;
}