Linux内核抢占点,linux内核抢占的几个细节

邮件列表每天都能让我学到新东西,感谢他!有朋友问PREEMPT_ACTIVE有什么用,我给出了最简单的回答,就是避免被抢占的进程被无情的赶出运行队列。这个回答显然不能让那位朋友满意...

进程一旦调用了schedule,如果再次被调度运行,那么有下面几种可能:

1.状态为TASK_RUNNING,处于运行队列,那么它肯定有机会再运行;

2.处于睡眠队列,那么一旦条件满足被唤醒,那么它就会运行。那么如果一个进程被抢占的话,而且它不在运行队列,那么怎么再让它运行呢?答案是它不能运行了。为了避免这种情况,就必须避免处于非TASK_RUNNING的进程被抢占的进程不被赶出运行队列,也就是下面的代码,schedule的代码:

if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {

switch_count = &prev->nvcsw;

if (unlikely((prev->state & TASK_INTERRUPTIBLE) && unlikely(signal_pending(prev))))

prev->state = TASK_RUNNING;

else {

if (prev->state == TASK_UNINTERRUPTIBLE)

rq->nr_uninterruptible++;

deactivate_task(prev, rq);

}

也许有人会问,怎么会有不是TASK_RUNNING的进程而且被抢占的,这个问题实在难以回答,可是记住,进程状态和其所在的队列没有关系,设置进程状态和抢占总是有可能有间隙的。我们看看下面的代码:

for (;;) { /

1: prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); /

2: if (condition) /

3: break; /

4: schedule(); /

}

如果在1中被抢占,恰恰在设置完进程为TASK_UNINTERRUPTIBLE的时候被抢占,本来马上就要测试条件是否满足了,结果又被加入睡眠队列去睡眠了,如果没有PREEMPT_ACTIVE,那么在schedule中就会被移出运行队列,如果只有这一次唤醒机会,那么就永远唤不醒这个进程了,如果本次从schedule回来条件不满足,那么在下面的schedue中就会被移出运行队列,这不是抢占的职责,如果非要怎么做就会出错,在dequeue_task中由array->queue已经为空了,在第二次真正出队的时候就会由于空指针引用而出错(这其实不会发生,因为只要从schedue回来,进程的状态肯定是TASK_RUNNING,仅仅是一个例子)。因此必须保证在将进程从运行队列移除的时候,它必须在运行队列,否则移个鸟啊!实际上PREEMPT_ACTIVE的作用就是防止将处于非TASK_RUNNING状态的进程并且没有在任何睡眠队列的进程移出运行队列,总之必须保证进程在一个队列中或者可以被唤醒,被抢占的进程是不能被唤醒的,如果它还不在运行队列中,那么它将永远不能再运行了。那么PREEMPT_ACTIVE是怎么保证被抢占的进程不会被移除运行队列呢?就是在preempt_schedule实现的:

asmlinkage void __sched preempt_schedule(void)

{

struct thread_info *ti = current_thread_info();

if (likely(ti->preempt_count || irqs_disabled()))

return;

do {

add_preempt_count(PREEMPT_ACTIVE); //设置PREEMPT_ACTIVE位,一直到下面的sub_preempt_count(PREEMPT_ACTIVE),这期间不能再抢占这个进程,不过再抢占也没有意义,如果非要抢占,出了下面的sub_preempt_count(PREEMPT_ACTIVE)也不迟

schedule();

sub_preempt_count(PREEMPT_ACTIVE); //抢占完毕后清除之

barrier();

} while (unlikely(test_thread_flag(TIF_NEED_RESCHED)));

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值