Kernel Timers - PowerPoint PPT Presentation

1 / 42
About This Presentation
Title:

Kernel Timers

Description:

If the clock ticks at 400MHz, TSC is incremented once every 2.5 nanoseconds. ... Tradeoff: shorter ticks, faster kernel response time, smoother multimedia, etc. ... – PowerPoint PPT presentation

Number of Views:164
Avg rating:3.0/5.0
Slides: 43
Provided by: John859
Category:
Tags: kernel | ticks | timers

less

Transcript and Presenter's Notes

Title: Kernel Timers


1
Kernel Timers
  • Goals.
  • Learn how to study kernel code.
  • Learn how kernel implements interval timers.
  • Learn how signals work in Linux.
  • Create a user-space mechanism to measure the
    execution time of a multithreaded program.

2
Kernel Timers
  • Overview.
  • Kernel keeps the current time by reading a clock
    device
  • maintains a kernel variable with the current time
  • User-mode programs can access current time via
    system calls.
  • gettimeofday( ) is the usual interface to the
    current time.
  • kernel uses current time to determine when
    currently running process should be removed from
    CPU.
  • kernel also uses the current time to keep track
    of user mode/supervisor mode time for process.

3
clocks
  • 4 clocks used in Linux
  • Real Time Clock (RTC)
  • Time Stamp Counter
  • Programmable Interval Timer
  • Timer of the local APICs (Advanced Programmable
    Interrupt Controller) in SMP systems. Wont
    cover here.

4
clocks
  • Real Time Clock (RTC)
  • Regular clock that runs on a battery
  • Often the Motorola 146818 CMOS RAM RTC
  • Capable of issuing periodic interrupts on IRQ8
  • So it can also work as an alarm clock
  • But not used for interrupts, instead PIT is used
  • Linux uses only to derive time and date
  • Processes can program RTC by acting on the
    /dev/rtc device file
  • Kernel accesses the RTC through 0x70 and 0x71 I/O
    ports
  • SysAd can set up clock via clock system call
    (acts on these two I/O ports)

5
clocks
  • Time Stamp Counter (TSC)
  • All 80x86 microprocessors include a CLK input pin
    which receives the clock signal of an external
    oscillator
  • Starting with the Pentium, 80x86 processors
    include a 64-bit Time Stamp Counter (TSC)
  • Can be read with rdtsc assembly language
    instruction.
  • The register is a counter that is incremented at
    each clock signal
  • If the clock ticks at 400MHz, TSC is incremented
    once every 2.5 nanoseconds.
  • Allows Linux to get more accurate time
    measurements than delivered by the Programmable
    Interval Timer.
  • Linux must determine the clock signal frequency
    while initializing the system.
  • Done during boot

6
clocks
  • Programmable Interval Timer (PIT)
  • PIT acts as the alarm clock of the system
  • Usually implemented by a 8254 CMOS chip
  • Uses I/O ports 0x40-0x43
  • Linux uses the PIT to issue timer interrupts on
    IRQ0 at about 100-Hz frequency (every 10
    milliseconds).
  • The timer interval is called a tick and is stored
    in the variable tick
  • Tradeoff shorter ticks, faster kernel response
    time, smoother multimedia, etc.
  • But then more CPU time is spent handling
    interrupts
  • Alpha and IA-64 1,024 interrupts/second (1
    millisecond)

7
Kernel Time
  • Beginning of UNIX epoch 12A.M. January 1, 1970
    (000000 Greenwich Meridian Time (GMT)).
  • actually is a skip second. Doesnt exist!
  • Kernel uses two long int variables
  • number of seconds since beginning of epoch
  • number of microseconds since beginning of last
    second

8
Kernel Time
  • To read time from user space
  • include ltsys/time.h.
  • struct timeval theTime
  • gettimeofday(theTime, NULL)
  • where
  • struct timeval
  • long tv_sec
  • long tv_usec

9
Kernel Time
  • call gettimeofday(theTime, NULL)
  • on return the variable theTime.tv_sec contains
    number of seconds since beginning of epoch
  • the variable theTime.tv_usec contains number of
    microseconds that have elapsed since last second
    began.
  • the date command translates kernel time to local
    time and to Gregorian calendar time epoch.

10
Kernel Time
  • gettimeofday(theTime, NULL)
  • uses sys_gettimeofday( ) in file /kernel/time.c
  • Also see do_gettimeofday( ) in file
    /arch/i386/kernel/time.c
  • Note that the / indicates the path to the source
    on your computer. Usually is /usr/src/linux

11
Kernel Time
  • Computing time.
  • All modern computers use same basic approach for
    keeping track of time.
  • Hardware has timer device.
  • can interrupt every K time units.
  • For Linux K set to 10 milliseconds.
  • System tracks time by counting number of
    interrupts that have occurred since system was
    booted.
  • If know when machine was last booted, can compute
    time to nearest 10 milliseconds.
  • Know when machine was last booted via a
    time-of-day clock in i386 machines. Runs with a
    battery.

12
Updating Kernel Time
bottom half
arch/i386/kernel/time.c
Clock ISR timer_interrupt( )
kernel variable
kernel/sched.c
jiffies
do-timer()
kernel/sched.c
timer_bh()
TIMER_BH
update_times()
update_process_times()
13
Updating Kernel Time
arch/i386/kernel/time.c
Clock ISR timer_interrupt( )
lost_ticks counts number of ticks since the last
time the itimer was checked in the bottom half
kernel variable
kernel/sched.c
jiffies
do-timer()
lost_ticks
lost_ticks_system
TIMER_BH
14
Updating Kernel Time
kernel variables
ret_from_sys-call()
TIMER_BH
jiffies
7. updates system wide timers
kernel/sched.c
timer_bh(void)
run_old_timers() run_timer_list()
lost_ticks
8. calls
update_times()
lost_ticks_system
9. update_times gets user ticks and system ticks
since last timer interrupt
15
Updating Kernel Time
kernel/sched.c
update_times()
update_wall_time(ticks)
11. also calls update_process-times passes
arguments ticks and system
10. updates system time (using ticks) and stores
in kernel variable struct timeval xtime
ticks represent number of timer interrupts
during user time system represents number of
timer interrupts during system time
update_process_times()
13. calculates user/system ticks and calls
counter
12. updates counter for this process. When
counter expires, time slice is up.
update_one_process()
PCB variable
14. compares user ticks to processes
it_virt_value and raises SIGTALRM if bigger
15. does same with system ticks and
it_prof_value and raises SIGTPROF if bigger
16
Per Process Timers
  • kernel accumulates time and manages timers for
    each process.
  • Per process time values are saved in processs
    descriptor.
  • When kernel creates a task
  • allocates a new task descriptor of type struct
    task_struct
  • allocated from the kernels heap space
  • uses kmalloc()call.

17
Per Process Timers
  • struct task_struct contains more than 75 fields
  • struct task_struct
  • long counter
  • unsigned long policy, rt_priority
  • unsigned long it_real_value, it_prof_value,
    it_virt_value
  • unsigned long it_real_incr, it_prof_incr,
    it_virt_incr
  • struct timer_list real_timer
  • // contains tms_utime,tms_stime,tms_cutime,
    tms_cstime
  • unsigned long start_time
  • long per_cpu_utimeNR_CPUS,per_cpu_stime,cutime
    ,cstime

18
Per Process Timers
  • Fields are updated in the update_process_times()fu
    nction located in kernel/sched.c
  • This function is invoked as part of the
    ret_from_sys_call bottom half processing.
  • This function calls update_one_process()
  • update_one_process()calls other functions to
    update the values and decide if a signal should
    be raised to indicate that a timer has expired.
  • The counter field of the task_struct structure is
    used to determine whether the process needs
    scheduling attention.

19
Per Process Timers
  • Interval timers (it_XXX_value and it_XXX_incr)
  • use the kernel time to keep track of 3 different
    intervals of time
  • ITIMER_REAL Reflects the passage of real time.
  • ITIMER_VIRTUAL Reflects the passage of virtual
    time (i.e., in user mode)
  • ITIMER_PROF is the total time the process is
    running (i.e., in both user and kernel mode)
  • The it_XXX_incr field stores the interval in
    ticks between two signals
  • The it_XXX_value field stores the current value
    of the timer.

20
Per Process Timers
  • Interval timers (it_XXX_value and it_XXX_incr)
  • use the kernel time to keep track of 3 different
    intervals of time
  • ITIMER_REAL Reflects the passage of real time.
  • Implemented using it_real_value and it_real_incr
    fields.
  • these values are updated each time a process is
    triggered in the scheduler
  • when time expires, a SIGALRM is raised.

21
Per Process Timers
  • Interval timers (it_XXX_value and it_XXX_incr)
  • ITIMER_VIRTUAL Reflects the passage of virtual
    time.
  • This is time during which the process is active
    but is not in a system call (system mode)
  • This time is incremented only when the
    corresponding process is executing.
  • updated by the do_timer( ) routine
  • when it expires, raises a SIGVTALRM.
  • Implemented using it_virt_value and it_virt_incr
    fields.

22
Per Process Timers
  • Interval timers (it_XXX_value and it_XXX_incr)
  • ITIMER_PROF is the total time the process is
    running.
  • Reflects the passage of time during which the
    process is active (virtual time) plus the time
    that the kernel is doing work on behalf of the
    process (eg, reading a timer).
  • when this timer expires it sends a SIGPROF signal.

23
Per Process Timer
  • Each timer is actually a countdown timer
  • periodically initialized to a prescribed value
  • then reflects the passage of time by counting
    down to 0
  • when timer reaches 0, raises a signal to notify
    another part of the system (in the OS or
    user-space program)
  • then resets the value and begins counting down
    again

24
Per Process Timer
  • Each timer initialized with setitimer()system
    call
  • include ltsys/time.hgt
  • setitimer(int timerType, const struct itimerval
    value,
  • struct itimerval oldValue)
  • The value type is wrong in the book.

25
Per Process Timer
  • Each timer initialized with setitimer()system
    call
  • The struct itimerval includes the following
    fields
  • strut itimerval
  • struct timeval it_interval
  • struct timeval it_value

26
Per Process Timer
  • Idea of setitimer(int timerType, const struct
    itimerval value,
  • struct itimerval oldValue)
  • ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF are
    constants defined in the sys/time.h file.
  • timerType parameter is set to one of these
  • value parameter is used to initialize second and
    microsecond fields of the given timer.
  • it_value field of value defines the current value
    for the timer, ie, the the initial value of the
    timer.
  • it_interval field of value defines the value that
    should be used to reset the timer when it reaches
    zero.
  • Each of these two parameters has fields tv_sec
    and tv_usec
  • oldVal is used to return the previous value of
    the timer.

27
Per Process Timer
  • Read a timer with getitimer()system call
  • include ltsys/time.hgt
  • getitimer(int timerType, const struct itimerval
    value)
  • Idea of getitimer()
  • ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF are
    constants defined in the sys/time.h file.
  • timerType parameter is set to one of these
  • value parameter is used to return the value of
    the given timer (fields tv_sec and tv_usec)

28
Setting and Reading a Timer
  • Code fragment to set ITIMER_REAL and then read
    it.
  • include ltsys/time.hgt
  • struct itimerval v
  • v.it_interval.tv_sec9
  • v.it_interval.tv_usec999999
  • v.it_val.tv_sec9
  • v.it_val.tv_usec999999
  • setitimer(ITIMER_REAL,v,NULL)

29
Setting and Reading a Timer
  • Code fragment to read ITIMER_REAL
  • include ltsys/time.hgt
  • struct itimerval v
  • getitimer(ITIMER_REAL,v)
  • printf(d seconds, d microsections
  • ,,v.it_value.tv_sec,v.it_value.tv_usec,)

30
Project 3
  • Part A. Use ITIMER_REAL to implement a function
    that works like gettimeofday()
  • Raise a signal once per second
  • Use the signal facility to determine when
    ITIMER_REAL has been decremented to 0 and to
    count the number of seconds that have elapsed.

31
Project 3
  • Part B. Design and implement facilities that use
    the ITIMER_VIRTUAL and ITIMER_PROF interval
    timers to profile a process
  • profile provides actual time of execution (use
    the timer from part A)
  • also provides CPU time (time that the process is
    actually running)
  • also provides user-space time
  • also provides kernel-space time
  • Use gettimeofday()to compute the programswall
    clock runtime.

32
Project 3
  • Part B (cont)
  • all times must have millisecond accuracy (to the
    extent the hardware supports it)
  • Code for millisecond accuracy, may not get it.
  • Use the signal facility to create signal handlers
    to keep track of the number of seconds of virtual
    and profile time
  • raise a signal once per second.

33
Project 3
  • Part C Spawn three children.
  • Each child must recursively compute the Fibonacci
    sequence for N 20, 30, 36
  • Fibonacci code given in the outline for the
    solution.
  • May take several minutes to compute N36
  • Use the facilities from part A and B to determine
    real time, virtual time, profile time for each of
    the three process.

34
Linux Source Code
  • Read the code to understand how interval timers
    work.

/usr/src/linux
Architecture dependent code kept in this directory
net
modules
arch
drivers
mm
block
Most code kept in the directories shown
lib
alpha
char
m68k
kernel
fs
i386
ipc
kernel
mm
.
Heart of kernel code kept here
ext2
fat
proc
init
include
35
Linux Source Code
  • Read the code to understand how interval timers
    work.

/usr/src/linux
Architecture dependent code kept in this directory
net
modules
arch
drivers
mm
block
Most code kept in the directories shown
lib
alpha
char
m68k
kernel
fs
i386
ipc
itimer.c is only here
kernel
mm
.
ext2
fat
proc
init
process.c is also here
process.c is here
include
36
Solution outline
include ltsys/time.hgt include ltsignal.hgt include
ltunistd.hgt include ltstdio.hgt long unsigned int
fibonacci(unsigned int n) static long
p_realt_secs0, c1_realt_secs0,
c2_realt_secs0 static long p_virtt_secs0,
c1_virtt_secs0, c2_virtt_secs0 static long
p_proft_secs0, c1_proft_secs0,
c2_proft_secs0 static struct itimerval p_realt,
c1_realt, c2_realt static struct itimerval
p_virtt, c1_virtt, c2_virtt static struct
itimerval p_proft, c1_proft, c2_proft
37
Solution outline
main(int argc, char argv) long unsigned fib
0 int pid1, pid2 unsigned int fibarg
int status // Get command line argument,
fibarg // Initialize parent, child1, child 2,
and child 3 timer values // Enable your signal
handlers for the parent signal(SIGALRM, )
signal(SIGVTALRM, ) signal(SIGPROF, ) //
Set the parent's itimers
38
Solution outline
pid1 fork() if (pid1 0) // Enable child
1 signal handlers (disable parent handlers) //
Set the child 1 itimers // Start child 1 on the
Fibonacci program fib fibonacci(fibarg) //
Read the child 1 itimer values, and report
them getitimer(ITIMER-PROF, ) getitimer(ITIME
R-REAL, ) getitimer(ITIMER-VIRTUAL, )
39
Solution outline
printf("\n") printf("Child 1 fib ld, real
time ld sec, ld msec\n",fib,
c1_realt_secs, elapsed_usecs(c1_realt.it_value.tv
_sec,c1_realt.it_value.tv_usec)/1000) printf("Chi
ld 1 fib ld, cpu time ld sec, ld
msec\n",fib, c1_proft_secs, elapsed_usecs(c1_prof
t.it_value.tv_sec,c1_proft.it_value.tv_usec)/1000)
printf("Child 1 fib ld, user time ld sec,
ld msec\n",fib, c1-proft_secs -
c1_virtt_secs, elapsed_usecs(c1_virtt.it_value.tv
_sec,c1_virtt.it_value.tv_usec)/1000) printf("Chi
ld 1 fib ld, kernel time ld sec, ld
msec\n",fib, c1_proft_secs, (elapsed_usecs(c1_pro
ft.it_value.tv_sec,c1_proft.it_value.tv_usec)/1000
) - (elapsed_usecs(c1_virtt.it_value.tv_sec,c1_vi
rtt.it_value.tv_usec)/1000)) fflush(stdout) exit
(0) // end of child code
40
Solution outline
else pid2 fork() if (pid2 0) //
Enable child 2 signal handlers (disable parent
handlers) // Set the child 2 itimers // Start
child 2 on the Fibonacci program fib
fibonacci(fibarg) // Read the child 2 itimer
values, and report them // lots more print
statements // end of if else // do the
third child stuff // end else // end
of else
41
Solution outline
else / this is the parent / // Start the
parent on the Fibonacci program fib
fibonacci(fibarg) // Wait for the children
to terminate waitpid(0, status, 0)
waitpid(0, status, 0) waitpid(0, status,
0) // Read the parent itimer values and
report them // lots of print statements
// end of main
42
Solution outline
long unsigned int fibonacci(unsigned int n) if
(n 0) return 0 else if (n 1 n
2) return 1 else return (fibonacci(n-1)
fibonacci(n-2))
Write a Comment
User Comments (0)
About PowerShow.com