linux中如何记录时间
你知道吗?我今天花了一天的时间,就是为了搞清楚linux中时间是从哪儿来的?
都快哭了,它的时间咋就那么的乱呢?还有时钟中断,怎么说呢?与其看他的杂乱无章的代码,不如暂时的囫囵吞枣先以为自己理解了。等到以后有机会再细看kernel代码。
开始时间之旅:
硬件所提供的功能:
- RTC(Real Time Clock)--------The RTC continues to tick even when the PC is switched off, because it is energized by a small battery.Linux uses the RTC only to derive the time and date。这就是为什么关了机器或者重装系统之后,时间依然是正确的。(补充:如果电脑连上网之后,可是使用命令使得系统时间去网络上进行校对)
- Time Stamp Counter(TSC)------ 80x86 microprocessors sporta counter that is increased at each clock signal. The counter is accessible through the 64-bit Time Stamp Counter(TSC) register, which can be read by means of the rdtsc assembly language instruction. 因为在系统启动时候测出了cpu主频之后,可以使用TSC来计算‘纳秒’级的时间。
- Programmable Interval Timer (PIT) ------- 我最熟悉的可编程器件,Each IBM-compatible PC includes at
least one PIT, which is usually implemented by an 8254 CMOS chip using the 0x40-0x43 I/O ports.16位的寄存器满的时候就会有。 Linux programs the PIT of IBM-compatible PCs to issue timer interrupts on the IRQ 0 at a (roughly) 1000-Hz frequency that is, once every 1 millisecond. This time interval is called a tick。
总结下三个器件:1 RTC用于产生time and date 。2 TSC用于不断的循环累计每个cpu signal clock。3 PIT用于操作系统编程给程序以时钟中断。
在往下进行之前需要提及两个其他的硬件:
- High Precision Event Timer (HPET) ------- replace for PIT(未来一段时间内可能会完全替代),因为HPET有更好的可配置的功能,灵活了更多并且因为有自己的时钟,粒度非常的细,可以兼具TSC的功能.
- ACPI Power Management Timer ----- 因为CPU会因电压或操作系统调频而降低频率,从而TSC也会随之改变计数频率。但是ACPI PMT不会改变会比On the other hand, the high-frequency of the TSC counter is quite handy for measuringvery small time intervals。PMT的频率要低一些。
下面看Linux如何使用以上三种硬件呢?
OS提供TIME-FUNCTION的目的:
- The kernel uses two basic timekeeping functions: one to keep the current time up-to-date and another to count the number of nanoseconds that have elapsed within the current second.
OS中用于记录时钟中断数目的变量:
- jiffies -------- It is increased by one when a timer interrupt occurs, that is, on every tick. In the 80 x 86 architecture, jiffies is a
32-bit variable, therefore it wraps around in approximately 50 daysa relatively short time interval for a Linux server. - jiffies_64 ------ the kernel needs the real number of system ticks elapsed since the system boot。它的低32位是jiffies。With a tick of 1 millisecond, the jiffies_64 variable wraps around in several hundreds of millions of years, thus we can safely assume that it never overflows。
OS中用户用于得到date和time的变量:
- xtime ------- The xtime variable is usually updated once in a tick. that is, roughly 1000 times per second.user programs get the current time and date from the xtime variable. The kernel also often refers to it, for instance, when updating inode timestamps 。
每一次时钟中断都会更改这个时间,系统就是通过这个数据结构得到时间的。
struct timespec 结构有2个变量,tv_sec ---- 记录格林睨治时间的秒数。tv_nsec ----- 记录格林睨治时间的纳秒数(当前秒中过了多少纳秒了)。
TimeKeeping Achitecture in Uniprocessor System:
明日在写。。oh 哈哈,感觉都懂了。。
Initialization phase:
- Initialize the xtime variable ----- 设定tv_sec和tv_nsec。(注意每一次timer interrupt, tv_nsec 和 jiffies都会被更改, tv_nsec被加上相应的纳秒数, jiffies被加1)。
- Initializes the wall_to_monotonic variable -------- 暂时用不到。
- Invokes select_timer( ) to select the best timer source available in the system, and sets the cur_timer variable to the address of the corresponding timer object. ----------- select_timer( ) selects the HPET, if available; otherwise, it selects the ACPI Power Management Timer , if available, or the TSC. As the last resort, select_timer( ) selects the always-present PIT。--------- 这个cur_timer是用来取得更加精确的clock值的。具体看下面mask_offset。我可以先暂时理解为interrupt0是hpet, pit其中的一个触发的。
- Invokes setup_irq( 0,&irq0) to set up the interrupt gate corresponding to IRQ0the line
associated with the system timer interrupt source (PIT or HPET). ---------- 从这可看出,只有PIT or HPET是interrupt source.
The time interrupt handler:
- xtime_lock --------- Protects the time-related kernel variables by issuing a write_seqlock() on the xtime_lock seqlock.(关于seqlock后续再学习,先暂时认为是一个普通的锁)
- Executes the mark_offset methodof the cur_timer timer object. (主要目的是为了更加精确的计时)---------- 根据硬件的情况分为以下几种情况:
- HPET chip is the source of timer interrupts。
- The PIT chip is the source of timer interrupts, but the kernel uses the APIC Power Management Timer to measure time
with a finer resolution. - The PIT chip is the source of timer interrupts, but the kernel uses the Time Stamp Counter to measure time with a finer
resolution. - The PIT chip is the source of timer interrupts, and there is no other timer circuit.
分别不同的硬件,但是做的工作是类似的:
The mark_offset method checks that no timer interrupt has been lost since the last tick(关键1) in this unlikely case, it updates jiffies_64 accordingly. Next, the method records the current value of the counter(关键2:根据上面说的不同的硬件去取不同的counter)。 - Invokes the do_timer_interrupt( )function ---------
- Increases by one the value of jiffies_64.
- Invokes the update_times( ) function to update the system date and time and to compute the current system load;-------这里就是去更改xtime,具体的policy可以不用太关注。
- 然后....