pacemaker 3.0.3
COM automation for people with deadlines and a hatred of GUIs
 
Loading...
Searching...
No Matches
Timer Class Reference

Fixed-rate, fixed-count periodic timer backed by a Windows high-resolution waitable timer. More...

#include <Timer.hpp>

Public Member Functions

 Timer (const std::chrono::milliseconds &period, const std::size_t &tasks_to_execute)
 Constructs a timer with the given period and iteration count.
 
 Timer (const Timer &)=delete
 Copying is deleted; The Win32 timer handle must not be duplicated.
 
 Timer (Timer &&)=delete
 Move construction is deleted; the timer has a unique identity.
 
Timeroperator= (const Timer &)=delete
 Copying assignment is deleted; The Win32 timer handle must not be duplicated.
 
Timeroperator= (Timer &&)=delete
 Move assignment is deleted; the timer has a unique identity.
 
 ~Timer ()
 Destructor; stops the timer if running and releases the Win32 handle.
 
auto start (const std::function< void(void)> &StartFcn=[]() {}) -> void
 Arms the timer and invokes the start callback.
 
auto stop (const std::function< void(void)> &StopFcn=[]() {}) -> void
 Invokes the stop callback and marks the timer as no longer running.
 
template<class F >
auto wait (const F &TimerFcn) -> void
 Blocks the calling thread and drives the timer callback to tasks_to_execute iterations.
 
auto is_running () const -> bool
 Getter to check whether or not the timer is running.
 

Detailed Description

Fixed-rate, fixed-count periodic timer backed by a Windows high-resolution waitable timer.

Timer wraps the Win32 CreateWaitableTimerExW / WaitForSingleObject API with CREATE_WAITABLE_TIMER_HIGH_RESOLUTION to achieve sub-millisecond scheduling accuracy on supported hardware. It is designed for deterministic, real-time control loops where a callback must execute at a precise, fixed rate for a known number of steps.

Execution model

The timer operates as a three-phase object:

  1. start(StartFcn): arms the waitable timer and invokes the optional start callback on the calling thread.
  2. wait(TimerFcn): blocks the calling thread, elevates it to the MMCSS "Pro Audio" scheduling class, then loops tasks_to_execute timer. Each iteration waits for the next timer tick and invokes TimerFcn with the current zero-based iteration index.
  3. stop(StopFcn): invokes the optional stop callback and marks the timer as no longer running. Called automatically by the destructor if the timer is still running at that point.

Typical usage

using namespace std::chrono_literls;
pacemaker::timer::Timer timer{10ms, 500}; // 10ms period, 500 ticks
timer.start([]{ std::cout << "Recording started\n"; });
timer.wait([](std::size_t i){
writeDataPoint(i); // called every 10ms, 500 times
});
timer.stop([]{ std::cout << "Recording stopped\n"; });
Fixed-rate, fixed-count periodic timer backed by a Windows high-resolution waitable timer.
Definition Timer.hpp:56
auto start(const std::function< void(void)> &StartFcn=[]() {}) -> void
Arms the timer and invokes the start callback.

Threading

start(), wait(), and stop() must be called from the same thread in the order shown above. Timer is non-copyable and non-movable.

First-tick delay

The waitable timer is armed with an initial due time of -400ms (expressed as a 100-ns relative interval: -4 000 000 x 100 ns) so that the first tick fires approximately 40ms after start() is called, giving downstram systems time to initialise before data capture begins.

Note
Platform: Windows only. Requires CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, which is available on Windows10 version 1803 and later
See also
pacemaker::timer::AvSetMmThreadOptions

Definition at line 55 of file Timer.hpp.

Constructor & Destructor Documentation

◆ Timer() [1/3]

Timer ( const std::chrono::milliseconds & period,
const std::size_t & tasks_to_execute )

Constructs a timer with the given period and iteration count.

Creates the underlying Win32 high-resolution waitable timer via CreateWaitableTimerExW with CREATE_WAITABLE_TIMER_HIGH_RESOLUTION. The timer is created in a stopped, unarmed state; call start() to arm it.

Parameters
periodTick interval, Must be a positive duration; the value is converted to milliseconds and passed as the lPeriod argument to SetWaitableTimer.
tasks_to_executeTotal number of timer ticks (loop iterations) that wait() will block for before returning.
Exceptions
std::runtime_errorif CreateWaitableTimerExW returns NULL (e.g. insufficient privileges or the high-resolution timer is unavailable on the current platform).

◆ Timer() [2/3]

Timer ( const Timer & )
delete

Copying is deleted; The Win32 timer handle must not be duplicated.

◆ Timer() [3/3]

Timer ( Timer && )
delete

Move construction is deleted; the timer has a unique identity.

◆ ~Timer()

~Timer ( )

Destructor; stops the timer if running and releases the Win32 handle.

If the timer is still running when the destructor executes stop() is called with the default (no-op) stop callback. The Win32 waitable timer is then cancelled via CancelWaitableTimer and its handle is closed via CloseHandle

Member Function Documentation

◆ operator=() [1/2]

Timer & operator= ( const Timer & )
delete

Copying assignment is deleted; The Win32 timer handle must not be duplicated.

◆ operator=() [2/2]

Timer & operator= ( Timer && )
delete

Move assignment is deleted; the timer has a unique identity.

◆ start()

auto start ( const std::function< void(void)> & StartFcn = []() {}) -> void

Arms the timer and invokes the start callback.

Arms the Win32 waitable timer with an initial due time of -40ms (~40ms from now, expressed as a relative 100-ns interval) and the configured period, then calls StartFcn on the calling thread.

The timer must not already be running when this method is called.

Parameters
StartFcnOptional callback invoked once on the calling thread immediately after the timer is armeds. Defaults to a no-op lambda. Use it to perform any initialisation tht must happen at the moment recording begins (e.g. opening a file, logging a timestamp).

◆ stop()

auto stop ( const std::function< void(void)> & StopFcn = []() {}) -> void

Invokes the stop callback and marks the timer as no longer running.

Calls StopFcn on the calling thread and then clears the internal running flag. This method does not cancel the Win32 waitable timer handle; handle cleanup is performed by the destructor.

stop() is called automatically by the destructor if the timer is still running at destruction time.

Parameters
StopFcnOptional callback invoked once on the calling thread before the running flag is cleared. Defaults to a no-op lambda. Use it to perform any teardown that must happen at the moment recording ends (e.g. flushing a buffer, logging a timestamp).

◆ wait()

template<class F >
auto wait ( const F & TimerFcn) -> void
inline

Blocks the calling thread and drives the timer callback to tasks_to_execute iterations.

Elevates the calling thread to the Windows Multimedia Class Scheduling Service (MMCSS) "Pro Audio" task at AVRT_PRIORITY_HIGH for the duration of the loop, then iterates tasks_to_execute times. Each iteration:

  1. Calls Timer::wait_for_single_object to block until the next timer tick fires.
  2. Invokes TimerFcn with the current zero-based iteration index.

MMCSS elevation is automatically reverted when wait() returns (via the RAII destructor of AvSetMmThreadOptions).

wait() returns only after all tasks_to_execute ticks have been processed. Call stop() after wait() returns to peform teardown.

Parameters
TimerFcnCallback invoked once per timer tick. Receives the zero-based iteration index (0 ... tasks_to_execute - 1) as its sole argument. The callback runs on the calling thread synchronously within the loop body; it must complete before the next Timer::wait_for_single_object call.
Note
If TimerFcn takes longer than one tick period to execute, subsequent ticks will fire late because the timer is re-armed relative to the previous expiry by the OS, not relative to when Timer::wait_for_single_object returns.

Definition at line 165 of file Timer.hpp.

◆ is_running()

auto is_running ( ) const -> bool
nodiscard

Getter to check whether or not the timer is running.


The documentation for this class was generated from the following file: