Timer by jgreddy30



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

         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(struct timer_list *timer);
The two functions to add/delete timers:
  void add_timer(struct timer_list *timer);
  int del_timer(struct timer_list *timer);

Linux 2.0

Linux 2.4
                 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(struct timeval *tvalptr, struct timezone *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
  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
         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

The times are indicated in the following structure:
  struct itimerval {
     struct timeval it_interval;      /* interval */
     Struct timeval it_value;         /* starting value */

To top