您好,欢迎访问三七文档
系统软件课程设计时钟中断与进程调度学号11070319姓名许明秀指导教师金雪云2013年12月一、报告摘要进程调度是操作系统十分重要的一个部分。在操作系统的设计过程中,进程调度和时钟中断形成了密不可分的关系。系统时钟、定时器的实现和进程调度,共同合作,实现了操作系统的有关功能。二、关键词操作系统、系统时钟、时钟中断、定时器、任务队列、进程调度三、引言进程调度是CPU处理多进程并发执行所必须的步骤,而和进程调度紧密相关的是时间中断,其中涉及到系统时钟的初始化和定时器的相关知识。课设进行过程中,采用分工方式,每人负责一部分内容,在每人阅读代码的过程中,若存在相互调用的关系,则合在一起共同完成代码阅读。分工如下:系统时钟(time.c)许明秀定时器(timer.c)胡建进程调度(sched.c)彭春华四、任务分配与代码分析4.1系统时钟的实现4.2.1内核机制原理分析时间在一个操作系统内核中占据着重要的地位,它是驱动一个OS内核运行的“起博器”。一般说来,内核主要需要两种类型的时间:1.在内核运行期间持续记录当前的时间与日期,以便内核对某些对象和事件作时间标记(timestamp,也称为“时间戳”),或供用户通过时间syscall进行检索。2.维持一个固定周期的定时器,以提醒内核或用户一段时间已经过去了。PC机中的时间是有三种时钟硬件提供的,而这些时钟硬件又都基于固定频率的晶体振荡器来提供时钟方波信号输入。这三种时钟硬件是:(1)实时时钟(RealTimeClock,RTC);(2)可编程间隔定时器(ProgrammableIntervalTimer,PIT);(3)时间戳计数器(TimeStampCounter,TSC)。1时钟硬件1.1实时时钟RTC自从IBMPCAT起,所有的PC机就都包含了一个叫做实时时钟(RTC)的时钟芯片,以便在PC机断电后仍然能够继续保持时间。显然,RTC是通过主板上的电池来供电的,而不是通过PC机电源来供电的,因此当PC机关掉电源后,RTC仍然会继续工作。通常,CMOSRAM和RTC被集成到一块芯片上,因此RTC也称作“CMOSTimer”。最常见的RTC芯片是MC146818(Motorola)和DS12887(maxim),DS12887完全兼容于MC146818,并有一定的扩展。本节内容主要基于MC146818这一标准的RTC芯片。具体内容可以参考MC146818的Datasheet。1.2可编程间隔定时器PIT每个PC机中都有一个PIT,以通过IRQ0产生周期性的时钟中断信号。当前使用最普遍的是Intel8254PIT芯片,它的I/O端口地址是0x40~0x43。Intel8254PIT有3个计时通道,每个通道都有其不同的用途:(1)通道0用来负责更新系统时钟。每当一个时钟滴答过去时,它就会通过IRQ0向系统产生一次时钟中断。(2)通道1通常用于控制DMAC对RAM的刷新。(3)通道2被连接到PC机的扬声器,以产生方波信号。每个通道都有一个向下减小的计数器,8254PIT的输入时钟信号的频率是1193181HZ,也即一秒钟输入1193181个clock-cycle。每输入一个clock-cycle其时间通道的计数器就向下减1,一直减到0值。因此对于通道0而言,当他的计数器减到0时,PIT就向系统产生一次时钟中断,表示一个时钟滴答已经过去了。当各通道的计数器减到0时,我们就说该通道处于“Terminalcount”状态。通道计数器的最大值是10000h,所对应的时钟中断频率是1193181/(65536)=18.2HZ,也就是说,此时一秒钟之内将产生18.2次时钟中断。1.3时间戳记数器TSC从Pentium开始,所有的Intel80x86CPU就都又包含一个64位的时间戳记数器(TSC)的寄存器。该寄存器实际上是一个不断增加的计数器,它在CPU的每个时钟信号到来时加1(也即每一个clock-cycle输入CPU时,该计数器的值就加1)。汇编指令rdtsc可以用于读取TSC的值。利用CPU的TSC,操作系统通常可以得到更为精准的时间度量。假如clock-cycle的频率是400MHZ,那么TSC就将每2.5纳秒增加一次。不同的操作系统,RTC和OS时钟的关系是不同的。RTC和OS时钟之间的关系通常也被称作操作系统的时钟运作机制。一般来说,RTC是OS时钟的时间基准,操作系统通过读取RTC来初始化OS时钟,此后二者保持同步运行,共同维持着系统时间。linux时钟机制Linux中的时钟运作机制如图所示。OS时钟和RTC之间要通过BIOS的连接,是因为传统PC机的BIOS中固化有对RTC进行有关操作的函数,例如INT1AH等中断服务程序,通常操作系统也直接利用这些函数对RTC进行操作,例如从RTC中读出有关数据对OS时钟初始化、对RTC进行更新等等。实际上,不通过BIOS而直接对RTC的有关端口进行操作也是可以的。Linux中在内核初始化完成后就完全抛弃了BIOS中的程序。我们可以看到,RTC处于最底层,提供最原始的时钟数据。OS时钟建立在RTC之上,初始化完成后将完全由操作系统控制,和RTC脱离关系。操作系统通过OS时钟提供给应用程序所有和时间有关的服务。因为OS时钟完全是一个软件问题,其所能表达的时间由操作系统的设计者决定,将OS时钟定义为整型还是长整型或者大的超乎想象都是设计者的事。Linux时间基准以上我们了解了RTC(实时时钟、硬件时钟)和OS时钟(系统时钟、软时钟)。下面我们具体描述OS时钟。我们知道,OS时钟是由可编程定时/计数器产生的输出脉冲触发中断而产生的。输出脉冲的周期叫做一个“时钟滴答”,有些书上也把它叫做“时标”。计算机中的时间是以时钟滴答为单位的,每一次时钟滴答,系统时间就会加1。操作系统根据当前时钟滴答的数目就可以得到以秒或毫秒等为单位的其他时间格式。不同的操作系统采用不同的“时间基准”。定义“时间基准”的目的是为了简化计算,这样计算机中的时间只要表示为从这个时间基准开始的时钟滴答数就可以了。“时间基准是由操作系统的设计者规定的。例如DOS的时间基准是1980年1月1日,Unix和Minux的时间基准是1970年1月1日上午12点,Linux的时间基准是1970年1月1日凌晨0点。Linux的时间系统通过上面的时钟运作机制,我们知道了OS时钟在Linux中的重要地位。OS时钟记录的时间也就是通常所说的系统时间。系统时间是以“时钟滴答”为单位的,而时钟中断的频率决定了一个时钟滴答的长短,例如每秒有100次时钟中断,那么一个时钟滴答的就是10毫秒(记为10ms),相应地,系统时间就会每10ms增1。不同的操作系统对时钟滴答的定义是不同的,例如DOS的时钟滴答滴答为1/18.2s,Minix的时钟滴答为1/60s等等。时钟中断的产生前面我们看到,Linux的OS时钟的物理产生原因是可编程定时/计数器产生的输出脉冲,这个脉冲送入CPU,就可以引发一个中断请求信号,我们就把它叫做时钟中断。“时钟中断”是特别重要的一个中断,因为整个操作系统的活动都受到它的激励。系统利用时钟中断维持系统时间、促使环境的切换,以保证所有进程共享CPU;利用时钟中断进行记帐、监督系统工作以及确定未来的调度优先级等工作。可以说,“时钟中断”是整个操作系统的脉搏。时钟中断的物理产生如图所示:操作系统对可编程定时/计数器进行有关初始化,然后定时/计数器就对输入脉冲进行计数(分频),产生的三个输出脉冲Out0、Out1、Out2各有用途,很多接口书都介绍了这个问题,我们只看Out0上的输出脉冲,这个脉冲信号接到中断控制器8259A_1的0号管脚,触发一个周期性的中断,我们就把这个中断叫做时钟中断,时钟中断的周期,也就是脉冲信号的周期,我们叫做“滴答”或“时标”(tick)。从本质上说,时钟中断只是一个周期性的信号,完全是硬件行为,该信号触发CPU去执行一个中断服务程序4.2.2数据结构与变量说明1、结构体Xtime在头文件include/linux/time.h中structtimeval{time_ttv_sec;/*seconds*/suseconds_ttv_usec;/*microseconds*/};其中,成员tv_sec表示当前时间距UNIX时间基准的秒数值,而成员tv_usec则表示一秒之内的微秒值,且1000000tv_usec=0。Linux内核通过timeval结构类型的全局变量xtime来维持当前时间,该变量定义在kernel/timer.c文件中,如下所示:/*Thecurrenttime*/volatilestructtimevalxtime__attribute__((aligned(16)));structirqactionirq0时钟中断结构体2、宏定义:HZ节拍率时钟滴答的频率(HZ):也即1秒时间内PIT所产生的时钟滴答次数。在#includelinux/param.h中设置2.5版本前,时钟中断频率为100Hz一次时钟滴答的具体时间间隔应该是(1000ms/HZ)=10ms。#defineTICK_SIZEtick宏TICK_SIZE来作为tick变量的引用别名Linux用全局变量tick来表示时钟滴答的时间间隔长度tick=(1000000+HZ/2)/HZ其中被除数表达式中的HZ/2的作用就是用来将tick值向上圆整成一个整型数。#ifndefCONFIG_X86_TSC表示是否存在TSC寄存器。CLOCK_TICK_RATE1s内时钟周期个数LATCH定义要写到PIT通道0的计数器中的值,它表示PIT将没隔多少个时钟周期产生一次时钟中断锁:xtime_lock相对时间锁,保证进程对xtime修改的互斥性rtc_lockrtc锁,保证进程对rtc操作的互斥,初始未锁i8253_lock计数器8253锁,初始未锁i8259A_lock中断8259A锁rtc_lock实时时钟RTC锁,用于保证操作RTC互斥3、主要变量cpu_khz系统时钟频率delay_at_last_interrupt中断服务执行延迟delay_at_last_interrupt:由于从产生时钟中断的那个时刻到内核时钟中断服务函数timer_interrupt真正在CPU上执行的那个时刻之间是有一段延迟间隔的,因此,Linux内核用变量delay_at_last_interrupt来表示这一段时间延迟间隔.last_tsc_low表示中断服务timer_interrupt真正在CPU上执行时刻的TSC寄存器值的低32位(LSB)。fast_gettimeoffset_quotient1个TSC计数值代表多长的时间间隔jiffies表示自内核上一次启动以来的时钟滴答次数。每发生一次时钟滴答,内核的时钟中断处理函数timer_interrupt()都要将该全局变量jiffies加1。wall_jiffies保存内核上一次更新xtime时的jiffies值xtime表示当前时间距UNIX时间基准1970-01-0100:00:00的相对秒数值last_rtc_update表示内核最近一次成功地对RTC进行更新的时间(单位是秒数)。timer_ack时间中断申请use_tsc表示内核是否使用CPU的TSC寄存器4.2.3函数组织流程及功能do_fast_gettimeoffset通过TSC寄存器来计算do_fast_gettimeoffset()函数被执行的时刻到上一次时钟中断发生时的时间间隔值do_slow_gettimeoffset在无TSC的情况下计算函数被执行的时刻到上一次时钟中断发生时的时间间隔值do_gettimeofday完成实际的当前时间检索工作,精确地修正xtime的值do_settimeofday把tv的时间设定为系统时间set_rtc_mmss向RTC中回写当前时间与日期,该函数用来更新RTC中的时间do_timer_interrupt中断服务
本文标题:课程设计报告
链接地址:https://www.777doc.com/doc-4822798 .html