Timer Callbacks Win32

tatteredpotato

Diamond Member
Jul 23, 2006
3,934
0
76
I'm working on a project that needs to keep track of time between certain events. There are two timers, timer 'A' is set for 1.5*x, while timer 'B' is set for 3.5*x, and 'x' is some constant (these values end up around 1ms and 2ms).

Timer 'B' is a timer that frames rs232 serial messages, while timer 'A' is used to determine errors. Example: the application is in a waiting state (either initialized or timer 'B' has already tripped at some point in the past). The first byte to come over rs232 represents the first byte of the message. Subsequent bytes are considered to be part of that same message until timer 'B' runs out again. This means that every time a byte is received, these timers need to be reset. If timer 'A' times out, then the message is invalid unless no more bytes are received before timer 'B' times out.

So basically I need something high precision (1-2ms +- 1ms), resettable, and able to call a callback when timed out. I've read on the multitude of different Win32 timers and am a bit lost as to which ones to use in this scenario.
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
Ok, the problem you'll have with ANY windows timer is that the maximum resolution for them is ~1-15ms (depending on the operating system). If you want to be sure that some task is running every 1 ms, your best bet would be to spawn a new thread, and have that thread spawn the callback function every 1ms using a QueryPerformanceCounter for your timing.

However, your problems are going to be deeper then that. Unfortunately, when a windows task switches (especially for xp and below) there is a delay that can be as long as 15ms (and usually task switching happens around 15ms intervals in windows). This can be overcome by programming at the driver level, however, at the application level it is simply impossible to avoid.

IIRC, standard r232 ports have a cache for just this type of problem (Right? You'll probably know more about this then me). So I would suggest relying on that over precision timing.
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
Oh, and don't let the windows API fool you. Some of their timers will have measurement devices that go into the nanoseconds. However, they are using the kernel to do all the callbacky stuff, and that fires at, you guessed it, task switching. So in otherwords those callback functions only activate at task switching.

If you are using WaitForSingle object and its ilk, essentially what it is doing is letting the kernel know "Hey, this thread isn't busy" so control is taken from the application until the timer runs out. Because control is gone, your are at the mercy of the windows task switcher for when control returns.
 

tatteredpotato

Diamond Member
Jul 23, 2006
3,934
0
76
Thanks Cogman, I'm really writing this code for an embedded system that will have hardware timers and interrupts to do this task, but I'm doing the most of the development and debugging on windows, so 15ms is probably good enough for now.

Should I look at the SetTimer function or Timer Queues? Timer Queues seem to be the preferred option right now, but I was having issues getting my complier to find them (undefined function error even though windows.h was inc'd) (Windows XP SP3 for the record).
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
Thanks Cogman, I'm really writing this code for an embedded system that will have hardware timers and interrupts to do this task, but I'm doing the most of the development and debugging on windows, so 15ms is probably good enough for now.

Should I look at the SetTimer function or Timer Queues? Timer Queues seem to be the preferred option right now, but I was having issues getting my complier to find them (undefined function error even though windows.h was inc'd) (Windows XP SP3 for the record).

The problem you are having with the timer cues might be that you need to link to the external library kernel32.lib (maybe.. That is usually linked by default).

I've only ever used the setTimer functions. Though, AFAIK there really isn't an issue of using some other timing function. Use whichever has the more natural syntax for you.
 

tatteredpotato

Diamond Member
Jul 23, 2006
3,934
0
76
The problem you are having with the timer cues might be that you need to link to the external library kernel32.lib (maybe.. That is usually linked by default).

I'm using MinGW/Netbeans, but the error seemed more like a complier error as opposed to a linker error, but I really didn't look too far into it. I'll probably just stick with SetTimer.

Can you "reset" or clear/delete those timers btw?
EDIT: nevermind, found KillTimer
 
Last edited:

Cogman

Lifer
Sep 19, 2000
10,284
138
106
I don't know if the multimedia timer API is still supported, or really what the status of it is. They used to offer higher resolution and accuracy over the setTimer method because that was required for some sound and video operations. They may still suffer from the issues Cogman outlined.

http://msdn.microsoft.com/en-us/library/dd743612(VS.85).aspx

Well, it depends. The multimedia timer functions a little differently then the other windows timers. Rather then using the "waitforsingleobject" functions, the event timer will fire off a message to the window that created it (with all the relevant info.)

Now, if you use "GetMessage" to get your messages, I can guarentee it will have the same issues, the reason for that is that GetMessage yeilds the current thread it is run on until a message arrives at the message queue.

PeakMessage MIGHT be able to achieve a higher resolution just because it doesn't yeild the thread (so you are now busy waiting). However, I'm not so certain it will make a difference as the OS is still in charge of putting the message on the queue. If it uses an interrupt type system to place the message on the queue (IE, setting a timer interrupt to give control back to the OS) Then it will have the possibility of having a pretty high resolution. However, if it uses some other mechanism then it will essentially suffer the same issues as any other timing method.

Really, the safest bet for high resolution timing is using "QueryPerformanceCounter" and busy waiting until the allotted time has run out. It isn't perfect as the OS will still interrupt your application every ~15ms just to say hi (It can really screw things up. Especially if your thread loses control of the CPU, that ends up being ~ a 15ms drop off where you application can't do a thing).

Dos doesn't have these issues :D