|
发表于 2007-4-14 12:25:13
|
显示全部楼层
在entry_armv.S中:(我的是ARM平台)
- irq_handler
- #ifdef CONFIG_PREEMPT
- ldr r0, [tsk, #TI_FLAGS] @ get flags
- tst r0, #_TIF_NEED_RESCHED ◎检查TIF_NEED_RESCHED标志位
- blne svc_preempt
- .
- .
- .
- svc_preempt:
- teq r8, #0 @ was preempt count = 0
- ldreq r6, .LCirq_stat
- movne pc, lr @ no
- ldr r0, [r6, #4] @ local_irq_count
- ldr r1, [r6, #8] @ local_bh_count
- adds r0, r0, r1
- movne pc, lr
- mov r7, #0 @ preempt_schedule_irq
- str r7, [tsk, #TI_PREEMPT] @ 保存preemnt_count值,但愿它是0,哦,expects preempt_count == 0
- 1: bl preempt_schedule_irq
复制代码
而在preempt_schedule_irq()函数中有:
- struct thread_info *ti = current_thread_info();
- #ifdef CONFIG_PREEMPT_BKL
- struct task_struct *task = current;
- int saved_lock_depth;
- #endif
- /* Catch callers which need to be fixed*/
- BUG_ON(ti->preempt_count || !irqs_disabled()); //不为0就BUG了
- .
- .
- .
- local_irq_enable();
- schedule(); //就可以调用schedule()了
- local_irq_disable();
复制代码
而在我的pxa_timer_init()函数中注册的pxa_timer_irq.handler=pxa_timer_interrupt() -> time_tick() -> update_process_times() -> scheduler_tick() 中设置NEED_RESCHED标志:
- if (!--p->time_slice) {
- dequeue_task(p, rq->active);
- set_tsk_need_resched(p);//时间片用完了,晕了吧,该设置TIF_NEED_RESCHED标志了
- p->prio = effective_prio(p);
- p->time_slice = task_timeslice(p);
- p->first_time_slice = 0;
- if (!rq->expired_timestamp)
- rq->expired_timestamp = jiffies;
- if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
- enqueue_task(p, rq->expired);
- if (p->static_prio < rq->best_expired_prio)
- rq->best_expired_prio = p->static_prio;
- } else
- enqueue_task(p, rq->active);
- }
复制代码
一起学习...... |
|