140 likes | 224 Views
Linux kernel timers. How can a module cause a function to be invoked at some future moment in time?. Hardware timer-counters. IA32 systems: several hardware timers External devices, or internal to processor Examples: 8254 Programmable Interval Timer (IRQ0)
E N D
Linux kernel timers How can a module cause a function to be invoked at some future moment in time?
Hardware timer-counters • IA32 systems: several hardware timers • External devices, or internal to processor • Examples: • 8254 Programmable Interval Timer (IRQ0) • MC146818 Real Time Clock w/CMOS (IRQ8) • Pentium’s 64-bit Time Stamp Counter register • Local APIC’s programmable Counter register • (optional) 8254 Watchdog Timer (NMI) • (optional) Network Interface Card (IRQ varies)
Linux Software Timers • Easy for device-driver programmers to use • Used mainly for detecting device “lockups” • But could also be used for other purposes • The driver-writer merely needs to: 1) define a “customized” timeout-function 2) allocate and initialize a kernel-structure 3) call standard routines for timer-control
Software Timer’s Data-Structure struct timer_list struct list_head list; unsigned long expires; unsigned long data; void (*function)( unsigned long ); Use the ‘init_timer()’ routine to initialize the ‘list’ field
Defining your “timeout” action void my_action( unsigned long dataptr ) { /* …perform your desired actions… */ /* then reschedule timer expiration */ next_timeout = jiffies + 5*HZ; mod_timer( &my_timer, next_timeout ); }
Assigning structure’s attributes struct timer_list my_timer; // declared global int init_module( void ) { init_timer( &my_timer ); // for ‘list’ setup my_timer.data = (unsigned long)&my_data; my_timer.function = my_action; my_timer.expires = jiffies + 5 * HZ; add_timer( &my_timer ); return SUCCESS; }
Removing your timer safely void cleanup_module( void ) { int status = del_timer_sync( &my_timer ); // 1 means ‘my_timer’ was queued // 0 means ‘my_timer’ wasn’t queued }
Kernel’s dynamic-timer handling • Need to deal efficiently with many timers • One big linked list would NOT be efficient • Linux adopts a clever partitioning structure • Uses special structures (called ‘tvec’s) • Timers partitioned by their expiration-times • Result: reduces amount of list-processing
Groups of timer lists Array of ‘tvec’ structures (< 0xFF ) ( < 0x3FFF ) ( < 0xFFFFF ) ( < 0x3FFFFFF ) ( < 0xFFFFFFFF )
In-Class Exercise • Modify the ‘mytimer.c’ demo (on website) • Change expiration-frequency (to 5 secs) • Print timer’s messages on user’s console • (See our ‘announce.c’ demo for how-to)