5 加快中断处理(1)(harib09e)

现在我们可以自由使用多个定时器了,从数量上说,已经足够了。但仔细看一下大家会发现,inthandler20还有很大问题:中断处理本来应该在很短的时间内完成,可利用inthandler20时却花费了很长时间。这就妨碍了其他中断处理的执行,使得操作系统反应很迟钝。

如果检查inthandler20,能发现每次进行定时器中断处理的时候,都会对所有活动中的定时器进行“timerctl.timer[i].timeout—;”处理。也就是说,CPU要完成从内存中读取变量值,减去1,然后又往内存中写入的操作。本来谁也不会注意到这种细微之处,但由于我们想在中断处理程序中尽可能减少哪怕是一点点工作量,所以才会注意到这里。

问题找到了,那该怎么修改才好呢?我们看看下面这样行不行。

本次的timer.c节选

  1. void inthandler20(int *esp)
  2. {
  3. int i;
  4. io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00信号接收结束的信息通知给PIC */
  5. timerctl.count++;
  6. for (i = 0; i < MAX_TIMER; i++) {
  7. if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {
  8. if (timerctl.timer[i].timeout <= timerctl.count) { /* 这里! */
  9. timerctl.timer[i].flags = TIMER_FLAGS_ALLOC;
  10. fifo8_put(timerctl.timer[i].fifo, timerctl.timer[i].data);
  11. }
  12. }
  13. }
  14. return;
  15. }

我们改变了程序中变量timer[i].timeout的含义。它指的不再是“所剩时间”,而是“予定时刻”了。因为现在的时刻计数到timerctl.count中去了,所以就拿它和timer[i].timeout进行比较,如果相同或是超过了,就通过往FIFO缓冲区里传送数据来通知HariMain。大家现在再看一看,我们一直担心的减法计算没有了。这样一改,程序的速度应该能稍微变快一些了。

下面我们也要相应地修改timer_settime函数。

本次的timer.c节选

  1. void timer_settime(struct TIMER *timer, unsigned int timeout)
  2. {
  3. timer->timeout = timeout + timerctl.count; /* 这里! */
  4. timer->flags = TIMER_FLAGS_USING;
  5. return;
  6. }

timer_settime函数中所指定的时间,是“从现在开始多少多少秒以后”的意思,所以用这个时间加上现在的时刻,就可以计算出中断的预定时刻。程序中对这个时刻进行了记录。别的地方就不用改了。

■■■■■

到底这样做行不行呢,我们执行一下“make run”。好哇,进行得很顺利。虽然还没能切身感到速度变快了多少,不过先自我满足一下吧(笑)。

同时也正是因为变成了这种方式,在我们这个纸娃娃操作系统中,启动以后经过42 949 673秒后,count就是0xffffffff了,比这个值再大就不能设定了。这么多秒是几天呢?……嗯,请稍等(用计算器算一下)……大约是497天。也就是大约一年就要重新启动一次操作系统,让count归0。

这里大家可能又会有怨言了“哎呀,还需要重新起动,这样的操作系统真是麻烦”。事实上笔者本人也是这么想的(笑)。怎么办才好呢。嗯,回到上一节的做法,好不好呢?可是回到上一节的做法,速度又有些慢。……既不希望速度慢,又不想重新启动——为了满足这种奢望,我们设计成一年调整一次时刻的程序也许比较好。

时刻调整程序

  1. int t0 = timerctl.count; /* 所有时刻都要减去这个值 */
  2. io_cli(); /* 在时刻调整时禁止定时器中断 */
  3. timerctl.count -= t0;
  4. for (i = 0; i < MAX_TIMER; i++) {
  5. if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {
  6. timerctl.timer[i].timeout -= t0;
  7. }
  8. }
  9. io_sti();

也许以上方法并非最好,但我们不轻言放弃而去想办法解决,这种心境是最重要的。只要努力,我们肯定还能找到别的好办法。