Two global variables involved in Linux clock interrupts one is xtime, it is the TIMEVAL data structure variable, the other is the jiffies, first of all, look at the timeval structure
struct Timeval
{
time_t tv_sec; /***second***/
susecond_t tv_usec;/***microsecond***/
}
is microsecond a millisecond or a microsecond??
1 seconds =1000 milliseconds (3 x 0), 1 seconds =1000 000 microseconds (6 0), 1 seconds =1000 000 000 nanoseconds (9 0), 1 SEC =1000 000 000 000 picosecond (12 0).
Seconds with s performance, milliseconds with MS, microseconds with us, nanosecond with NS, picosecond with PS, their rating unit is thousands, that is, 3 zeros each time.
The reason for the confusion found, because MS in MS, so I always think microsecond is milliseconds, so the tv_usec understand wrong.
Microsecond is also the meaning of microsecond (microsecond! =ms,microsecond==us), it seems that the unit's expression confuses me, also confuses most people, please friends to remember here, is very important.
Xtime is the time obtained from a CMOS circuit, usually from a historical moment to the present time, that is, to obtain the date displayed on our operating system. This is called the "real-time Clock", and its accuracy is microseconds.
Jiffies is a total number of clock interrupts recorded from the computer to the present. In the Linux kernel jiffies is far more important than xtime, then he depends on the frequency of the system, the unit is Hz, here have to say the frequency of units, 1mhz=1000,000hz (6 0), 1khz=1000hz (3 0).
Frequency is the inverse of the cycle, usually a second interrupt generation, so, if we need to know the system's precise time unit, need to convert, if our system frequency is 200Mhz, then the interval of one interrupt is 1 seconds/200,000,000hz=0.000 000 005 seconds to look at our unit of time above, a comparison of the decimal point is 9 zeros, so theoretically our system accuracy is 5 nanoseconds. The Linux system clock frequency is determined by a constant Hz, usually hz=100, then his accuracy is 10ms (milliseconds). That means every 10ms interrupt. So the accuracy of Linux in general is 10 milliseconds.
The hardware provides a system timer for the kernel to calculate and manage time, and the kernel programmatically presets the frequency of the system timer, which is the tick rate, which is called a tick (the beat) for each cycle. Linux kernel from the 2.5 version of the kernel began to increase the frequency from 100 to 1000, the time unit jiffies how long?
"In Linux 2.6, the system clock is interrupted every 1 milliseconds (clock frequency, expressed as a HZ macro, defined as 1000, 1000 interrupts per second, 2.4 is defined as 100, and many applications still use 100 clock frequency), a time unit called a jiffie. "
"The conversion between jiffies and absolute time, with two macros to complete the interchange of two time units: Jiffies_to_ns (), Ns_to_jiffies ()"
(Of course, there are many advantages, there are some shortcomings).
The hardware provides a system timer for the kernel to calculate and manage time, and the kernel programmatically presets the frequency of the system timer, which is the tick rate, which is called a tick (the beat) for each cycle. The Linux kernel starts with the 2.5 kernel to increase the frequency from 100 to 1000 (which of course brings many advantages and some drawbacks).
Jiffies is a global variable in the kernel that is used to record the number of Beats generated from the start of the system. For example, if the calculation system is running for how long, it can be calculated using Jiffies/tick rate. Jiffies defined in file <linux/jiffies.h>:
extern unsigned long volatile jiffies;
You can use Jiffies to set timeouts, for example:
unsigned long timeout = jiffies + tick_rate * 2; Timeout after 2 seconds
if (Time_before (jiffies, timeout) {
Not yet timed out
}
else{
Has timed out
}
The kernel provides four macros to compare the beat count, which are defined in file <linux/jiffies.h>:
Time_before (unknown, known)
Time_after (unknown, known)
Time_before_eq (unknown, known)
Time_after_eq (unknown, known)
Use these macros when comparing to avoid jiffies caused by too large.
In addition to the system timer, there is a time-dependent clock: Real time Clock (RTC), which is a hardware clock that is used to keep the system time in place and the system shuts down to maintain timekeeping on the micro battery on the motherboard. When the system starts, the kernel initializes the wall time by reading the RTC and stores it in the Xtime variable, which is the main function of RTC.
The content of network correlation function is detailed///////////////////////////////// /////////////////////////////////////
1.linux HZ
Linux core several important time-related nouns or variables, the following will introduce Hz, tick and jiffies.
Hz
The Linux core emits a timer interrupt (IRQ 0) every fixed period, and Hz is used to define a few timer interrupts per second. For example, a Hz of 1000 means that there are 1000 timer interrupts per second. Hz can be set at the time of compiling the core, as shown below (for example in core version 2.6.20-15):
[Email protected]:~$ cd/usr/src/linux
[Email protected]:/usr/src/linux$ make Menuconfig
Processor type and features---> Timer frequency (HZ)--->
Where Hz can be set to 100, 250, 300 or 1000.
Small experiment
Observe the number of timer interrupts in/proc/interrupt and observe their values again after one second. Theoretically, the two should be about 250.
[Email protected]:~$ cat/proc/interrupts | grep timer && sleep 1 && cat/proc/interrupts | grep timer
0:9309306 Io-apic-edge Timer
0:9309562 Io-apic-edge Timer
The above four fields are interrupt number, number of CPU interrupts, PIC and device name, respectively.
To check the value of Hz on the system, execute the command
Cat Kernel/.config | grep ' ^config_hz= '
2.Tick
Tick is the reciprocal of Hz, meaning that the timer interrupt every time the interrupt occurs. When Hz is 250, the tick is 4 milliseconds (millisecond).
3.Jiffies
Jiffies is a linux core variable (unsigned long), which is used to record how many ticks have been made since the system was powered on. Each time a timer interrupt,jiffies variable is added. It should be noted that the Jiffies system boot, not initialized to 0, but is set to -300*hz (ARCH/I386/KERNEL/TIME.C), that is, on behalf of the system five minutes after the boot, jiffies will overflow. What about the overflow? In fact, the Linux core defines several macro (Timer_after, Time_after_eq, Time_before and time_before_eq), even if the overflow, can be borrowed from this Several macro-jiffies correctly obtained the content.
In addition, the 80X86 schema defines a jiffies-related variable jiffies_64, which is a 64-bit variable that can take up to millions of years to overflow this variable. So it's going to be hard to wait for the overflow to happen.
3.1 Jiffies and its overflow
The global variable jiffies value is the number of clock ticks since the operating system started, defined in header file <linux/sched.h>, with the data type unsigned long volatile (32-bit unsigned long).
Jiffies converted to seconds can be calculated using the formula: (Jiffies/hz),
Converting seconds to jiffies can be calculated using the formula: (SECONDS*HZ).
When the clock interrupt occurs, the Jiffies value is added 1. Therefore, the continuous accumulation of a year and four months after the overflow (assuming hz=100,1 jiffies equals 1/100 seconds, jiffies can record the maximum number of seconds is (2^32-1)/100=42949672.95 seconds, about 497 days or 1.38 years), That is, when the value reaches the maximum value continues to add 1, it becomes 0.
3.4 How the Linux kernel prevents jiffies overflow
The following four macros are available in the Linux kernel to effectively resolve errors in program logic caused by jiffies overflow. Here is the code extracted from the Linux Kernel 2.6.7 Release:
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because If the timer wrap changes in future you won ' t has to
* Alter your driver code.
*
* Time_after (A, B) returns true if the time A is after time B.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* Good compiler would generate better code (and a really good compiler
* wouldn ' t care). GCC is currently neither.
*/
#define Time_after (A, b) \
(Typecheck (unsigned long, a) && \
Typecheck (unsigned long, b) && \
((long) (b)-(long) (a) < 0))
#define Time_before (A, B) time_after (b,a)
#define TIME_AFTER_EQ (A, b) \
(Typecheck (unsigned long, a) && \
Typecheck (unsigned long, b) && \
((Long) (a)-(long) (b) >= 0))
#define TIME_BEFORE_EQ (A, B) time_after_eq (b,a)
In macro Time_after, first make sure that the data type of the two input parameters A and B is unsigned long before performing the actual comparison.
8. Conclusion
The system uses the jiffies to calculate the time, but because the jiffies overflow may cause the time comparison error, therefore strongly recommends in the code uses the Time_after and so on the macro to compare the time relations, these macros can rest assured use.
Kernel clock:
The kernel uses different clocks provided by the hardware to provide time-dependent services, such as busy-waiting (wasting CPU cycles) and sleep-waiting (discarding the CPU)
5.HZ and Jiffies
Jiffies records the number of ticks after the system starts, commonly used functions: Time_before (), Time_after (), Time_after_eq (), Time_before_eq (). Because the jiffies changes with the clock tick, cannot optimize it with the compiler, should take the volatile value.
The 32-bit jiffies variable overflows after 50 days and is too small, so the kernel provides variable jiffies_64 to hold 64-bit jiffies. The 64-bit low 32-bit is jiffies, which requires a two-day instruction on a 32-bit machine to assign 64-bit data, not atomic, so the kernel provides the function get_jiffies_64 ().
6.Long delays
Busy-wait:timebefore (), so that the CPU is busy waiting, sleep-wait:shedule_timeout (up to the time), regardless of the kernel space or user space, there is no more precise control than Hz, because the time slices are based on tick updates, And even if you define your process to run after a specified time, the scheduler may choose other processes to execute based on the priority.
Sleep-wait (): Wait_event_timeout () is used to re-enter the ready queue after a condition or timeout is met, Msleep () Sleep-specified MS, and these long delays apply only to the process context. You cannot sleep in an interrupt context and you cannot busy-waiting for long periods of time.
The kernel provides the timer API to execute a function after a certain amount of time:
#include <linux/timer.h>
struct Timer_list my_timer;
Init_timer (&my_timer); /* Also See Setup_timer () */
My_timer.expire = jiffies + n*hz; /* n is the timeout in number of seconds */
My_timer.function = Timer_func; /* Function to execute
After n seconds */
My_timer.data = Func_parameter; /* Parameter to being passed to Timer_func */
Add_timer (&my_timer); /*start the timer*/
If you want to execute the above code periodically, add them to the Timer_func () function. You use Mod_timer () to change the My_timer time-out value, Del_timer () to delete the My_timer, and timer_pending () to see if My_timer is in the suspended state.
The user-space functions clock_settime () and Clock_gettime () are used to obtain the kernel clock service. The user application uses Setitimer () and Getitimer () to control the delivery of the alarm signal when the specified time-out occurs.
8.Real Time Clock
RTC Clock Track absolute time. RTC batteries often exceed computer lifetimes. You can use RTC to perform the following functions: (1) Read or set the absolute clock, interrupt at clock updates, (2) generate periodic interrupts from 2HZ to 8192HZ, and (3) set alarms.
Jiffies is only relative to the system boot relative time, if you want to get absolute or wall times, you need to use RTC, the kernel is recorded with variable Xtime, when the system starts, read the RTC and recorded in Xtime, when the system halt, it will wall Time is written back to RTC, the function Do_gettimeofday () to read wall time.
#include <linux/time.h>
static struct Timeval curr_time;
Do_gettimeofday (&curr_time);
My_timestamp = Cpu_to_le32 (curr_time.tv_sec); /* Record Timestamp */
User space Get wall time function: Time () returns the number of seconds from calendar time or 00:00:00 on January 1,1970; (2) localtime (): Returns calendar Time in broken-down Format, (3) mktime (): Contrary to LocalTime (), (4) Gettimeofday () returns the calendar time with microsecond accuracy.
Another way to get the RTC is through the character device/DEV/RTC, which allows only one processor to access it at a time.
9. Clocks and Timers
Clocks and timers are important to the Linux kernel. First, the kernel manages the running time (uptime) of the system and the current wall time (wall times), which is the current actual time. Second, a large amount of activity in the kernel is time-driven.
9.1 Real-Time clock
The kernel must use hardware to achieve time management. The real-time clock is the device used to keep the system time in place, which is powered by the motherboard battery, so the real-time clock continues to work even after shutting down the computer system.
When the system starts, the kernel reads the real-time clock, stores the read time in the variable xtime as the wall time (wall times), Xtime holds the number of seconds from January 1, 1970 0:00 to the current moment. While the kernel periodically saves the current time back to the real-time clock on an Intel x86 machine, it should be clear that the primary function of the real-time clock is to initialize the wall time xtime at startup.
9.2 System timers and dynamic timers
Events that occur periodically are driven by the system timer. On the X86 architecture, the system timer is usually a programmable hardware chip, and the resulting interrupt is the clock interrupt. The handler that corresponds to the clock interrupt is responsible for updating the system time and performing the tasks that are running periodically. The frequency of the system timer is called the tick rate, which is expressed as Hz in the kernel.
In the case of X86, the size of the kernel before 2.4 is 100, starting with the core 2.6, HZ = 1000, which means that the clock interrupt occurs 1000 times per second. This change makes the accuracy of the system timer (resolution) from 10ms to 1ms, which greatly improves the accuracy of the system for time-driven event scheduling. Too frequent clock interrupts inevitably add to the overhead of the system.
In contrast to the system timer is the dynamic timer, which is the timing of the scheduled event (the execution Scheduler) at some point in the future. A dynamic timer can be created or destroyed dynamically by the kernel.
The system timer and its interrupt handlers are the backbone of the kernel management mechanism, and here are some of the work performed using the system timer cycle (the work done by the interrupt handler):
(1) Update system run time (uptime)
(2) Update the current wall time (wall)
(3) on a symmetric multiprocessor system (SMP), a balanced dispatch of the running queue on each processor
(4) Check if the current process is running out of time slices (slice), and if exhausted, re-dispatch
(5) Dynamic timer for running timeout
(6) Update the statistics for resource exhaustion and processor time
The kernel dynamic timer relies on the system clock interrupt because the kernel checks for a dynamic timer that currently has a timeout only after the system clock interrupt occurs.
---------------------------------------------------------
In the X86 architecture, the core 2.6.X Hz = 1000, that is, the system clock interrupt execution granularity is 1ms, which means that the system in the cycle is the fastest thing to do once, and it is impossible to have a higher precision. The dynamic timer may time out at any time, but the average error of the dynamic timer is approximately half the system clock cycle (i.e. 0.5ms), since the kernel checks the dynamic timer for the execution timeout only when the system clock interrupt arrives.