Click
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | List of all members
Timer Class Reference

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.
 

Detailed Description

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.

Examples

This example element code, based on TimedSource, will print a message every 5 seconds:

#include <click/element.hh>
#include <click/timer.hh>
class PeriodicPrinter : public Element { public:
PeriodicPrinter();
const char *class_name() const { return "PeriodicPrinter"; }
int initialize(ErrorHandler *errh);
void run_timer(Timer *timer);
private:
Timer _timer;
};
PeriodicPrinter::PeriodicPrinter()
: _timer(this) // Sets _timer to call this->run_timer(&_timer)
{ // when it fires.
}
int PeriodicPrinter::initialize(ErrorHandler *) {
_timer.initialize(this); // Initialize timer object (mandatory).
_timer.schedule_now(); // Set the timer to fire as soon as the
// router runs.
return 0;
}
void PeriodicPrinter::run_timer(Timer *timer) {
// This function is called when the timer fires.
assert(timer == &_timer);
click_chatter("%s: %p{timestamp}: timer fired with expiry %p{timestamp}!\n",
declaration().c_str(), &now, &_timer.expiry_steady());
// _timer.expiry_steady() is the steady-clock Timestamp
// at which the timer was set to fire.
_timer.reschedule_after_sec(5); // Fire again 5 seconds later.
}
Base class for Click elements.
Definition element.hh:42
Error reporting class.
Definition error.hh:90
Triggers execution at a given time.
Definition timer.hh:14
Represents a moment or interval in time.
Definition timestamp.hh:125
static Timestamp now_steady()
Return the current steady-clock time.
Definition timestamp.hh:986
Click's Element class.
Support for Timer, which triggers execution at a given time.

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:

void PeriodicPrinter::run_timer(Timer *timer) {
click_chatter("%s: %p{timestamp}: timer fired with expiry %p{timestamp}!\n",
name().c_str(), &now, &_timer.expiry_steady());
_timer.schedule_after_sec(5); // Fire again 5 seconds later.
// This is the same as:
// _timer.schedule_at_steady(Timestamp::now_steady() + Timestamp::make_sec(5));
}

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.

Notes

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.

Constructor & Destructor Documentation

◆ Timer() [1/6]

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() [2/6]

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() [3/6]

Timer::Timer ( TimerCallback  f,
void *  user_data 
)

Construct a Timer that calls f(this, user_data) when fired.

Parameters
fcallback function
user_dataargument for callback function

◆ Timer() [4/6]

Timer::Timer ( Element *  element)

Construct a Timer that calls element ->run_timer(this) when fired.

Parameters
elementthe element

◆ Timer() [5/6]

Timer::Timer ( Task *  task)

Construct a Timer that schedules task when fired.

Parameters
taskthe task

◆ Timer() [6/6]

Timer::Timer ( const Timer &  x)

Construct a Timer that acts like x when fired.

The newly-constructed Timer is not initialized.

◆ ~Timer()

Timer::~Timer ( )
inline

Destroy a Timer, unscheduling it first if necessary.

Member Function Documentation

◆ assign() [1/5]

void Timer::assign ( )
inline

Change the Timer to do nothing when fired.

◆ assign() [2/5]

void Timer::assign ( const do_nothing_t &  unused)
inline

Change the Timer to do nothing when fired.

◆ assign() [3/5]

void Timer::assign ( TimerCallback  f,
void *  user_data 
)
inline

Change the Timer to call f(this, user_data) when fired.

Parameters
fcallback function
user_dataargument for callback function

◆ assign() [4/5]

void Timer::assign ( Element *  element)
inline

Change the Timer to call element ->run_timer(this) when fired.

Parameters
elementthe element

◆ assign() [5/5]

void Timer::assign ( Task *  task)
inline

Change the Timer to schedule task when fired.

Parameters
taskthe task

◆ initialized()

bool Timer::initialized ( ) const
inline

Return true iff the Timer has been initialized.

◆ scheduled()

bool Timer::scheduled ( ) const
inline

Return true iff the Timer is currently scheduled.

◆ expiry_steady()

const Timestamp & Timer::expiry_steady ( ) const
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.

See also
expiry()

◆ expiry()

Timestamp Timer::expiry ( ) const
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.)

See also
expiry_steady()

◆ router()

Router * Timer::router ( ) const
inline

Return the Timer's associated Router.

◆ element()

Element * Timer::element ( ) const
inline

Return the Timer's owning element.

◆ thread()

RouterThread * Timer::thread ( ) const
inline

Return the Timer's associated RouterThread.

◆ home_thread_id()

int Timer::home_thread_id ( ) const

Return the Timer's associated home thread ID.

◆ move_thread()

void Timer::move_thread ( int  tid)

Change the home thread. Will only apply at next schedule.

Parameters
tidthe new thread id

◆ initialize() [1/2]

void Timer::initialize ( Element *  owner,
bool  quiet = false 
)

Initialize the timer.

Parameters
ownerthe owner element
quietdo 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.

◆ initialize() [2/2]

void Timer::initialize ( Router *  router)

Initialize the timer.

Parameters
routerthe owner router

This function is shorthand for Timer::initialize(router ->root_element()). However, it is better to explicitly associate timers with real elements.

◆ schedule_at_steady()

void Timer::schedule_at_steady ( const Timestamp &  when_steady)

Schedule the timer to fire at when_steady.

Parameters
when_steadyexpiration 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.

See also
schedule_at()

◆ reschedule_at_steady()

void Timer::reschedule_at_steady ( const Timestamp &  when_steady)

Schedule the timer to fire at when_steady.

Parameters
when_steadyexpiration time according to the steady clock

This is a synonym for schedule_at_steady().

◆ schedule_at()

void Timer::schedule_at ( const Timestamp &  when)
inline

Schedule the timer to fire at when.

Parameters
whenexpiration 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.

Note
The schedule_at_steady() function should generally be preferred to schedule_at(). schedule_at() is implemented in terms of schedule_at_steady().
See also
schedule_at_steady()

◆ reschedule_at()

void Timer::reschedule_at ( const Timestamp &  when)
inline

Schedule the timer to fire at when.

Parameters
whenexpiration time

This is a synonym for schedule_at().

◆ schedule_now()

void Timer::schedule_now ( )
inline

Shedule the timer to fire immediately.

Equivalent to schedule_at(Timestamp::recent()).

◆ schedule_after()

void Timer::schedule_after ( const Timestamp &  delta)

Schedule the timer to fire delta time in the future.

Parameters
deltainterval 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.

◆ schedule_after_sec()

void Timer::schedule_after_sec ( uint32_t  delta_sec)
inline

Schedule the timer to fire after delta_sec seconds.

Parameters
delta_secinterval until expiration time, in seconds
See also
schedule_after, reschedule_after_sec

◆ schedule_after_msec()

void Timer::schedule_after_msec ( uint32_t  delta_msec)
inline

Schedule the timer to fire after delta_msec milliseconds.

Parameters
delta_msecinterval until expiration time, in milliseconds
See also
schedule_after, reschedule_after_msec

◆ reschedule_after()

void Timer::reschedule_after ( const Timestamp &  delta)
inline

Schedule the timer to fire delta time after its previous expiry.

Parameters
deltainterval 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.

See also
schedule_after

◆ reschedule_after_sec()

void Timer::reschedule_after_sec ( uint32_t  delta_sec)
inline

Schedule the timer to fire delta_sec seconds after its previous expiry.

Parameters
delta_secinterval until expiration time, in seconds
See also
schedule_after_sec, reschedule_after

◆ reschedule_after_msec()

void Timer::reschedule_after_msec ( uint32_t  delta_msec)
inline

Schedule the timer to fire delta_msec milliseconds after its previous expiry.

Parameters
delta_msecinterval until expiration time, in milliseconds
See also
schedule_after_msec, reschedule_after

◆ unschedule()

void Timer::unschedule ( )

Unschedule the timer.

The timer's expiration time is not modified.

◆ clear()

void Timer::clear ( )
inline

Unschedule the timer and reset its expiration time.

◆ adjustment()

static Timestamp Timer::adjustment ( )
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.

◆ schedule_after_s()

void Timer::schedule_after_s ( uint32_t  delta_sec)
inline

Schedule the timer to fire after delta_sec seconds (deprecated).

Deprecated:
Use schedule_after_sec() instead.

◆ schedule_after_ms()

void Timer::schedule_after_ms ( uint32_t  delta_sec)
inline

Schedule the timer to fire after delta_msec milliseconds (deprecated).

Deprecated:
Use schedule_after_msec() instead.

◆ reschedule_after_s()

void Timer::reschedule_after_s ( uint32_t  delta_sec)
inline

Schedule the timer to fire delta_sec seconds after its previous expiry time (deprecated).

Deprecated:
Use reschedule_after_sec() instead.

◆ reschedule_after_ms()

void Timer::reschedule_after_ms ( uint32_t  delta_sec)
inline

Schedule the timer to fire delta_msec milliseconds after its previous expiry time (deprecated).

Deprecated:
Use reschedule_after_msec() instead.

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