好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

操作系统课程设计内核定时器.docx

9页
  • 卖家[上传人]:gg****m
  • 文档编号:215497377
  • 上传时间:2021-11-25
  • 文档格式:DOCX
  • 文档大小:68.50KB
  • / 9 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 学号:0121110680课程设计题目内核定时器学院计算机学院专业软件工程班级姓名指导教师刘军2013 年课程设计任务书学生姓名: 专业班级: 软件zyllOl指导教师: 刘军 工作单位:计算机科学与技术学院题目:内核定时器初始条件:1操作系统:Linux或者windows2程序设计语言:C, java语言要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1. 技术要求:1) 分析操作系统内核源码2) 研究内核的时间管理算法3) 建立一种用户空间机制来测量一个多线程程序的执行时间2. 设计说明书内容要求:1) 设计题目与耍求2) 总的设计思想及系统平台、语言、工具等3) 数据结构与模块说明(功能与流程图)4) 给出用户名、源程序名、日标程序名和源程序及其运行结果要注明存储各个程序及其运行结果的主机IP地址和目录5)运行结呆与运行情况(提示:(1)编译命令可用: CC(2)多线程编程方法参见附件・ lpthread■0H标文件名 源文件名3. 调试报告:1) 调试记录2) 口我评析和总结上机时间安排:19周一〜五下午14: 00 一 18: 00指导教师签名:年月日系主任(或责任教师)签名:年口摘要:每个正在系统上运行的程序都是一个进程。

      每个进程包含一到多个线程进程也可能是 整个程序或者是部分程序的动态执行线程是一组指令的集合,或者是程序的特殊段,它 可以在程序里独立执行也可以把它理解为代码运行的上下文内核时间指明线程执行操 作系统代码己经经过了多少个100ns的CPU时间,linux是一个具有保护模式的操作系统 它一直T作在i386 cpu的保护模式Z下内存被分为两个单元:内核区域和用户区域一般 地,在使用虚拟内存技术的多任务系统上,内核和应用有不同的地址空间,因此,在内核 和应用Z间以及在应用与应间进行数据交换需要专门的机制来实现,本文站在用户空 间的角度,测试一个多线程程序的程序执行时间当一个进程希望获得信号量时,如果信号 量已经被占有,则该进程将会被放到等待队列上sleep直到cpu将其唤醒相对丁 spinlock 来说开销太大,适用于长时间占有的locko不可用于中断状态,因为它拥有信号量的进程 可以sleep,可以被抢占,信号量可以设置为同时允许的进程数关键字:内核的时间管理算法 内核定时器 执行时间 多线程程序1.设计题目和要求设计题内核定时器设计要求:通过研究内核的时间管理算法,学习内核源代码;然后应用这些知识并且使用“信号”建 立一种用户空间机制來测量一个多线程程序的执行时间2.1.1 Linux内核定时器定时器是管理内核时间的基础,用来计算流逝的时间,它以某种频率(节扌n率)自行 触发时钟中断,当时钟中断发生时,内核就通过一种特殊中断处理程序对其进行处理。

      但是原来的实现只能是time_t mytime形式的,经过简单的localtime(mytime)和 ctime(&mytime)处理.精度是不够的,为了返回高精度的时间,这里使用了 gettimeofday函数 这个syscall用来供用户获取timeval格式的当前时间信息(精确度为微秒级),以及系统的 当前时区信息(timezone)o结构类型timeval的指针参数tv指向接受时间信息的用户空间 缓冲区,参数tz是一个timezone结构类型的指针,指向接收时区信息的用户空间缓冲区 这两个参数均为输出参数,返回值0表示成功,返回负值表示出错两数sys_gettimeofday() 的源码如卜(kernel/time.c):asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz){ if (tv) { struct timeval ktv; do_gettimeofday(&ktv); if (copy_to_user(tv, &ktv, sizeof(ktv))) return -EFAULT;} if (tz) { if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) return ・EFAULT;return 0;}显然,函数的实现主要分成两个大的方面:(1) 如果W指针有效,则说明用户要以timeval格式来检索系统当前时间。

      为此,先调用 do_gettimeofday()函数来检索系统当前时间并保存到局部变量ktv中然后再调用 copy_to_user ()宏将保存在内核空间中的当前时间信息拷贝到由参数指针tv所指向的用户 空间缓冲区中2) 如果tz指针有效,则说明用户要检索当前时区信息,因此调用copy_to_user()宏将全 局变量sys_tz中的时区信息拷贝到参数指针tz所指向的用户空间缓冲区中3) 最病,返回0表示成功函数 do_gettimeofday()的源码如下(arch/i386/kemel/time.c):/** This version of gettimeofday has microsecond resolution* and better than microsecond precision on fast x86 machines with TSC.*/void do_gettimeofday(struct timeval *tv){unsigned long flags;unsigned long usee, sec;read_lock_irqsave(&xtime_lock, flags);usee = do_gettimeoffset();{unsigned long lost = jiffies ・ wall」iffies;if (lost)usee += lost * (1000000 / HZ);}sec = xtime.tv_sec;usee += xtime.tv_usec;read_unlock_irqrestore(&xtime_lock, flags);while (usee >= 1000000) {usee -= 1000000;sec++;}tv->tv_sec = sec;tv->tv_usec = usee;}该苗数的完成实际的当前时间检索工作。

      出于gettimeofday()系统调用要求时间精度要 达到微秒级,因此do_gettimeofday()函数不能简单地返回xtime中的值即口J,而必须精确地 确运自从时钟驱动的Bottom Half _t一次更新xtime的那个时刻到do_gettimeofday()函数的 当前执行时刻之间的具体时间间隔长度,以使精确地修正xtime的值.假定被 do_gettimeofday()用來修正 xtime 的时间间隔为 fixed_usec,而从 wall_jiffies 到 jiffies Z间的时间间隔是lost_usec, jflj从jiffies到do_gettimeofday()函数的执行时刻的时间间隔是 offset_usec则下列三个等式成立:fixed_usec = (lost_usec+offset_usec )lost_usec= (jiffies-wall _jiffies) *TICK_SIZE= (jiffies-wall Jiffies)次(1000000 / HZ) 曲于全局变量last_tsc_low表示上一次时钟中断服矗函数timer_interrupt()^L行时刻的CPU TSC寄存器的值,因此我们可以用X86 CPU的TSC寄存器來计算offset_usec的值。

      也即: offset usec=delay at last interrupt + ( current tsc low — last tsc low ) *fast_gettimeoffset_quotient其中,delay_at_last_interrupt是从上一次发生时钟中断到timer_interrupt()服务函数真正执行 时刻之间的时间延迟间隔每一次timer_interrupt()执行时都会计算这一间隔,并利用TSC 的当前值更新 last_tsc_low 变量(可以参见 7.4 节)假定 current_tsc_low 是 do_gettimeofday() 函数执彳亍时刻TSC的当前值,全局变量fast_gettimeoffset_quotient则表示TSC寄存器每增 加1所代表的时间间隔值,它是由time_init()^|数所计算的根据上述原理分析,do_gettimeofday()函数的执行步骤如下:(1 )调用函数do_gettimeoffset()i+算从上一次时钟中断发生到执行do_gettimeofday()函数的 当前时刻之间的时间间隔offse(_usec。

      2) 通过 walljiffies 和 jiffies 计算 lost_usec 的值3) 然后,sec=xtime.tv_sec, usec=xtime.tv_usec+lost_usec4-offset_useco 显然,sec 表示 系统当前时间在秒数量级上的值,而usee表示怎统当前时间在微秒量级上的值4) 用-个while{}循环来判断usee是否已经溢出而超过106us=l秒如果溢出,则将usee 减去106us并相应地将sec增加1,直到usee不溢出为止5) 最后,用sec和usee分别更新参数指针所指向的timeval结构变量至此,整个查询 过程结束函数do_gettimeoffset()ffi据CPU是否配置有TSC寄存器这一条件分别有不同的实现 其定义如下(arch/i386/kemel/time.c ):#ifndef CONFIG_X86_TSCstatic unsigned long do_slow_gettimeoffset(void) static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;#else#define do_gettimeoffset() do_fast_gettimeoffset()* endif显然,在配置有TSC寄存器的i386平台上,do_gettimeoffset ()函数实际上就是 do_fast_gettimeoffset()函数。

      它通过TSC寄存器来计算do_fast_gettimeoffset()函数被执彳亍的 时刻到上一次时钟中断发生时的时间间隔值其源码如卜(arch/i386/kernel/time.c): static inline unsigned long do_fast_gettimeoffset(void){register unsigned long eax, edx;/* Read the Time Stamp Counter */rdtsc(eax,edx);/* .. relative to previous jiffy (32 bits is enough) */eax -= last_tsc_low。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.