Timer Class Reference

List of all members.

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);
     Timestamp now = Timestamp::now();
     click_chatter("%s: %{timestamp}: timer fired with expiry %{timestamp}!\n",
                   declaration().c_str(), &now, &_timer.expiry());
                   // _timer.expiry() is the Timestamp at which the timer
                   // was set to fire.
     _timer.reschedule_after_sec(5);  // Fire again 5 seconds later.
 }

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() reports the current system time. Note that the timer's expiry time goes up by exactly 5 seconds each time, and that system 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) {
     Timestamp now = Timestamp::now();
     click_chatter("%s: %{timestamp}: timer fired with expiry %{timestamp}!\n",
                   name().c_str(), &now, &_timer.expiry());
     _timer.schedule_after_sec(5);  // Fire again 5 seconds later.
         // This is the same as:
         // _timer.schedule_at(Timestamp::now() + Timestamp::make_sec(5));
 }

The schedule_after_sec() function sets the timer to fire an interval after the current system 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 system time. Thus, the reschedule_after() methods will never fall more than a second or two behind system 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.


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 (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 Timestampexpiry () const
 Return the Timer's current expiration time.
Routerrouter () const
 Return the Timer's associated Router.
void initialize (Element *owner, bool quiet=false)
 Initialize the timer.
void initialize (Router *router)
 Initialize the timer.
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.

Classes

struct  do_nothing_t


Constructor & Destructor Documentation

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.

Parameters:
f callback function
user_data argument for callback function

Timer::Timer ( Element element  ) 

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

Parameters:
element the element

Timer::Timer ( Task task  ) 

Construct a Timer that schedules task when fired.

Parameters:
task the task

Timer::Timer ( const Timer x  ) 

Construct a Timer that acts like x when fired.

The newly-constructed Timer is not initialized.

Timer::~Timer (  )  [inline]

Destroy a Timer, unscheduling it first if necessary.


Member Function Documentation

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

Change the Timer to do nothing when fired.

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

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

Parameters:
f callback function
user_data argument for callback function

void Timer::assign ( Element element  )  [inline]

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

Parameters:
element the element

void Timer::assign ( Task task  )  [inline]

Change the Timer to schedule task when fired.

Parameters:
task the task

bool Timer::initialized (  )  const [inline]

Return true iff the Timer has been initialized.

bool Timer::scheduled (  )  const [inline]

Return true iff the Timer is currently scheduled.

const Timestamp& Timer::expiry (  )  const [inline]

Return the Timer's current expiration time.

The expiration time is the absolute time at which the timer is next scheduled to fire. If the timer is not currently scheduled, then expiry() returns the last assigned expiration time.

Router* Timer::router (  )  const [inline]

Return the Timer's associated Router.

void Timer::initialize ( Element owner,
bool  quiet = false 
) [inline]

Initialize the timer.

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

Parameters:
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 ( const Timestamp when  ) 

Schedule the timer to fire at when.

Parameters:
when expiration time
If when is more than 2 seconds behind system time, then the expiration time is silently updated to the current system time.

void Timer::reschedule_at ( const Timestamp when  )  [inline]

Schedule the timer to fire at when.

Parameters:
when expiration time
This element is a synonym for schedule_at().

void Timer::schedule_now (  )  [inline]

Shedule the timer to fire immediately.

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

void Timer::schedule_after ( const Timestamp delta  ) 

Schedule the timer to fire delta time in the future.

Parameters:
delta interval until expiration time
The schedule_after methods schedule the timer relative to the current system time, Timestamp::now(). 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.

void Timer::schedule_after_sec ( uint32_t  delta_sec  )  [inline]

Schedule the timer to fire after delta_sec seconds.

Parameters:
delta_sec interval until expiration time, in seconds
See also:
schedule_after, reschedule_after_sec

void Timer::schedule_after_msec ( uint32_t  delta_msec  )  [inline]

Schedule the timer to fire after delta_msec milliseconds.

Parameters:
delta_msec interval until expiration time, in milliseconds
See also:
schedule_after, reschedule_after_msec

void Timer::reschedule_after ( const Timestamp delta  )  [inline]

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

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

See also:
schedule_after

void Timer::reschedule_after_sec ( uint32_t  delta_sec  )  [inline]

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

Parameters:
delta_sec interval until expiration time, in seconds
See also:
schedule_after_sec, reschedule_after

void Timer::reschedule_after_msec ( uint32_t  delta_msec  )  [inline]

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

Parameters:
delta_msec interval until expiration time, in milliseconds
See also:
schedule_after_msec, reschedule_after

void Timer::unschedule (  ) 

Unschedule the timer.

The timer's expiration time is not modified.

void Timer::clear (  )  [inline]

Unschedule the timer and reset its expiration time.

static Timestamp Timer::adjustment (  )  [inline, static]

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.

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.

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.

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.

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:
Generated on Tue Mar 2 12:25:48 2010 for Click by  doxygen 1.5.1