uCore Lab Documents

计时器的原理和实现

在传统的操作系统中,计时器是其中一个基础而重要的功能.它提供了基于时间事件的调度机制。在ucore 中,timer 中断(irq0)给操作系统提供了有一定间隔的时间事件,操作系统将其作为基本的调度和计时单位(我们记两次时间中断之间的时间间隔为一个时间片,timer splice)。

基于此时间单位,操作系统得以向上提供基于时间点的事件,并实现基于时间长度的等待和唤醒机制。在每个时钟中断发生时,操作系统产生对应的时间事件。应用程序或者操作系统的其他组件可以以此来构建更复杂和高级的调度。

  • sched.h, sched.c 定义了有关timer的各种相关接口来使用 timer 服务,其中主要包括:
  • typedef struct {……} timer_t: 定义了 timer_t 的基本结构,其可以用 sched.h 中的timer_init函数对其进行初始化。
  • void timer_init(timer t *timer, struct proc_struct *proc, int expires): 对某计时器 进行初始化,让它在 expires 时间片之后唤醒 proc 进程。
  • void add_timer(timer t *timer): 向系统添加某个初始化过的timer_t,该计时器在 指定时间后被激活,并将对应的进程唤醒至runnable(如果当前进程处在等待状态)。
  • void del_timer(timer_t *time): 向系统删除(或者说取消)某一个计时器。该计时器在取消后不会被系统激活并唤醒进程。
  • void run_timer_list(void): 更新当前系统时间点,遍历当前所有处在系统管理内的计时器,找出所有应该激活的计数器,并激活它们。该过程在且只在每次计时器中断时被调用。在ucore 中,其还会调用调度器事件处理程序。

一个 timer_t 在系统中的存活周期可以被描述如下:

  1. timer_t 在某个位置被创建和初始化,并通过 add_timer加入系统管理列表中
  2. 系统时间被不断累加,直到 run_timer_list 发现该 timer_t到期。
  3. run_timer_list更改对应的进程状态,并从系统管理列表中移除该timer_t。

尽管本次实验并不需要填充计时器相关的代码,但是作为系统重要的组件(同时计时器也是调度器的一个部分),你应该了解其相关机制和在ucore中的实现方法。接下来的实验描述将会在一定程度上忽略计时器对调度带来的影响,即不考虑基于固定时间点的调度。