时钟丢了,vivox9丢了怎么找回回

您所在的位置: &
找回遗失的时钟中断
找回遗失的时钟中断
河秦/王洪涛
人民邮电出版社
《Linux 2.6内核标准教程》第6章时间度量,这一章围绕墙上时间xtims和相对时间jiffies两个主体进行阐述,从硬件支持到软件架构;从时间度量模块的初始化到如何使用时间度量的工作机制;从软件定时器的使用到软件定时器的工作原理。本小节分析函数mark_offset_tsc()如何找回遗失的时钟中断。
6.4.1& 找回遗失的时钟中断
本小节分析函数mark_offset_tsc()如何找回遗失的时钟中断。由于该函数很长且夹杂了冗长的注解,为了避免在正文中包含大量无用的信息,只摘出该函数中相关的代码段进行分析。读者有兴趣可以自行查看原来的函数。
代码清单6.11--函数mark_offset_tsc
功能简介:该函数负责判断此次时钟中断处理之前,是否有产生的时钟中断而没有进行中断处理的情况,并找回丢失的时钟中断。
文件:src/arch/i386/kernel/timers/timer_tsc.c
347& static void mark_offset_tsc(void)348& {349&&&&&& unsigned long lost,350&&&&&& unsigned long delta = last_tsc_略去不相关代码 373&&&&&& rdtsc(last_tsc_low, last_tsc_high);374& 375&&&&&& spin_lock(&i8253_lock);376&&&&&& outb_p(0x00, PIT_MODE);&&/* latch the count ASAP */377& 378&&&&&& count = inb_p(PIT_CH0);&&/* read the latched count */379&&&&&& count |= inb(PIT_CH0) && 8;略去不相关代码392&&&&&& spin_unlock(&i8253_lock); 略去不相关代码409&&&&&& delta = last_tsc_low -410&&&&&& {411&&&&&&&&&&& register unsigned long eax,412&&&&&&&&&&& eax =413&&&&&&&&&&& __asm__("mull %2"414&&&&&&&&&&& :"=a" (eax), "=d" (edx)415&&&&&&&&&&& :"rm" (fast_gettimeoffset_quotient),416&&&&&&&&&&& "0" (eax));417&&&&&&&&&&& delta =418&&&&&& }419&&&&&& delta += delay_at_last_420&&&&&& lost = delta/(1000000/HZ);421&&&&&& delay = delta%(1000000/HZ);422&&&&&& if (lost &= 2) {423&&&&&&&&&&& jiffies_64 += lost-1; 略去不相关代码440&&&&&& } 略去不相关代码448&&&&&& count = ((LATCH-1) - count) * TICK_SIZE;449&&&&&& delay_at_last_interrupt = (count + LATCH/2) / LATCH;450& 451&&&&&& /* catch corner case where tick rollover occured452&&&&&&& * between tsc and pit reads (as noted when453&&&&&&& * usec delta is & 90% # of usecs/tick)454&&&&&&& */455&&&&&& if (lost && abs(delay - delay_at_last_interrupt) & (900000/HZ))456&&&&&&&&&&& jiffies_64++;457& }
第350行保存静态变量last_tsc_low的值到无符号变量delta中。静态变量last_tsc_low记录了上次系统时钟中断时时间戳计数器低32位的值,静态变量last_tsc_high纪录了上次系统时钟中断时时间戳计数器高32位的值。
第373行代码通过宏定义rdtsc()将时间戳计数器的高32位、低32位分别保存到变量last_tsc_high、last_tsc_low中。该宏定义在文件src/include/asm-i386/msr.h中的第65行开始定义,代码如下:
#define rdtsc(low,high)&&&&&&&&&\__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
该宏定义使用汇编指令rdtsc来读取时间戳计数器的值,分别将高32位、低32位保存到寄存器%edx、%eax中,然后再将这两个寄存器的值保存到变量high和low中。
第375~392行代码首先获得保护8254可编程定时器的自选锁,然后锁住该定时器的计数器,使其不再随输入晶振的脉冲而变化。再分两步分别读取可编程定时器中0号通道计数器当前值的低8位、高8位,并把低、高8位拼成的值保存到变量count中。可以看出(LATCH-count)的值表示8254可编程定时器产生时钟中断请求到系统处理该中断请求的间隔内通道计数器的变化值,该值用于计算产生此次时钟中断请求到系统响应这一中断的延迟。
第409行代码计算出上次时钟中断中断处理至此次时钟中断中断处理期间时间戳计数器增量,并将该增量保存到变量delta中。该增量是判断是否有时钟中断遗失的基础。
第410~418行代码根据第409行获得的时间戳计数器增量delta,算出该增量代表的时间间隔(单位为微秒),然后再将该时间间隔保存到变量delta中。其中变量fast_gettimeoffset_quotient表示时间戳计数器进行一次计数的快慢,该值的含义由下面的公式表示。
&×(1/一微秒内时间戳计数器所能达到的计数值)
具体的值在系统初始化过程中由函数calibrate_tsc()测定。该公式中498)this.width=498;' onmousewheel = 'javascript:return big(this)' height=23 alt="" src="/files/uploadimg/656942.jpg" width=30 border=0>的系数由于在内联汇编计算中只取了乘积结果的高32位而被抵消。经过这段代码处理后,变量delta保存上次时钟中断处理到这次时钟中断处理的时间,单位为微秒。
第419~421行代码首先在变量delta上加上上次时钟中断处理时的延迟量delay_ at_last_interrupt,然后计算delta代表的时间段内所能发生时钟中断的次数,并将该次数的值保存到变量lost中,将delata中不足发生一次时钟中断的时间保存在变量delay中,单位仍为微秒。
第422~440行代码首先根据lost的值判断是否真的发生了时钟中断遗失。如果lost的值为0,则什么都不用处理;如果lost的值大于或等于2,那么一定发生了时钟中断的遗失。此时将遗失的时钟中断次数(lost?1)添加到系统核心变量jiffies_64中。lost中剩余的1目前还不确定是否代表了时钟中断遗失,需要后面的进一步判断。
第448~449行代码用于计算8254可编程定时器产生时钟中断请求到系统处理该中断请求的间隔内通道计数器的变化值所代表的实际时间。单位为微秒,我们称这段时间为时钟中断的响应时间。该时间保存在变量delay_at_last_interrupt中。
第455~456行代码处理判断lost中剩余的1或lost的值本来就是1的情况。首先判断这种情况是否代表时钟中断的遗失,如果是,则将变量jiffies_64的值加1;否则不做处理。这里将判断条件改变一下形状以帮助理解,如图6.7所示。
图6.7& 时钟遗失判断条件其中delay、delay_at_last_interrupt的单位是微秒。分母106/HZ表示了一个时钟中断间隔的所跨过的时间长度,单位为微秒。可知该条件表示这两个差值所代表的时间段是否大于0.9倍的时钟中断间隔。【责任编辑: TEL:(010)】&&&&&&
关于&&&&&&的更多文章
Linux系统的魅力之一就是你可以直接从终端使用命令行来管理整个
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
讲师: 5人学习过讲师: 17人学习过讲师: 16人学习过
《移动互联网O2O社群微营销--移动互联网销售业绩提升
《物流江湖自我修炼之道--一位物流经理人的精益职场实
《从0 到1 教你做微商》记录了微商行业的萌芽与发展,
本书虽然是《网管员必读―网络应用》的改版,但它绝不是简单的修改,而是完完全全的重写,内容更实用、更专业。全书共9章,13个
51CTO旗下网站}

我要回帖

更多关于 苹果手机丢了怎么找回 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信