《最新四Linux内核时钟幻灯片》由会员分享,可在线阅读,更多相关《最新四Linux内核时钟幻灯片(26页珍藏版)》请在金锄头文库上搜索。
1、四四Linux内核时钟内核时钟1 1 时钟与定时器时钟与定时器A Linux system actually has two clocks: One is the battery powered Real Time Clock (also known CMOS clock, or Hardware clock) which keeps track of time when the system is turned off but is not used when the system is running.The other is the system clock (sometimes cal
2、led the kernel clock or software clock) which is a software counter based on the clock tick. It does not exist when the system is not running, so it has to be initialized from the RTC (or some other time source) at boot time. 2. Linux系统时钟的实现系统时钟的实现相关的数据结构及变量: include/include/linuxlinux/ /xtimextime.
3、h.h struct timeval time_t tv_sec;subseconds_t tv_usec; ; Tick:时钟中断周期。 初值=(1000000+HZ/2)/HZ Xtime:保存系统当前时间的结构体变量。 Jiffies:系统启动以来的时钟滴答数。相关的数据结构及变量: wall_jiffies:每次bottom half时用来记 录当前jiffies的变量. TSC:保存CPU的ticks数目.系统时钟初始化:arch/i386/kernel/time.carch/i386/kernel/time.c调用get_cmos_time()函数从cmos中读取硬件时钟赋给tv_
4、sec,初始化 tv_usec 为0。调用setup_irq()重新设置时钟中断irq0的中断服务程序入口。系统时钟的运行:时钟中断发生时,中断服务程序实际上是依靠do_timer()函数来完成其必须完成的工作; do_timer() 进一步调用update_times函数来更新系统时间,调用run_timer_list函数来检查、执行定时服务,即在bottom half中完成。系统时钟的设置和调整:系统调用sys_time;/读取,秒级sys_stime;/设置,秒级sys_gettimeofday;/读取,微秒级sys_settimeofday;/设置,微秒级sys_adjtimex;/调
5、整,主要用于网络和分布式系统。时间的准确读取时间的准确读取: 最近一次bottom half运行的时间值xtime+ 从最近一次bottom half到最近一次时钟中断的间隔(jiffies- wall_jiffies)+最近一次时钟中断到当前的时间间隔usec 3. Linux定时器的实现定时器的实现数据结构数据结构:链表节点include/linux/timer.h struct timer_list struct list_head list; unsigned long expires;/定时器的激活时刻 unsigned long data;/函数的参数 void(*function
6、)(unsigned long);/执行函数 链表结构体kernel/timer.c struct timer_vec int index;/定时器链表索引,指向当前要响应的链表。 struct list_head vecTVN_SIZE;/定时器链表数组 ;/ TVN_SIZE=64根链表结构体: struct timer_vec_root int index;/定时器链表索引,指向当前要响应的链表。 struct list_head vecTVR_SIZE;/定时器链表数组 ;/ TVN_SIZE=256定义数组tvecs的5个成员管理定时器链表:static sturct timer_v
7、ec tv5;static sturct timer_vec tv4;static sturct timer_vec tv3;static sturct timer_vec tv2;static sturct timer_vec_root tv1;static struct timer_vec * const tvecs = (struct timer_vec *)&tv1,&tv2,&tv3,&tv4,&tv5;IndexVec0IndexVec0VecindexVecindextvecsTimer_listTimer_listTimer_listTimer_listtv3tv4tv5Tim
8、er_list型定时器体系结构型定时器体系结构tv1tv2可以采用以下的假定:Tv1 分Tv2 时Tv3 日Tv4 月Tv5 年实现机制实现机制: 定时器升序排列,在时钟中断的bottom_half检查当前节点是否到时。实现:实现: 由5个定时器数组形成树形链表结构加以实现。 -初始化:根据用户空间得到的数据设置初值 并将设定好的定时器挂到链表上。 -运行:判断时间到达,由run_timer_list() 检查并执行定时服务。run_timer_list()run_timer_list()函数的实现思想:函数的实现思想:1 首先判断tv1.index的值。如果非0,则激活定时器,递增timer
9、_jiffies和tv1.index,使tv1.vectv1.index指向下一个时钟中断服务处理的链表;否则转2。2 tv1.index=0,即tv1为空,调用cascade_timers(tvecs1), 从tvecx1 (tv2)搬一组链表,分散插入tvecs0(tv1)的各个链表,如果tvecx1为空,则从tvecx2(tv3)搬来一组链表,分散插入tvecx0(tv1), tvecx1(tv2)的各个链表中对于定时器的操作:对于定时器的操作:1 添加add_timer()2 修改先调用detach_timer()将定时器从链表上取下,修改时间后再调用 internal_add_tim
10、er()将定时器从新挂接到链表上。3 删除del_timer()4. Linux定时器的应用例定时器的应用例例:例:设置一个ITIMER_REAL类型的定时器,每秒发出一个信号,等到定时到达时,程序统计经过的时间。#include #include #include Static void sig_handler(int signo);/声明信号量函数声明信号量函数Long lastsec,countsec;/上一秒时间,总的时间花销Int main(void)struct itimerval v;/定时器结构体 long nowsec,nowusec;/当前时间 if(signal(SIGU
11、SR1,sig_handler)=SIG_ERR) printf(“Unable to create handler for SIGUSR1n”);exit(0); if(signal(SIGALRM,sig_handler)=SIG_ERR) printf(“Unable to create handler for SIGALRMn”);exit(0); v.it_interval.tv_sec=9;v.it_interval.tv_usec=999999;v.it_value.tv_sec=9;v.it_value.tv_usec=999999;/初始化setitimer(ITIMER_R
12、EAL,&v,NULL);lastsec=v.it_value.tv_sec;countsec=0;/设置定时器,并挂接到链表上。while(1)getitimer(ITIMER_REAL,&v);nowsec=v.it_value.tv_sec;nowusec=v.it_value.tv_usec;if(nowsec=lastsec-1)raise(SIGUSR1);/每过1秒,产生一个信号lastsec=nowsec;countsec+;/信号处理函数,根据不同的信号,输出不同的信息。Static void sig_handler(int signo) switch(signo) case SIGUSER1: printf(“One second passedn”); break; case SIGALRM: printf(“Timer has been zero, elapsed %d secondn”,countsec); lastsec=countsec; countsec=0; break; 结束语结束语谢谢大家聆听!谢谢大家聆听!26