基于时间事件的等待与唤醒

    sched.h定义了有关timer数据结构,

    timer相关操作

    一个 timer在ucore中的生存周期可以被描述如下:

    1. 某进程创建和初始化timer_t结构的一个timer,并把timer被加入系统timer管理列表timer_list中,进程设置为基于timer事件的阻塞态(即睡眠了),这样这个timer就诞生了,;
    2. 系统时间通过时钟中断被不断累加,且ucore定期检查是否有某个timer的到期时间已经到了,如果没有到期,则ucore等待下一次检查,此timer会挂在timer_list上继续存在;
    3. 如果到期了,则对应的进程又处于就绪态了,并从系统timer管理列表timer_list中移除该 timer,自此timer就死亡退出了。
    • timer init:对timer的成员变量进行初始化,设定了在expires时间之后唤醒proc进程
    • del_timer:向系统timer链表timer_list删除(或者说取消)某一个计时器。该计时 器在取消后,对应的进程不会被系统在指定时刻expires唤醒。
    • run_timer_list:被trap函数调用,遍历系统timer链表timer_list中的timer计时器,找出所有应该到时的timer计时器,并唤醒与此计时器相关的等待进程,再删除此timer计时器。在lab4/proj13以后,还增加了对进程调度器在时间事件产生后的处理函数的调用(在后续有进一步分析)。

    有了这些函数的支持,我们就可以实现进程睡觉并被定时唤醒的功能了。比如ucore在用户函数库中提供了sleep函数,当用户进程调用sleep函数后,会进一步调用sys_sleep系统调用,在内核中完成sys_sleep系统调用服务的是do_sleep内核函数,其实现如下:

    1. do_sleep(unsigned int time) {
    2. ……
    3. timer_t __timer, *timer = timer_init(&__timer, current, time);
    4. current->wait_state = WT_TIMER;
    5. add_timer(timer);
    6. ……
    7. del_timer(timer);
    8. return 0;