|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
一、调度时机
1)显示调度,进程自己因为缺少相应的所申请的资源,显示调用调度器,让出处理器,比如:内核申请的
信号阻塞了,自旋锁锁住了
2)隐式调度,整个linux系统在运行过程中的非显示的调用调度器,这又分两种情况
A)用户态抢占调度 比如:在系统调用,中断处理,异常处理返回用户态时,该进程的时间片已经用完
B)内核态抢占调度 比如:当前内核态执行过程中事先没有禁止内核态抢占,有中断产生时,中断处理
又产生了更高级优先进程,那么就会直接抢占前面的内核态执行体
内核态抢占的抢占点有两处A)中断处理返回内核态时(如果事先没有禁止内核态抢占---preempt_disable)
(B)重新起用内核态抢占时---preempt_enable
相关数据结构及函数如下:
struct task中
{
unisgned int preempt_count;-----(PREEMPT 0-7位表示内核态禁止抢占计数器,SOFTIRQ 8-15表示软中断禁止
计数器,HARDIRQ 16-27表示中断嵌套的深度)
}
只要PREEMPT为0时才允许内核态抢占.
preempt_disable()--------------主要执行inc_preempt_count()(增加PREEMPT,从而禁止内核态抢占)
preempt_enable()--------------主要执行preempt_enable_no_resched()和preempt_check_resched()
preempt_enable_no_resched()主要执行dec_preempt_count()
preempt_check_resched()主要执行test_thread_flag(TIF_NEED_RESCHED)
(是否设置了需要调度的标志)和preempt_schedule()(进行内核态抢占调度)
二、常见的调度点
1)进程被阻塞时 比如申请资源时被阻塞
2)调整参数时 比如通过sched_setscheduler() ,nice()等函数调整进程的调度策略,静态优先级时
3)睡眠进程被唤醒时 比如wake_up唤醒等待队列中的进程时,如果该进程具有更高优先级则会设置当前
进程TIF_NEED_RESCHED,如果允许内核态抢占,则会调度一次,
( 这是由等待队列中的默认的唤醒函数控制的,默认的唤醒函数为:
int default_wake_function(wait_queue_t*,unisgned int mode,int sync,void* key)
EXPORT_SYMBOL(default_wake_function)
因为EXPORT_SYMBOL了default_wake_function,所以我们可以制作我们自己的唤醒函数.
4)中断处理完时 如果中断处理过程中设置了TIF_NEED_SCHED标志,中断返回时,不论是要返回内核态
还是用户态,都会发生一次抢占.当然,在这也会检查有没有软中断需要处理.
5)执行了preempt_enable()函数 (见前面说明) |
|