30天自制操作系统day13

来源:互联网 发布:控制电脑使用时间软件 编辑:程序博客网 时间:2024/05/22 06:58

这一章继续讲定时器的优化。

上一章中,每个定时器都有一个FIFO,判断时钟中断时需要判断每个FIFO的状态。其实可以让它们共用一个FIFO,通过向FIFO中传入不同的值来区别是哪个定时器超时了。

继续优化,可以把鼠标和键盘的FIFO也加进来,这样每次循环就只需要检测一个FIFO的状态。同时需要让键盘鼠标中断时向FIFO中传入不同的值,与定时器区别开来。

然后是在inthandler20()和timer_settime()函数中。intlandler20()中,当有计时器超时时,需要将它从timerctl->timers中删除,同时还需要将它后面的timer前移。timer_settime()中也一样,插入新的timer时需要将后面的后移。为了避免大量的移动操作,可以使用链表。这样插入删除就只是常数时间了。

最后得到一个优化的定时器模块。总结一下:
TIMERCTL结构:

struct TIMERCTL {    unsigned int count, next;//count为当前计数值,next为下一超时数值    struct TIMER *t0;//相当于链表的head    struct TIMER timers0[MAX_TIMER];//定时器};

TIMER结构:

struct TIMER {    struct TIMER *next;//指向链表中的下一个    unsigned int timeout, flags;//timeout为超时值    struct FIFO32 *fifo;//这个FIFO会设置为一个全局的FIFO    int data;};

timer_alloc()分配一个新的定时器,timer_settimer()启动这个定时器。启动时将它插入到适当的位置,并更新timerctl的next值。链表中有一个哨兵,它的timeout值为0xffffffff,当链表中没有别的定时器时,timerctl的next值就是0xffffffff。由于timerctl->count会在达到这个值之前清零,所以这个timeout不会触发。
inthandler20()中,每次先判断timerctl->count和timerctl->next。如果有超时,则删除掉超时的timer(总是在链表的最前面),向FIFO中传入信号。
主循环中,只要判断FIFO状态,读取信号值,处理相应的定时器。

0 0