| 在循环中检查等待条件是否满足,不满足则调用schedule(),满足了就退出循环;
将进程从事件等待队列中删除。
从"调度器工作流程"中我们知道,调度器会将处于休眠状态的进程从就绪队列中删除,而只有就绪队列中的进程才有可能被调度到。将该进程重新放到就绪队列中的动作是在事件发生时的"唤醒"过程中完成的。在以上所示的鼠标驱动中,鼠标中断将调用mousedev_event()函数,该函数的最后就会使用wake_up_interruptible()唤醒等待鼠标事件的所有进程。wake_up_interruptible()将最终调用try_to_wake_up()函数:
/* 节选自[kernel/sched.c] */
static inline int try_to_wake_up(struct task_struct * p, int synchronous)
{
unsigned long flags;
int success = 0;
spin_lock_irqsave(&runqueue_lock, flags);
p->state = TASK_RUNNING;
if (task_on_runqueue(p))
goto out;
add_to_runqueue(p); /* 添加到就绪队列中 */
if (!synchronous || !(p->cpus_allowed & (1 << smp_processor_id())))
reschedule_idle(p); /* 这种情况下调用wake_up(),synchronous总为0,此时,*/
/* 如果本CPU不适合运行该进程,则需要调用reschedule_idle()寻找合适的CPU */
success = 1;
out:
spin_unlock_irqrestore(&runqueue_lock, flags);
return success;
}
这时启动schedule()就是被动的了。
B. 被动式
在系统调用执行结束后,控制由核心态返回到用户态之前,Linux都将在ret_from_sys_call入口检查当前进程的need_resched值,如果该值为1,则调用schedule():
/* 节选自[arch/i386/kernel/entry.S] */
ENTRY(ret_from_sys_call)
上一页 [1] [2] [3] 下一页 |