Linux Modules Character drivers IO & Memory Linux Kernel Process Management Process Address space Linux Scheduler Memory Management Interrupts Signals System Calls Kernel Synchronization Linux Inter Process Communications Serial Ports Parallel Ports Introduction to Hardware Linux Timers DMA in Linux Linux Threads Linux Thread Synchronization Linux Multi Threading Debugging in Linux GDB GNU Debugger KDB Kernel Debugger KGDB Kernel GNU Debugger Example Ethernet Driver |
Timer Timers The user application requires use of timers for various functions. In order to deal with timer, let us look into the following points: ü Understanding kernel time ü Knowing the current time ü Delaying operation for a specified amount of time ü Scheduling asynchronous functions to happen after a specified time lapse Two
main kinds of Timing measurements Keeping the current time and date, so that they can be returned to user programs: time(), ftime(), and gettimeofday(). Maintaining timers to notify the kernel that a certain interval of time is elapsed Hardware
clocks Three clocks: The real-time clock, the time stamp counter and Programmable Interval Timer. Real
time clock ü Real time clock (RTC)-CMOS RAM and RTC in same Chip, Motorola 146818 ü Periodic interrupt on IRQ8 ü Ports 0x70 and 0x71 Time
Stamp Counter ü Pentium includes a 64bit Time Stamp Counter (TSC), can be read by rdtsc instruction. ü Register is a counter that is incremented at each clock. ü If the clock rate is 400 MHz, TSC is incremented at every 2.5 nsec Programmable
Interval Timer Time measuring device, based on PIT 8254 Interrupts on IRQ0 at every 10 msec HZ 100 CLOCK_TICK_RATE 1193180 LATCH ratio of CLOCK_TICK_RATE and HZ Initialization: outb_p(0x34,
0x43); outb_p(LATCH
& 0xff, 0x40); outb(LATCH >> 8, 0x40); Time Intervals in the kernel The timer interrupt is a mechanism the kernel uses to keep track of time intervals. Timer interrupts are generated by timer chip at regular intervals, counted by timer interrupt in global variable jiffies. The time interval is set by kernel according to value of HZ, defined in <linux/param.h>. Current Linux versions define HZ to be 100, i.e. one tick is 10 msec Current Time To get the current time, use the function do_gettimeofday #include
<linux/time.h> void do_gettimeofday(struct timeval*tv); Delaying Execution Long Delays unsigned long j = jiffies +
delay * HZ; while (jiffies < j) /*
nothing */; Short Delay The kernel functions udelay and mdelay #include
<linux/delay.h> void udelay (unsigned long
usecs); void mdelay (unsigned long
msecs); Timer Interrupt Handler ü Major activities in handler: ü Updates the time elapsed since system startup ü Updates time and date ü Determines process scheduling ü Updates resource usage statistics ü Checks expiry of software timer The first activity is done in timer, other activities are done in TIMER_BH bottom half. The
Role of Timers A timer is software facility that allows functions to be invoked at some future moment. A time-out denotes a moment at which the time interval associated with a timer has elapsed. Timers are used both by the kernel and processes. Most device drivers make use of timers to detect anomalous conditions: floppy disk driver, use timers to switch off the device motor after the floppy has not been accessed for a while. Timers are also used to force execution of specific functions at some future time. System Timers int init_timer(structtimer_list*timer); The two functions to add/delete timers: void
add_timer(structtimer_list*timer); int del_timer(structtimer_list*timer); Static
timers There are 32 different timers. The static timers are stored in the timer-table array, which includes 32 entries. Each entry consists of the following timer_struct structure: struct
timer_struct{ unsigned
long expires; void
(*fn)(void); }; The expires field specifies when the timer expires, expresses in terms of number of ticks (jiffies) The fn field contains the address of the function to be executed when the timer expires. Dynamic
Timers Dynamic timers may be dynamically created and destroyed. No limit is placed on numbers of currently active dynamic timers. A dynamic timer is stored in the following timer_list structure: struct
timer_list{ struct
timer_list*next; struct
timer_list*prev; unsigned
long expires; unsigned
long data; void
(*function) (unsigned long); }; System
calls related to timing measurement System calls allow user mode processes to read and modify the time and date and to create timers. time() Returns number of elapsed seconds since midnight at the start of January 1, 1970. ftime() Returns, in a data structure of type timeb, elapsed seconds and time zone. gettimeofday()
returns elapsed time and time zone in two data structures. Current Time Linux provides the gettimeofday system call, which returns the number of seconds since 00:00:00 GMT, January 1, 1970. It also returns time zone information. #include <sys/time.h> int gettimeofday(structtimeval*tvalptr,
structtimezone*tzoneptr); struct
timeval{ long
tv_sec;/* seconds since 00:00:00 GMT, Jan.
1, 1970 */ long
tv_usec;/* and microseconds */ }; It returns zero if all is OK, with the structure pointed to by the tvalptr filled in. settimeofday() system call sets the time of day. Delaying Execution We also use the sleep function to pause for a specified number of seconds. unsigned
int sleep(unsigned int sec); The sleep function usually sets a SIGALRM signal, which it catches. Scheduling asynchronous functions to happen after a
specified time lapse -alarm() system call The alarm() system call is used for setting software timeouts. A process can set an alarm clock by calling the alarm system call unsigned
int alarm(unsigned int sec); The sec argument specifies the number of seconds to elapse before the kernel is to send the process a SIGALRM signal. The argument specifies the “real time”, not the CPU time. If the argument is zero, any previous alarm clock for the process is cancelled. The value returned by the function is the time remaining, if any, from the previous call to the function. The process has to set a signal handler to process the SIGALRM signal signal
(SIGALRM, handler); setitimer() system
call Linux allows user mode processes to activate special timers called interval timers. The timers cause signals to be sent periodically to the process. It is also possible to activate an interval timer so that it sends just one signal. The frequency at which the signals must be emitted, or a null value if just one signal is to be generated. The time remaining until the next signal is to be generated. ITMER_REAL: Actual elapsed time ITIMER_VIRTUAL: Time spent is user process ITIMER_PROF: Time spent both in user and kernel mode. The following functions allow better time monitoring of a process than does alarm(). #include <sys/time.h> int getitimer(int which,
struct itimerval*value); int setitimer(int which,
const struct itimerval*value, struct itimerval *ovalue); The variable “which” specifies one of the special timer (ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF). The times are indicated in the following structure: struct
itimerval{ struct
timevalit_interval;/* interval */ struct
timevalit_value;/* starting value */ }; |