linux内核时间函数us,linux内核中一个有趣的函数calibrate_delay ZZ

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

34    loops_per_sec &=~loopbit;

35  }

36 /* finally,adjust loops per second in terms of seconds

37 * instead of clocks */

38  loops_per_sec *= HZ;

39 /* Round the value and print it */

40  printk(“%lu.%02lu BogoMIPSn”,

41   (loops_per_sec+2500)/500000,

42   ((loops_per_sec+2500)/5000) % 100);

43 }

对calibrate_delay()函数分析如下:

1 定义计算BogoMIPS的精度,这个值越大,则计算出的BogoMIPS越精确。

7 loops_per_sec为每秒钟执行一个极短的循环的次数。

9 printk()是内核消息日志打印函数,用法同printf()函数。

10 第10至21行,是第一次计算loops_per_sec的值,这次计算只是一个粗略的计算,为下面的计算打好基础。

11 第11 至16行,是用于等待一个新的定时器滴答(它大概是百万分之一秒)的开始。可以想象我们要计算loops_per_sec的值,可以在一个滴答的开始时,立即重复执行一个极短的循环,当一个滴答结束时,这个循环执行了多少次就是我们要求的初步的值,再用它乘以一秒钟内的滴答数就是loops_per_sec的值。

12 系统用jiffies全局变量记录了从系统开始工作到现在为止,所经过的滴答数。它会被内核自动更新。这行语句用于记录当前滴答数到tick变量中。

13 注意这是一个没有循环体得空循环,第14行仅有一个“;”号。这条循环语句是通过判断tick的值与jiffies的值是否不同,来判断jiffies是否变化,即是否一个新的滴答开始了

16 记录下新的滴答数以备后用。

17 根据loops_per_sec值进行延时(及执行loop_per_sec次极短循环)。

18 以下三行用于判断执行的延时是否超过一个滴答。一般loops_per_sec的初始值并不大,所以循环会逐步加大loops_per_sec的值,直到延时超过一个滴答。我们可以看出,前一次loops_per_sec的值还因太小不合适时,经过一次增大,它提高了两倍,满足了循环条件,跳出循环,而这个值实在是误差太大,所以我们还要经过第二次计算。这里还要注意的是通过上面的分析,我们可以知道更加精确的loops_per_sec的值应该在现在的值与它的一半之间。

23 这里开始就是第二次计算了。它用折半查找法在我们上面所说的范围内计算出了更精确的loops_per_sec的值。

25 义查找范围的最小值,我把它称为起点。

26 定义查找范围,这样我们就可以看到loop_per_sec的值在“起点”与“起点加范围(终点)”之间。

27 进入循环,将查找范围减半。

28 重新定义起点,起点在“原起点加27行减半范围”处,即新起点在原先起点与终点的中间。这时我们可以看出loops_per_sec在“新起点”与“新起点加减半范围(新终点)”之间。

29 第29至32行与第12至17行一致,都是等待新的滴答,执行延时。

33 如果延时过短,说明loops_per_sec的值小了,将会跳过这部分,再次进入循环。它将是通过不断的折半方式来增大。如果延时过长,说明loops_per_sec的值大了,将起点重新返回原起点,当再次进入循环,由于范围减半,故可以达到减小的效果。

38 计算出每秒执行极短循环的次数。从这里我们可以看出它好像是个死循环,所以加入了lps_precision变量,来控制循环,即LPS_PREC越大,循环次数越多,越精确。可能这些不太好懂,总的说来,它首先将loop_per_sec的值定为原估算值的1/2,作为起点值(我这样称呼它),以估算值为终点值.然后找出起点值到终点值的中间值.用上面相同的方法执行一段时间的延时循环.如果延时超过了一个tick,说明loop_per_sec值偏大,则仍以原起点值为起点值,以原中间值为终点值,以起点值和终点值的中间为中间值继续进行查找,如果没有超过一个tick,说明loop_per_sec偏小,则以原中间值为起点值,以原终点值为终点值继续查找。

40 出BogoMIPS,并打印。

至此,我们就分析完了calibrate_delay()函数。你从中学到了什么没有?如果你还有什么不明白的地方,可以给我发Email,如果你认为有什么更好的方法,欢迎来信我们一同探讨,我的Email是:feixiangniao@sina.com。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值