- 论坛徽章:
- 6
|
回复 1# yifei429
内核中经常有set_current_state(TASK_INTERRUPTIBLE);这段代码,并且还没有放入唤醒队列中(例如2.6.18中的do_poll函数),当执行完这段代码之后:
1.此时刚好时间片到期,那此进程是不是永远不会执行了?
2.此事发生抢占,会出现什么情况?
这个问题的确是可能发生的,但是内核通过一个标志PREEMPT_ACTIVE来防止这种情况的发生。
PREEMPT_ACTIVE的作用:防止已经处于非运行状态的进程还没有加入到相应的队列之前,就被抢占的情况发生。
具体代码在schedule函数中:- asmlinkage void __sched schedule(void)
- {
- struct task_struct *prev, *next;
- long *switch_count;
- struct rq *rq;
- int cpu;
- need_resched:
- preempt_disable();
- cpu = smp_processor_id();
- rq = cpu_rq(cpu);
- rcu_qsctr_inc(cpu);
- prev = rq->curr;
- switch_count = &prev->nivcsw;
- release_kernel_lock(prev);
- need_resched_nonpreemptible:
- schedule_debug(prev);
- /*
- * Do the rq-clock update outside the rq lock:
- */
- local_irq_disable();
- __update_rq_clock(rq);
- spin_lock(&rq->lock);
- clear_tsk_need_resched(prev);
- if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
- if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
- unlikely(signal_pending(prev)))) {
- prev->state = TASK_RUNNING;
- } else {
- deactivate_task(rq, prev, 1);
- }
- switch_count = &prev->nvcsw;
- }
- if (unlikely(!rq->nr_running))
- idle_balance(cpu, rq);
- prev->sched_class->put_prev_task(rq, prev);
- next = pick_next_task(rq, prev);
- sched_info_switch(prev, next);
- if (likely(prev != next)) {
- rq->nr_switches++;
- rq->curr = next;
- ++*switch_count;
- context_switch(rq, prev, next); /* unlocks the rq */
- } else
- spin_unlock_irq(&rq->lock);
- if (unlikely(reacquire_kernel_lock(current) < 0)) {
- cpu = smp_processor_id();
- rq = cpu_rq(cpu);
- goto need_resched_nonpreemptible;
- }
- preempt_enable_no_resched();
- if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
- goto need_resched;
- }
复制代码 |
|