A lot of things under kernel are time sensitive, or periodic. This means that we need to perform some operations every once in a time or that we need to wait some time before proceeding. There is a diference between periodic operations which are driven by the system timer, and operations that are to be run after a specific time, those are dyamic timers, created and maintained by the kernel. When programming modules it only makes sense to use dynamic timers.
The kernel is aware of time thanks to an electronic timer that interrupts the processor in a frequency fixed by the statically defined variable HZ, every time the timer interrupts the cpu, the variable jiffies is incremented by one, thus the system uptime is jiffies/HZ. The variable jiffies is a 64-bit unsigned integer.
Dynamic Timers
Dynamic Timers provide a way to delay execution by a fixed amount of time. The elapsed time will never be smaller than the one expected, but can be greater. The way to use a timer is to initialize it, fix the expiring time and then the function to execute after that time. The timer is deleted after that time, is for that reaoson that timers are not periodic.
struct list_head list;
unsigned long expires;
unsigned long data;
void (*function)(unsigned long);
};
To define a timer the first we need to do is declare a variable of the type struct timer_list after that, the required attributes are to be filled. Once finished filling the structure we can use the provided functions to work with the timer:
init_timer(&test_timer) : Is used to initialize the timer and has to be run previous to anything else releated to the timer, this will not activate it.
add_timer(&test_timer) : Activates the timer.
mod_timer(&test_timer, jiffies + new_wait) : Is used to modify the timer structure, it sets a new value for the expiration time.
del_timer(&test_timer) : Deletes the specifies timer. Inactive timers do not need to be deleted.
del_timer_sync(&test_timer) : Deletes the timer, assuring that the current timer handler is not running.
Example:
struct timer_list test_timer;
init_timer (&test_timer);
// We set the timer to expire after
// wait ticks
test_timer.expires= jiffies + wait;
// This data is passed to timer handler
test_timer.data = 12;
// Time handler function
test_timer.function = timer_funct;
// Activate the timer
add_timer (&test_timer);
The handler function is called with an argument of 12 after wait ticks have elapsed, the prototype for the handler function should look like: