`
love19820823
  • 浏览: 933914 次
文章分类
社区版块
存档分类
最新评论

《深入理解Linux内核》--第六章 定时测量:读书笔记

 
阅读更多

感想:1)linux内核给用户很多选择选项,为了兼容不同的硬件提供了多种选项,硬件定时器(HPET、TSC),软件定时器。
2)注意处理竞争条件(在多核情况下,会引入在单核情况下不存在的竞争条件,例如,定时器函数在【被删除函数】终止时可能在其他CPU上运行【和删除函数不在一个CPU上】,del_timer_sync()删除指定的定时器后,需要检查定时函数是否还在其他CPU上运行,如果是,则需要等到定时器函数结束) 。
3)在体系结构中分为 全局时钟 和 CPU本地时钟
4) 监管内核代码,依赖于eip寄存器的值,来揭示中断发生前内核在做什么。
5)看门狗的实现依赖于 非屏蔽中断(NMI),它们在每个CPU上产生周期性的NMI中断。
零、印象深的章节
用tv1,tv2,tv3,tv4,tv5将list_head元素分为在将来2^8-1,2^14-1, 2^20-1, 2^26-1和2^32-1时钟节拍内将要到期的所有动态定时器。(分而治之的思想)


一、全局时钟 和 CPU本地(强调的是CPU内部的,全局的是CPU外部)定时器
全局时钟:RTC、TSC、PIT
CPU本地定时器:HPET、ACPI PMT。
1)RTC:Linux只用RTC来获取时间和日期,可以通过/dev/rtc对设备文件进行操作,可以对RTC编程。
2)TSC:(64位)每个时钟信号到来时加1,其单位与时钟节拍频率有关,如果时钟节拍频率是1GHz,则单位是ns(即每1na增加1),是计数器(是在上电后工作,RTC可以在断电后工作,RTC有自己的电源)。calibrate_tsc()通过计算一个大约5ms的时间间隔内所产生的时钟信号的 个数 来算出 CPU实际频率。
3)PIT:作用是让用户意思到时间间隔已经过了。 通常使用0X40 ~ 0x43 I/O端口的一个8254CMOS芯片。
-----------------------------------
4)HPET:
5)ACPI PMT:时钟信号频率大约--3.58MHz。每个时钟节拍到来时增加一次。

二、常用数据结构
1)定时器对象:timer_opt
{ name,
mark_offset, 上一个节拍的准确时间
get_offset, 上一个节拍开始经过的时间
monotonic_clock, 纳秒数
delay
}
2)jiffies (32位)变量 (Jiffy,英文:瞬间)
系统启动后每次时钟节拍加1(大约50天会回绕wraparound到 0)。
初始化为0xfffb6c20,(-300 000)。大约5分钟内能益出,目的是检查有缺陷的(不能对jiffies作溢出检测)内核代码。
unsigned long long get_jiffies_64(void)
{
unsigned long seq;
unsigned long long ret;
do{
seq=read_seqbegin(&xtime_lock);
ret=jiffies_64;
}while(read_seqretry(&xtime_lock,seq));
return ret;
}
void update_times(void)
{
unsigned long ticks;
ticks= jiffies –wall_jiffies; //wall_jiffies变量存储的xtime变量最后更新时间
if(ticks){
wall_jiffies +=ticks;
update_wall_time
}
calc_load(ticks);
}
3)xtime 变量
保存当前时间和日期,timespec类型的数据结构{tv_sec,tv_nsec}。

三、记录系统负载
1)监管内核代码(readprofiler)
为了确定内核的“热点”hot spot。,内核从堆栈取回中断发生前的eip寄存器的值,用这个值揭示中断发生前内核正在做什么。
内核启动时“profile=N”,2^N表示要监管代码的大小。
/proc/profile中保存采集的数据。
2)检查NMI监视器
四、动态定时器和 间隔定时器
两种类型定时器:动态定时器(只能由内核使用),间隔定时器(可以由进程在用户态创建)
1)动态定时器
struct timer_list{
struct list_head entry;
unsigned long expires; 定时器到期时间
spinlock_t lock;
unsigned long magic;
void (*function) (unsigned long); 定时器到期执行函数的地址
unsigned long data; 传递给定时器函数的参数 (可以存放设备ID,实现处理多个设备驱动程序的超时问题)
tvec_base_t * base;
}
del_singleshot_timer_sync()函数不能重新激活
typedef struct tvec_t_base_s {
spinlock_t lock;
unsigned long timer_jiffies;
struct timer_list *running_timer;
tvec_root_t tv1; 将来 2^8-1 节拍
tvec_t tv2; 2^14-1
tvec_t tv3; 2^20-1
tvec_t tv4; 2^26-1
tvec_t tv5; 2^32 -1
}tvec_base_t;

if(!index && (!cascade(base, &base->tv2,(base->timer_jiffies>>8)&63)) &&
//将tv2中的所有动态定时器移到base->tv1适当的链表上。
(!cascade(base, &base->tv3,(base->timer_jiffies>>14)&63)) &&
(!cascade(base, &base->tv4,(base->timer_jiffies>>20)&63)) )
cascade(base, &base->tv5,(base->timer_jiffies>>26)&63);

2)延迟函数
udelay()和ndelay()
gettimeofday()
nanosleep()

英文简写含义:
RTC(Real Time Clock),实时时钟。
TSC(Time Stamp Counter),时间戳计数器
PIT(Programmab Interval Timer),可编程间隔定时器
HPET(High Precision Event Timer),高精度事件定时器
ACPI PMT(Advanced Configuration & Power Interface Power Management Timer),ACPI电源管理定时器
APIC(Advanced Programmable Interrupt Controller)
NMI(Non Masked Interrupt) 非屏蔽中断
SMP(Symmetric multiprocessing

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics