BDE 4.14.0 Production release
|
Provide a mechanism to meter time.
This component provides a mechanism, bslmt::Turnstile
, to meter time. A turnstile is configured with a rate that specified how many "events" per second the turnstile should allow. After the rate is set (via the constructor or the reset
method), callers may execute the waitTurn
method, which blocks until the next interval arrives. If the turnstile is not called at or above the configured rate (e.g., due to processing performed at each interval), the turnstile is said to be "lagging behind." The amount of lag time is obtained from the lagTime
method.
A straightforward implementation of metering is to call some form of sleep (e.g., bslmt::ThreadUtil::microSleep
) with a computed rate after each processing step. However, simply calling "sleep" accumulates errors since this implementation does not account for the time taken during the processing step. For example, given two functions that take rate
(turns per second) and duration
(expected execution time in seconds), and execute rate * duration
calls to bsl::sqrt
, calling waitTurn
on a turnstile or bslmt::ThreadUtil::microSleep
with duration 1000000 / rate
, respectively; the elapsed time for each call results in the following table, showing that the bslmt::Turnstile
implementation maintains the correct rate while the microSleep
implementation accumulates errors.
Except for the reset
method, this component is thread-safe and thread-aware, meaning that multiple threads may safely use their own instances or a shared instance of a bslmt::Turnstile
object, provided that reset
is not called on a turnstile object while another thread is accessing or modifying the same object.
The waitTurn
method has a resolution of 10 milliseconds. Therefore, bslmt::Turnstile
cannot guarantee that all turns can be taken in each one second interval if a rate higher than 100 turns per second is specified.
This section illustrates intended use of this component.
The following example illustrates the use of bslmt::Turnstile
to control the rate of output being written to a specified output stream. The example function, heartbeat
, prints a specified message at a specified rate for a specified duration. An instance of bsls::Stopwatch
is used to measure time against the specified duration.
The benefits of using bslmt::Turnstile
in the above example, as opposed to simply calling sleep
in a loop, are twofold. Firstly, bslmt::Turnstile
automatically accounts for drift caused by additional processing, so the loop is allowed to execute immediately if the program fails to execute the loop at the specified rate
. Secondly, computing the sleep time and executing the sleep call, are encapsulated in the turnstile component, which improves the overall readability of the program.