在退出中断程序的时候会判断是否需要进入调度器进行抢占,通过_TIF_NEED_RESCHED标记,代码如下:
__irq_svc:
svc_entry
irq_handler
#ifdef CONFIG_PREEMPTION
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
ldr r0, [tsk, #TI_FLAGS] @ get flags
teq r8, #0 @ if preempt count != 0
movne r0, #0 @ force flags to 0
tst r0, #_TIF_NEED_RESCHED
blne svc_preempt
#endif
svc_exit r5, irq = 1 @ return from exception
UNWIND(.fnend )
ENDPROC(__irq_svc)
如果需要抢占则会进入svc_preempt -> preempt_schedule_irq -> __schedule
如果不进行抢占,由svc_exit执行中断退出(寄存器恢复到被中断的进程)
我的问题是:
因为抢占是不能进行在中断上下文中的(书上这么说的,我认为应该是中断栈不能单独保存的原因),所以执行__schedule的时候已经在进程上下文,但是为什么这里就是进程上下文了呢?堆栈不都还是在中断里吗。
例如在进程A的过程中触发了中断,在svc_preempt进行了抢占,切换到了任务B,这时的svc_exit没有得到执行,寄存器状态还在中断栈,从任务B再切换回来时中断栈可能已经被其他中断破坏,怎么能够返回到任务A呢?