MINIX 3 源码解读报告
—— MINIX 3.1.6 时钟任务
1.时钟的作用
操作系统的时钟任务有很多作用,如维护系统时间、提供定时器、检测系统性能等,还有非常重要的一
点就是防止一个进程独占 CPU 资源。MINIX 3 是一个分时的交互式系统,多个程序共享同一资源时,需
要将 CPU 时间划分成多个时间片,分配给不同的进程,使每个进程都能得到调度。一个进程的运行时间
是否超过最大运行时间,需要由时钟来控制。
2.MINIX 3 的时钟驱动程序
MINIX 3.1.6 的时钟任务管理部分在 kernel/clock.c 的 clock_task()函数中定义。在函数的开
始,调用 init_clock()设置一个看门狗时钟,用来周期性地调整进程调度队列。随后,它循环运行,
等待一个消息,然后分析消息来源:如果是 HARD_INT,则进行进一步处理,如果是其他消息,提示出
错,进入下一个循环。
init_clock()程序调用 balance_queues 初始化时钟,除了产生周期性中断之外,还将中断处理程
序的地址放在合适的地方,以便时钟芯片向中断控制芯片触发了 8 号中断时能够找到,并使能它以响应
输入的中断。
时钟中断处理程序在 MINIX 3.1.6 中有两种,一种是用于 boot processor 的
bsp_timer_int_handler(),一种是只用于 non-boot processor 的
ap_timer_int_handler()。前者也调用后者。它们的区别在于,bsp_timer_int_handler()更
新 realtime,并且在必要的时候发消息通知 clock_task()。
在每次时钟中断产生之后,中断处理程序开始运行。clock.c 中不提供具体的系统启动时间的计算,只
维护节拍计数器,提供当前节拍数给系统调用计算真实时间,这符合 MINIX 微内核的特性:功能性的模
块都交由外层的服务器来做。
当中断被禁止时,时钟节拍会丢失,使用一个全局变量 lost_ticks 来计算丢失的节拍数,再加上主计
时器 ticks,每次中断处理程序被激活时将 lost_ticks 清零。这个全局变量本身是由 kernel/
arch/i386/klib386.s 中的 int86 函数使用的,int86 使用引导程序监控程序来管理对于 BIOS 的
控制,而监控程序返回在返回到内核之前 BIOS 调用忙期间 ecx 寄存器内对时钟节拍的计数值。
bsp_timer_int_handler()运行时,得到当前的 lost_ticks 数,于是更新 ticks 并清零
lost_ticks 使它在下一轮重新计算:
ticks = lost_ticks+1;
lost_ticks = 0;
然后更新 realtime:
realtime += ticks;
接下来才是真正调用时钟中断处理器 ap_timer_int_handler()。这个函数首先更新当前进程的用户
时间,如果它是一个用户进程,那么它将支付系统进程的时间。否则,它将从其他进程那里获得一些系
统时间。
p = proc_ptr;
billp = bill_ptr;
p->p_user_time += ticks;
if (priv(p)->s_flags & PREEMPTIBLE) {
p->p_ticks_left -= ticks;
}
if (! (priv(p)->s_flags & BILLABLE)) {
billp->p_sys_time += ticks;
- 1
- 2
前往页