Timer example:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
MODULE_LICENSE("GPL");
static struct timer_list my_timer;
void my_timer_callback( unsigned long data )
{
printk( "my_timer_callback called (%ld).\n", jiffies );
}
int init_module( void )
{
int ret;
printk("Timer module installing\n");
// my_timer.function, my_timer.data
setup_timer( &my_timer, my_timer_callback, 0 );
printk( "Starting timer to fire in 200ms (%ld)\n", jiffies );
ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(200) );
if (ret) printk("Error in mod_timer\n");
return 0;
}
void cleanup_module( void )
{
int ret;
ret = del_timer( &my_timer );
if (ret) printk("The timer is still in use...\n");
printk("Timer module uninstalling\n");
return;
}
High-resolution timers:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
MODULE_LICENSE("GPL");
#define MS_TO_NS(x) (x * 1E6L)
static struct hrtimer hr_timer;
enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
{
printk( "my_hrtimer_callback called (%ld).\n", jiffies );
return HRTIMER_NORESTART;
}
int init_module( void )
{
ktime_t ktime;
unsigned long delay_in_ms = 200L;
printk("HR Timer module installing\n");
ktime = ktime_set( 0, MS_TO_NS(delay_in_ms) );
hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
hr_timer.function = &my_hrtimer_callback;
printk( "Starting timer to fire in %ldms (%ld)\n", delay_in_ms, jiffies );
hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );
return 0;
}
void cleanup_module( void )
{
int ret;
ret = hrtimer_cancel( &hr_timer );
if (ret) printk("The timer was still in use...\n");
printk("HR Timer module uninstalling\n");
return;
}
List API example:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
MODULE_LICENSE("GPL");
struct my_data_struct {
int value;
struct list_head full_list;
struct list_head odd_list;
};
LIST_HEAD( my_full_list );
LIST_HEAD( my_odd_list );
int init_module( void )
{
int count;
struct my_data_struct *obj;
for (count = 1 ; count < 11 ; count++) {
obj = (struct my_data_struct *)
kmalloc( sizeof(struct my_data_struct), GFP_KERNEL );
obj->value = count;
list_add( &obj->full_list, &my_full_list );
if (obj->value & 0x1) {
list_add( &obj->odd_list, &my_odd_list );
}
}
return 0;
}
void cleanup_module( void )
{
struct list_head *pos, *q;
struct my_data_struct *my_obj;
printk("Emit full list\n");
list_for_each( pos, &my_full_list ) {
my_obj = list_entry( pos, struct my_data_struct, full_list );
printk( "%d\n", my_obj->value );
}
printk("Emit odd list\n");
list_for_each_entry( my_obj, &my_odd_list, odd_list ) {
printk( "%d\n", my_obj->value );
}
printk("Cleaning up\n");
list_for_each_safe( pos, q, &my_full_list ) {
struct my_data_struct *tmp;
tmp = list_entry( pos, struct my_data_struct, full_list );
list_del( pos );
kfree( tmp );
}
return;
}