CreateTimerQueue() - questions about how it works? [modified]
-
I have a thread going on a little way down, about threads and timing. Now a question came up that I felt should go into a different thread. I have the following code piece
HANDLE hTimerQueue = CreateTimerQueue();
HANDLE hTimer;
count = 0;
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)&DoSendHere, 0 , 20, 0, WT_EXECUTEINTIMERTHREAD);QueryPerformanceCounter(&liStart);
::SleepEx(60, TRUE);
//DeleteTimerQueueTimer( hTimerQueue, hTimer, NULL );
LONG lCount = count;
QueryPerformanceFrequency(&liFreq);m_pLogger->Out( Logger::DEBUG, "RTPEngine: Time = %f.\n", double(liEnd.QuadPart-liStart.QuadPart) / double(liFreq.QuadPart) );
m_pLogger->Out( Logger::DEBUG, "RTPEngine: Count = %d.\n", lCount );
//DeleteTimerQueueTimer( hTimerQueue, hTimer, NULL );The liEnd variable is filled in the callback function. Several issues: 1. Like it is the callback func is called once (like intended) but the output gives a time of appx. 30ms, not 20ms. Actually the time is never the time I set up. 2. Why does it crash if I call DeleteTimerQueueTimer( hTimerQueue, hTimer, NULL ); after the output? The output is this
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.030410.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.030192.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.030377.
RTPEngine: Count = 1.This is the output for a 9ms dueTime:
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.016252.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.014759.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.014178.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.014759.
RTPEngine: Count = 1.Souldrift
modified on Monday, July 6, 2009 5:53 AM
-
I have a thread going on a little way down, about threads and timing. Now a question came up that I felt should go into a different thread. I have the following code piece
HANDLE hTimerQueue = CreateTimerQueue();
HANDLE hTimer;
count = 0;
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)&DoSendHere, 0 , 20, 0, WT_EXECUTEINTIMERTHREAD);QueryPerformanceCounter(&liStart);
::SleepEx(60, TRUE);
//DeleteTimerQueueTimer( hTimerQueue, hTimer, NULL );
LONG lCount = count;
QueryPerformanceFrequency(&liFreq);m_pLogger->Out( Logger::DEBUG, "RTPEngine: Time = %f.\n", double(liEnd.QuadPart-liStart.QuadPart) / double(liFreq.QuadPart) );
m_pLogger->Out( Logger::DEBUG, "RTPEngine: Count = %d.\n", lCount );
//DeleteTimerQueueTimer( hTimerQueue, hTimer, NULL );The liEnd variable is filled in the callback function. Several issues: 1. Like it is the callback func is called once (like intended) but the output gives a time of appx. 30ms, not 20ms. Actually the time is never the time I set up. 2. Why does it crash if I call DeleteTimerQueueTimer( hTimerQueue, hTimer, NULL ); after the output? The output is this
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.030410.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.030192.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.030377.
RTPEngine: Count = 1.This is the output for a 9ms dueTime:
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.016252.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.014759.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.014178.
RTPEngine: Count = 1.
RTPEngine: Sending data package with size 480 (excluding header).
RTPEngine: Timer callback activated.
RTPEngine: Time = 0.014759.
RTPEngine: Count = 1.Souldrift
modified on Monday, July 6, 2009 5:53 AM
I can't reproduce your results - I always see the timer triggering roughly (within around 2-300 microseconds) when expected. Note that in my initial post about timer queue timers I posted the wrong callback function signature - that could have caused crashes, as there was an extra formal parameter - sorry about that. You may find it useful to investigate the different values in the Flags parameter of CreateTimerQueueTimer - the callback doesn't have to execute in the same thread as the timer.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
I can't reproduce your results - I always see the timer triggering roughly (within around 2-300 microseconds) when expected. Note that in my initial post about timer queue timers I posted the wrong callback function signature - that could have caused crashes, as there was an extra formal parameter - sorry about that. You may find it useful to investigate the different values in the Flags parameter of CreateTimerQueueTimer - the callback doesn't have to execute in the same thread as the timer.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Well, I made a small adaption to your code like this (some output and another timing behaviour)
#include #include #include LONG count;
LARGE_INTEGER liStart, liEnd, liFreq;VOID CALLBACK DoSendHere(__in_opt LPVOID lpArgToCompletionRoutine,
__in DWORD dwTimerLowValue,
__in DWORD dwTimerHighValue)
{
QueryPerformanceCounter(&liEnd);count++;
std::cout << "Time = " << double(liEnd.QuadPart-liStart.QuadPart) / double(liFreq.QuadPart) << std::endl;
}void SendLoop()
{
HANDLE hTimerQueue = CreateTimerQueue();
HANDLE hTimer;
count = 0;
QueryPerformanceFrequency(&liFreq);
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)&DoSendHere, 0 , 0, 9, WT_EXECUTEINTIMERTHREAD);
QueryPerformanceCounter(&liStart);::SleepEx(65, TRUE);
LONG lCount = count;
DeleteTimerQueueTimer(hTimerQueue, hTimer, 0);
std::cout << "Time = " << double(liEnd.QuadPart-liStart.QuadPart) / double(liFreq.QuadPart) << std::endl;
std::cout << "count = " << lCount << std::endl;
}int _tmain(int argc, _TCHAR* argv[])
{
SendLoop();
getchar();
return 0;
}The result shows the same 15ms jumps I had before. Maybe there´s just no way around. I guess, I think some more and then we might have to settle for a different approach. Thanks once again for ideas and brainstorming. Souldrift