140 likes | 229 Views
Learn how Linux kernel utilizes hardware and software timers for precise invocation of functions in the future. Explore examples like IA32 systems and software timer data structures for efficient timer handling. Modify demos for practical exercises.
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)