Linux OS system analysis (5)-timer

Source: Internet
Author: User
Tags event timer time and date
I. Summary

A timer is a basic component in the operating system. Whether it is user space program development or kernel space program development, a timer is often required as the basic component. The purpose of using a timer is nothing more than to periodically execute a task, or to execute a task at a specified time.

This article first discusses the classification and implementation of timers in Linux, and uses corresponding interface functions.


Ii. Timer types

RTC (real time clock)

Real-time clock, independent of the CPU and all other chips, can interrupt periodically on irq8, with a frequency between 2hz-8192hz.


TSC (time stamp counter)

Timestamp timer, which is a 64-bit TSC register in the CPU. The value of each CPU clock cycle is plus one. You can use the assembly language command rdtsc to read this register.


Pit (programmable interval timer)

The programmable interval timer sends out a special interrupt to notify the kernel that a time interval has elapsed, and the pit always interrupts at a fixed frequency specified by the kernel.


APIC-CPU local Timer


Hpet-high-precision Event timer


ACPI Power Management timer

Iii. Timing System Structure

The kernel periodically performs the following tasks:

1) Update the time elapsed since the system was started;

2) Update time and date;

3) process time slice allocation;

4) Update the resource usage statistics;

5) check whether the time interval of each soft timer has been reached.

Timer Initialization

1) initialize the xtime variable (storing the current time and date );

2) initialize the wall_to_monotonic variable;

3) if the kernel supports hpet, it will call the hpet_enable function to check whether the ACPI firmware detects the chip and maps its registers to the memory address space;

4) Call select_timer () to select the best timer resources available in the system (precision first) and set the cur_timer variable to point to the address of the timer object corresponding to the timer resource;

5) Call setup_irq (0, & irq0) to create the interrupt gate corresponding to irq0. The irq0 pin is connected to the interrupt source (pit or hpet) of the system clock ).


Clock terminal Processing Program Execution

1) generate a write_seqlock () in the xtime_lock sequence to protect timer-related kernel variables;

2) run the mark_offset method of the cur_timer timer object. The timer pointed to by cur_timer has been determined during timer initialization;

3) Call the do_timer_interrupt () function;

4) Call write_sequnlock to release the xtime_lock sequence lock;

5) return 1, and the report interruption has been effectively handled.


In Linux, two types of timers are considered: Dynamic timer and interval timer ). The first type is used by the kernel, which can be created by the process in the user State.


Create a dynamic Timer

1) Create a New timer_list object (static global variables, defining local variables, and Dynamic Allocation );

2) Call init_timer (& T) to initialize this object;

3) Place the function address to be activated when the timer expires in the function field;

4) if the dynamic timer has not been inserted into the linked list, for example, the expires field assigns an appropriate value and calls add_timer (& T) to insert T into the linked list;

5) if it has been inserted, call mod_timer () to update the expires field.


Iii. Timer usage

Unsigned int alarm (unsigned int seconds );
Function Description: Alarm () is used to set the signal sigalrm to be transmitted to the current process after the number of seconds specified by the seconds parameter. If the seconds parameter is 0, the previously set alarm is canceled and the remaining time is returned.

Return Value: returns the remaining seconds of the previous alarm. If no alarm is set, 0 is returned.
After alarm () is executed, the process continues to be executed. In the later stage (after alarm), the process will receive the signal sigalrm and execute its processing function in seconds.

Example:

#include <stdio.h>#include <unistd.h>#include <signal.h>void alarm_handler(int a){printf("Timer is up!\n");alarm(3);}int main(){signal(SIGALRM,alarm_handler);alarm(1); while(1) {};return 1;}

Execution result:




Int setitimer (INT which, const struct itimerval * value, struct itimerval * ovalue ));
Setitimer () is more powerful than alarm and supports three types of Timers:

Itimer_real: calculated based on the real time of the system. It sends the sigalrm signal.
Itimer_virtual:-calculate the time spent by the process in the user State, and it sends the sigvtalrm signal.
Itimer_prof: calculates the time spent by the process in the user and kernel modes, and sends the sigprof signal.
Setitimer () the first parameter which specifies the timer type (one of the above three); the second parameter is an instance of the structure itimerval; the third parameter can not be processed.
If setitimer () is called successfully, 0 is returned; otherwise,-1 is returned.


Related struct:


Struct itimercal:
Struct itimerval {
Struct timeval it_interval;/* timer interval */
Struct timeval it_value;/* Current Value *
};

Struct timeval {
Long TV _sec;
Long TV _usec;
};

The it_value in the itimerval structure is the time for reduction. When the value is 0, a corresponding signal is sent. set it_value to it_interval. in this way, the round-robin timing is realized, instead of having to schedule only once as alarm, and its accuracy is also very high.


Example:

#include <stdio.h>#include <unistd.h>#include <signal.h>#include <sys/time.h>void alarm_handler(int sig){switch(sig){case SIGALRM:printf("Catch a SIGALRM!\n");break;case SIGVTALRM:printf("Catch a SIGVTALRM!\n");break;}return;}int main(){struct itimerval value, ovalue, value2;              signal(SIGALRM, alarm_handler);    signal(SIGVTALRM, alarm_handler);    value.it_value.tv_sec = 1;    value.it_value.tv_usec = 0;    value.it_interval.tv_sec = 1;    value.it_interval.tv_usec = 0;    setitimer(ITIMER_REAL, &value, &ovalue);    value2.it_value.tv_sec = 0;    value2.it_value.tv_usec = 500000;    value2.it_interval.tv_sec = 0;    value2.it_interval.tv_usec = 500000;    setitimer(ITIMER_VIRTUAL, &value2, &ovalue);    while(1);return 1;}

Run:



Iv. References

Understanding the kernel 3rd Edith

Linux Application Layer timer and sleep-http://blog.csdn.net/max415/article/details/2315977


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.