Kernel Event-Timers Our first look at the Linux kernel’s dynamic timers

advertisement
Kernel Event-Timers
Our first look at the Linux kernel’s
mechanism for managing its
dynamic timers
The timer interrupt
“There is a sense in which the timer interrupt drives
the entire Operating System” -- John O’Gorman
The ‘task_struct’ structure
• The OS kernel creates a Task Control
Block for each task which currently exists
• In Linux this TCB has type ‘task_struct’
• There are numerous fields in a task_struct
• We wrote a module which creates a ‘/proc’
file (named ‘tcbinfo’) to let us see a TCB
• We wrote a demo-program (dumptcb,cpp)
which displays a task’s ‘task_struct’ in hex
format, by reading the ‘/proc/tcbinfo’ file
Timer-related fields
• There are several fields in the ‘task_struct’
which pertain to time-keeping mechanisms
– ‘it_real_value’ and ‘it_real_incr’
– ‘it_prof_value’ and ‘it_prof_incr’
– ‘it_virt_value’ and ‘it_virt_incr’
– ‘real_timer’
• The ‘real_timer’ field is actually a structure
of type ‘struct timer_list’ (an ‘event timer’)
‘struct timer_list’
• The ‘real_timer’ field in the ‘task_struct’ is
an element of type ‘struct timer_list’.
next
prev
expires
data
function
Demo: ‘realtimers.c’
• We wrote a kernel module which creates a
pseudo-file (named ‘/proc/realtimers’) that
shows a list of all current tasks that have
an active real-time event-timer
• You can compile this module (using our
‘Makefile’ script) with: $ make realtimers.o
• Install it with: $ /sbin/insmod realtimers.o
• Then use it with: $ cat /proc/realtimers
The ‘setitimer()’ function
• In our lab-exercise on Friday we studied
the ‘setitimer()’ library-function, used by
applications to implement ‘interval timers’
• Now we can see how ‘setitimer()’ affects
timer-related fields in a task’s ‘task_struct’
• Our ‘timerinfo.c’ module creates a ‘/proc’
file that displays those timer-related fields
• Our ‘trytimer.cpp’ demo illustrates this
The kernel’s ‘TO DO’ list
• A multitasking operating system has many
timer-related events to keep track of, so it
could have lots of work to do each time a
timer-interrupt occurs
• So there needs to be a very efficient way
to manage all of the kernel’s event-timers
• Linux employs a clever mechanism for
organizing all of its active event-timers
Doubly-Linked Lists
next
prev
A single-element list
next
prev
A multi-element list
next
prev
next
prev
next
prev
timer-list vectors
index
vec
The ‘tvecs[ ]’ array
tvecs
tvec1
index
tvec2
index
vec[ 64 ]
tvec3
index
vec[ 64 ]
tvec4
index
vec[ 64 ]
tvec5
index
vec[ 64 ]
vec[ 256 ]
Where is an event-timer put?
•
•
•
•
•
Each event-timer has an ‘expires’ field
‘expires’ holds a future value for ‘jiffies’
It’s a 32-bit unsigned long integer
These bits are subdivided: 32=6+6+6+6+8
The event-timer is assigned to one of the
five timer-list vectors, based on which one
of five numeric intervals ‘expires’ falls into
• This organizes the kernel’s ‘TO DO’ list
The five ‘expires’ intervals
•
•
•
•
•
•
Compute: when = expires – jiffies;
Use tvec1[ when>>0 ]: 0  when < 28
Use tvec2[ when>>8 ]: 28  when < 214
Use tvec3[ when>>14]: 214  when < 220
Use tvec4[ when>>20]: 220  when < 226
Use tvec5[ when>>26]: 226  when < 232
The work to be done
• When a timer-interrupt occurs, the value of
‘jiffies’ gets incremented, so it is possible that
some ‘event-timers’ may have expired
• The kernel checks the ‘index’ field of the ‘root’
timer-list vector to quickly find the list of eventtimers which might have expired
• It processes the event-timers in that list. then
increments the root vector’s ‘index’ (modulo 256)
• If ( index == 0 ) the tvecs array is ‘cascaded’
In-class exercises
• Try modifying the ‘trytimer.cpp’ program so
that it calls ‘setitimer()’ with ITIMER_PROF
instead of ITIMER_REAL. What do you
observe about the ‘task_struct’ fields?
• Try modifying the ‘trytimer.cpp’ program so
it calls ‘setitimer()’ with ITIMER_VIRTUAL
instead of ITIMER_REAL. What do you
observe about the ‘task_struct’ fields?
Exercises (continued)
• Try installing your own signal-handlers for
the SIGALRM, the SIGVTALRM, and the
SIGPROF signals, to see the effects of
using ‘setitimer()’ with the three different
types of interval timers.
• Use our ‘realtimers.c’ module to look at the
list of all current tasks that have an active
‘event-timer’
Download