Sunday, May 5, 2013

Kernel High-resolution timers (hrtimer)

In the Linux kernel, time is measured by a global variable named jiffies, which identifies the number of ticks that have occurred since the system was booted. The manner in which ticks are counted depends, at its lowest level, on the particular hardware platform on which you're running; however, it is typically incremented through an interrupt.
High-resolution timers (or hrtimers) provide a high-precision framework for timer management independent of the previously discussed timer framework because of complexities in merging the two frameworks. Although timers operate on the granularity of jiffies, hrtimers operate at the granularity of nanoseconds.

High-resolution timer API
Like the traditional timer API, timers are represented by a structure—in this case, hrtimer. This structure defines the timer from a user perspective (callback function, expiration time, and so on) and also incorporates the management information (where the timer exists in the red-black tree, optional statistics, and so on).

How to use High-Resolution Timer
Declare hrtimer Object:
static struct hrtimer hr_timer;

To initialize hrtimer:

void hrtimer_init( struct hrtimer *time, clockid_t which_clock, enum hrtimer_mode mode );
For Eg.
                hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
                hr_timer.function = &hrtimer_callback;//hrtimer_callback is variable

CALLBACK Function Eg.
enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
{
  printk( "my_hrtimer_callback called (%ld).\n", jiffies );

  return HRTIMER_NORESTART/RESTART;//based on the requirement
}


To start hrtimer:
int hrtimer_start(struct hrtimer *timer, ktime_t time, const     enum hrtimer_mode mode);
ForEg.
        ktime_t ktime;
                unsigned long delay_in_ms = 30000L;
                ktime = ktime_set( 0, MS_TO_NS(delay_in_ms) );
        hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );



Once an hrtimer has started, it can be canceled through a call to hrtimer_cancel or hrtimer_try_to_cancel. Each function includes the hrtimer reference as the timer to be stopped. These functions differ in that the hrtimer_cancel function attempts to cancel the timer, but if it has already fired, it will wait for the callback function to finish. The hrtimer_try_to_cancel function differs in that it also attempts to cancel the timer but will return failure if the timer has fired.

int hrtimer_cancel(struct hrtimer *timer);
int hrtimer_try_to_cancel(struct hrtimer *timer);