|
Click
|
Triggers execution at a given time. More...
Public Types | |
| enum | { behind_sec = 1 } |
Public Member Functions | |
| Timer () | |
| Construct a Timer that does nothing when fired. | |
| Timer (const do_nothing_t &unused) | |
| Construct a Timer that does nothing when fired. | |
| Timer (TimerCallback f, void *user_data) | |
| Construct a Timer that calls f(this, user_data) when fired. | |
| Timer (Element *element) | |
| Construct a Timer that calls element ->run_timer(this) when fired. | |
| Timer (Task *task) | |
| Construct a Timer that schedules task when fired. | |
| Timer (const Timer &x) | |
| Construct a Timer that acts like x when fired. | |
| ~Timer () | |
| Destroy a Timer, unscheduling it first if necessary. | |
| void | assign () |
| Change the Timer to do nothing when fired. | |
| void | assign (const do_nothing_t &unused) |
| Change the Timer to do nothing when fired. | |
| void | assign (TimerCallback f, void *user_data) |
| Change the Timer to call f(this, user_data) when fired. | |
| void | assign (Element *element) |
| Change the Timer to call element ->run_timer(this) when fired. | |
| void | assign (Task *task) |
| Change the Timer to schedule task when fired. | |
| bool | initialized () const |
| Return true iff the Timer has been initialized. | |
| bool | scheduled () const |
| Return true iff the Timer is currently scheduled. | |
| const Timestamp & | expiry_steady () const |
| Return the Timer's steady-clock expiration time. | |
| Timestamp | expiry () const |
| Return the Timer's system-clock expiration time. | |
| Router * | router () const |
| Return the Timer's associated Router. | |
| Element * | element () const |
| Return the Timer's owning element. | |
| RouterThread * | thread () const |
| Return the Timer's associated RouterThread. | |
| int | home_thread_id () const |
| Return the Timer's associated home thread ID. | |
| void | move_thread (int tid) |
| Change the home thread. Will only apply at next schedule. | |
| void | initialize (Element *owner, bool quiet=false) |
| Initialize the timer. | |
| void | initialize (Router *router) |
| Initialize the timer. | |
| void | schedule_at_steady (const Timestamp &when_steady) |
| Schedule the timer to fire at when_steady. | |
| void | reschedule_at_steady (const Timestamp &when_steady) |
| Schedule the timer to fire at when_steady. | |
| void | schedule_at (const Timestamp &when) |
| Schedule the timer to fire at when. | |
| void | reschedule_at (const Timestamp &when) |
| Schedule the timer to fire at when. | |
| void | schedule_now () |
| Shedule the timer to fire immediately. | |
| void | schedule_after (const Timestamp &delta) |
| Schedule the timer to fire delta time in the future. | |
| void | schedule_after_sec (uint32_t delta_sec) |
| Schedule the timer to fire after delta_sec seconds. | |
| void | schedule_after_msec (uint32_t delta_msec) |
| Schedule the timer to fire after delta_msec milliseconds. | |
| void | reschedule_after (const Timestamp &delta) |
| Schedule the timer to fire delta time after its previous expiry. | |
| void | reschedule_after_sec (uint32_t delta_sec) |
| Schedule the timer to fire delta_sec seconds after its previous expiry. | |
| void | reschedule_after_msec (uint32_t delta_msec) |
| Schedule the timer to fire delta_msec milliseconds after its previous expiry. | |
| void | unschedule () |
| Unschedule the timer. | |
| void | clear () |
| Unschedule the timer and reset its expiration time. | |
| void | schedule_after_s (uint32_t delta_sec) |
| Schedule the timer to fire after delta_sec seconds (deprecated). | |
| void | schedule_after_ms (uint32_t delta_sec) |
| Schedule the timer to fire after delta_msec milliseconds (deprecated). | |
| void | reschedule_after_s (uint32_t delta_sec) |
| Schedule the timer to fire delta_sec seconds after its previous expiry time (deprecated). | |
| void | reschedule_after_ms (uint32_t delta_sec) |
| Schedule the timer to fire delta_msec milliseconds after its previous expiry time (deprecated). | |
Static Public Member Functions | |
| static Timestamp | adjustment () |
| Return an adjustment interval useful for precise timers. | |
Triggers execution at a given time.
Click Timer objects trigger the execution of code after a specific time. Click's version of "ping" (the ICMPPingSource element) uses Timer objects to create ping packets at specific times. Many other elements, such as IPRewriter, garbage-collect their internal state based on timers. An element that needs to run occasional timed tasks includes and initializes a Timer instance variable. When scheduled, most timers call their associated element's run_timer() method.
Each scheduled Timer has a single expiration Timestamp. To implement a periodic timer, reschedule the timer as appropriate.
This example element code, based on TimedSource, will print a message every 5 seconds:
Running this element might produce output like this:
pp: 1204658365.127870: timer fired with expiry 1204658365.127847! pp: 1204658370.127911: timer fired with expiry 1204658370.127847! pp: 1204658375.127877: timer fired with expiry 1204658375.127847! pp: 1204658380.127874: timer fired with expiry 1204658380.127847! pp: 1204658385.127876: timer fired with expiry 1204658385.127847! pp: 1204658390.127926: timer fired with expiry 1204658390.127847! pp: 1204658395.128044: timer fired with expiry 1204658395.127847!
The expiry time measures when the timer was supposed to fire, while Timestamp::now_steady() reports the current steady-clock time. Note that the timer's expiry time goes up by exactly 5 seconds each time, and that steady-clock time is always later than the expiry time.
Click aims to fire the timer as soon as possible after the expiry time, but cannot hit the expiry time exactly. The reschedule_after_sec() function and its variants (reschedule_after(), reschedule_after_msec()) schedule the next firing based on the previous expiry time. This makes the timer's action more robust to runtime fluctuations. Compare:
The schedule_after_sec() function sets the timer to fire an interval after the current steady-clock time, not the previous expiry. As a result, the timer drifts:
pp: 1204658494.374277: timer fired with expiry 1204658494.374256! pp: 1204658499.374575: timer fired with expiry 1204658499.374478! pp: 1204658504.375261: timer fired with expiry 1204658504.375218! pp: 1204658509.375428: timer fired with expiry 1204658509.375381! ... pp: 1204658884.998112: timer fired with expiry 1204658884.998074! pp: 1204658890.001909: timer fired with expiry 1204658889.998209! pp: 1204658895.002399: timer fired with expiry 1204658895.002175! pp: 1204658900.003626: timer fired with expiry 1204658900.003589!
Timers that are set to fire more than 1 second in the past are silently updated to the current steady-clock time. Thus, the reschedule_after() methods will never fall more than a second or two behind steady-clock time.
Elements desiring extremely frequent access to the CPU, up to tens of thousands of times a second, should use a Task object rather than a Timer. However, Tasks essentially busy-wait, taking up all available CPU. There is a tradeoff, and some elements combine a Task and a Timer to get the benefits of both; for example, LinkUnqueue uses a Task at high rates and a Timer at low rates. The Timer::adjustment() value is useful in this context.
Particularly at user level, there can be a significant delay between a Timer's nominal expiration time and the actual time it runs. Elements that desire extremely precise timings should combine a Timer with a Task. The Timer is set to go off a bit before the true expiration time (see Timer::adjustment()), after which the Task polls the CPU until the actual expiration time arrives.
Since Click is cooperatively scheduled, any timer callback should run for just a short period of time. Very long callbacks can inappropriately delay other timers and periodic events.
The Click core stores timers in a heap, so most timer operations (including scheduling and unscheduling) take O(log n) time and Click can handle very large numbers of timers.
Timers generally run in increasing order by expiration time. That is, if timer a's expiry() is less than timer b's expiry(), then a will generally fire before b. However, Click must sometimes run timers out of order to ensure fairness. The only strict guarantee is that a Timer will run after its nominal expiration time.
| Timer::Timer | ( | ) |
Construct a Timer that does nothing when fired.
This constructor is most useful for a Timer that will be assigned a true callback later, using one of the Timer::assign() methods. Timer::initialize() will report a warning if called on a Timer created by this constructor.
| Timer::Timer | ( | const do_nothing_t & | unused | ) |
Construct a Timer that does nothing when fired.
Unlike with the default Timer() constructor, Timer::initialize() will not report a warning if called on a Timer created by this constructor.
| Timer::Timer | ( | TimerCallback | f, |
| void * | user_data | ||
| ) |
Construct a Timer that calls f(this, user_data) when fired.
| f | callback function |
| user_data | argument for callback function |
| Timer::Timer | ( | Element * | element | ) |
| Timer::Timer | ( | Task * | task | ) |
Construct a Timer that schedules task when fired.
| task | the task |
| Timer::Timer | ( | const Timer & | x | ) |
|
inline |
Destroy a Timer, unscheduling it first if necessary.
|
inline |
Change the Timer to do nothing when fired.
|
inline |
Change the Timer to do nothing when fired.
|
inline |
Change the Timer to call f(this, user_data) when fired.
| f | callback function |
| user_data | argument for callback function |
|
inline |
|
inline |
Change the Timer to schedule task when fired.
| task | the task |
|
inline |
Return true iff the Timer has been initialized.
|
inline |
Return true iff the Timer is currently scheduled.
|
inline |
Return the Timer's steady-clock expiration time.
This is the absolute time, according to the steady clock, at which the timer is next scheduled to fire. If the timer is not currently scheduled, then expiry_steady() returns the last assigned expiration time.
|
inline |
Return the Timer's system-clock expiration time.
Timer expirations are measured using the system's steady clock, which increases monotonically. (See Timestamp::now_steady().) The expiry() function, however, returns the timer's expiration time according to the system clock. This is a calculated value: if the system clock changes – because the user changes the current system time, for example – then the timer's expiry() will also change. (The timer's expiry_steady() value will not change, however.)
|
inline |
Return the Timer's associated RouterThread.
| int Timer::home_thread_id | ( | ) | const |
Return the Timer's associated home thread ID.
| void Timer::move_thread | ( | int | tid | ) |
Change the home thread. Will only apply at next schedule.
| tid | the new thread id |
| void Timer::initialize | ( | Element * | owner, |
| bool | quiet = false |
||
| ) |
Initialize the timer.
| owner | the owner element |
| quiet | do not produce default-constructor warning if true |
Before a timer can be used, it must be attached to a containing router. When that router is destroyed, the timer is automatically unscheduled. It is safe to initialize the timer multiple times on the same router.
If Click is compiled with statistics support, time spent in this Timer will be charged to the owner element.
Initializing a Timer constructed by the default constructor, Timer(), will produce a warning.
| void Timer::initialize | ( | Router * | router | ) |
Initialize the timer.
| router | the owner router |
This function is shorthand for Timer::initialize(router ->root_element()). However, it is better to explicitly associate timers with real elements.
| void Timer::schedule_at_steady | ( | const Timestamp & | when_steady | ) |
Schedule the timer to fire at when_steady.
| when_steady | expiration time according to the steady clock |
If when_steady is more than 2 seconds behind the current time, then the expiration time is silently updated to the current time.
| void Timer::reschedule_at_steady | ( | const Timestamp & | when_steady | ) |
Schedule the timer to fire at when_steady.
| when_steady | expiration time according to the steady clock |
This is a synonym for schedule_at_steady().
|
inline |
Schedule the timer to fire at when.
| when | expiration time according to the system clock |
If when is more than 2 seconds behind system time, then the expiration time is silently updated to the current system time.
|
inline |
Schedule the timer to fire at when.
| when | expiration time |
This is a synonym for schedule_at().
|
inline |
Shedule the timer to fire immediately.
Equivalent to schedule_at(Timestamp::recent()).
| void Timer::schedule_after | ( | const Timestamp & | delta | ) |
Schedule the timer to fire delta time in the future.
| delta | interval until expiration time |
The schedule_after methods schedule the timer relative to the current time. When called from a timer's callback function, this will usually be slightly after the timer's nominal expiration time. To schedule a timer at a strict interval, compensating for small amounts of drift, use the reschedule_after methods.
|
inline |
Schedule the timer to fire after delta_sec seconds.
| delta_sec | interval until expiration time, in seconds |
|
inline |
Schedule the timer to fire after delta_msec milliseconds.
| delta_msec | interval until expiration time, in milliseconds |
|
inline |
Schedule the timer to fire delta time after its previous expiry.
| delta | interval until expiration time |
If the expiration time is too far in the past, then the new expiration time will be silently updated to the current system time.
|
inline |
Schedule the timer to fire delta_sec seconds after its previous expiry.
| delta_sec | interval until expiration time, in seconds |
|
inline |
Schedule the timer to fire delta_msec milliseconds after its previous expiry.
| delta_msec | interval until expiration time, in milliseconds |
| void Timer::unschedule | ( | ) |
Unschedule the timer.
The timer's expiration time is not modified.
|
inline |
Unschedule the timer and reset its expiration time.
|
inlinestatic |
Return an adjustment interval useful for precise timers.
Due to scheduling granularity, other tasks running on the same machine, and similar effects, a Timer object can trigger some time after its nominal expiry(). Functions that require precise timers should combine a Timer and a Task object. The Timer's job is to schedule the Task; the Timer's expiry is set to go off a short interval before the true expiry, and the Task is used to busy-wait the difference. Timer::adjustment() is an appropriate value for this time difference.
|
inline |
Schedule the timer to fire after delta_sec seconds (deprecated).
|
inline |
Schedule the timer to fire after delta_msec milliseconds (deprecated).
|
inline |
Schedule the timer to fire delta_sec seconds after its previous expiry time (deprecated).
|
inline |
Schedule the timer to fire delta_msec milliseconds after its previous expiry time (deprecated).