It’s time for another “APIs you never heard of” article 🙂
This time, I’d like to talk about the time* APIs.
The time* APIs are a set of 7 APIs built into the windows multimedia extensions (winmm.dll). They provide a rudimentary set of timer functions for Windows applications. At this point, except for two of the APIs, they exist only for historical purposes, the core OS now provides significantly higher quality APIs for timers.
The time APIs fall into three rough categories:
- Timer information (timeGetDevCaps, timeGetTime and timeGetSystemTime)
- Timer callback functions (timeSetEvent and timeKillEvent)
- Timer frequency functions (timeBeginPeriod and timeEndPeriod)
The first two categories are obsolete (arguably timeGetDevCaps still has valid uses). The timeGetTime API is effectively identical to the GetTickCount() API, and timeGetSystemTime simply returns the exact same value that timeGetTime would have returned, packed into a MMTIME structure.
The timeSetEvent and timeKillEvent have been replaced with the Win32 Timer Queue functions, I’m not sure if I know of any reason to ever call the MME versions of these functions :). In fact, timeSetEvent will call PulseEvent API, which is fundamentally flawed. There is one difference between timeSetEvent and the Win32 timer queue functions – timeSetEvent will call timeBeginPeriod to set the timer resolution to the resolution specified in the call to timeSetEvent. Even with this, you’re better off calling timeBeginPeriod and using the Win32 Timer Queue functions (because the Win32 timer queue functions are far more flexible).
But then there’s the timeBeginPeriod and timeEndPeriod APIs. These are actually fun APIs, especially in the multimedia or gaming space, because they allow you to change the resolution of the internal scheduler, which can lower (or raise) the resolution with which the internal clock runs.
This has a number of side effects – it increases the responsiveness of the system to periodic events (when event timeouts occur at a higher resolution, they expire closer to their intended time). But that increased responsiveness comes at a cost – since the system scheduler is running more often, the system spends more time scheduling tasks, context switching, etc. This can ultimately reduce overall system performance, since every clock cycle the system is processing “system stuff” is a clock cycle that isn’t being spent running your application. For some multimedia applications (video, for example) the increased system responsiveness is worth the system overhead (for instance, if you’re interested in very low latency audio or video, you need the system timers to run at a high frequency).
Edit: Added comment about timeSetEvent calling timeBeginPeriod to set the resolution.\
Edit2 (years later): Updated the link to GetTickCount…