linux高精度时钟分析(Linux high-precision clock analysis)
linux高精度时钟分析(Linux high-precision clock analysis)
********************************************
蛐蛐
/
MSN:qgjie@
本文适用于
linux-
V 0.1
欢迎转载,但请保留作者信息
********************************************
一、数据结构分析
结构hrtimer_clock_base {
结构hrtimer_cpu_base * cpu_base;
clockid_t指数;
结构rb_root活跃;
结构rb_node *第一;
ktime_t分辨率;
ktime_t(* get_time)(void);
ktime_t(* get_softirq_time)(void);
ktime_t softirq_time;
# ifdef config_high_res_timers
ktime_t偏移;
int(*编程)(struct hrtimer * T,
结构hrtimer_clock_base * B,
ktime_t N);
# endif
};
结构hrtimer_cpu_base {
spinlock_t锁;
结构lock_class_key lock_key;
结构hrtimer_clock_base clock_base [ hrtimer_max_clock_bases ];
# ifdef config_high_res_timers
ktime_t expires_next;
国际hres_active;
结构list_head cb_pending;
无符号长nr_events;
# endif
};
kernel-2.6.22中的臂拱加入了对dynticks,时钟/事件支持。找了些内核
及子系统近来的变化时钟定时器,总结一下。
一般来说软定时器(定时器轮/ hrtimer)
都是由硬件定时器(时钟中断之类)以及相关的时钟源(例如GPT驱动SOC),
所以我打算先从时钟这层开始介绍,接着是软定时器,内核计时,
最后来看一些应用。
时钟源
时钟源定义了一个时钟装置的基本属性及行为,这些时钟装置一般都有计数,
定时,产生中断能力,比如GPT。结构定义如下:
struct {时钟
char *名称;
结构list_head列表;
国际评级;
cycle_t(阅读)(void);
cycle_t面具;
U32多;/*周期-> xtime区间,也许两个时钟周期触发一个
中断(一个xTime区间)* /
U32移;
无符号长标志;
cycle_t(* Vread)(void);
无效(*简历)(无效);
* *计时具体数据,忽略*
cycle_t cycle_interval;/*只是GPT计数每个操作系统时的速度
u64 xtime_interval;/* xtime_interval = cycle_interval *多。* /
cycle_t cycle_last ____cacheline_aligned_in_smp;/*最后率数*周期/
u64 xtime_nsec;
/ *盘点,仍然从xtime.tv_nsec
*现在纳秒数偏移率= xtime_nsec +
* xtime.tv_nsec <
S64误差;
};
最重要的成员是read(),cycle_last和cycle_interval。分别定义了读取计数时钟装置
寄存器当前计数值接口,保存上一次周期计数值和每个蜱周期间隔值。这个结构内的值,
无论是cycle_t,还是u64类型(实际cycle_t就是u64)都是计数值(周期),而不是纳秒,
SEC和jiffies。read()是整个内核读取精确的单调时间计数的接口,
核会用它来计算其他时间,比如:jiffies,xtime。
的引入时钟,解决了之前内核各个拱都有自己的时钟装置的管理方式,
基本都隐藏在MSL层,核心及司机很难访问的问题。它导出了以下接口:
1)clocksource_register()注册时钟
2)clocksource_get_next()获取当前设备时钟
3)clocksource_read()读取时钟,时钟实际跑到-> read()
当司机处理的时间精度比较高的时,可以通过上面的接口,直接拿时钟装置来读。
当然目前股票时钟中断源也会以的形式存在时钟。
时钟事件
时钟事件的主要作用是分发时钟事件及设置下一次触发条件。在没有时钟事件之前,
时钟中断都是周期性地产生,也就是熟知的jiffies和赫兹。
时钟事件设备主要的结构:
结构clock_event_device {
常量char *名称;
无符号整型特征;
无