Xtensa port: Prevent preemption of locked threads.
When an IRQ is serviced, the ISR dispatcher will check for any new thread in the ready queue and switch to it. However, if the current thread is marked as non preemptable due to _kernel.current->base.preempt > _NON_PREEMPT_THRESHOLD then we should not switch to another one. Change-Id: Icdc08105cc6433da479bb95265710462a0f37c0b Signed-off-by: Mazen NEIFER <mazen@nestwave.com>
This commit is contained in:
parent
53f66d0bf7
commit
74ff1092d4
2 changed files with 18 additions and 6 deletions
|
@ -84,9 +84,11 @@ _Swap:
|
||||||
call4 _sys_k_event_logger_context_switch
|
call4 _sys_k_event_logger_context_switch
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
/* _thread := _kernel.ready_q.cache */
|
||||||
|
l32i a3, a2, KERNEL_OFFSET(ready_q_cache)
|
||||||
/*
|
/*
|
||||||
* Swap threads if any is to be swapped in.
|
* Swap threads if any is to be swapped in.
|
||||||
*/
|
*/
|
||||||
call0 _zxt_dispatch
|
call0 _zxt_dispatch /* (_kernel@a2, _thread@a3) */
|
||||||
/* Never reaches here. */
|
/* Never reaches here. */
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
.set _interrupt_stack_top, _interrupt_stack + CONFIG_ISR_STACK_SIZE
|
.set _interrupt_stack_top, _interrupt_stack + CONFIG_ISR_STACK_SIZE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _zxt_dispatch(_kernel_t *_kernel)
|
* _zxt_dispatch(_kernel_t *_kernel, _thread_t *_thread)
|
||||||
* At this point, the a2 register contains the '&_kernel' and the
|
* At this point, the a2 register contains the '&_kernel' and the
|
||||||
* thread to be swapped in is in _kernel.ready_q.cache.
|
* thread to be swapped in (&_thread) is in a3.
|
||||||
*/
|
*/
|
||||||
.text
|
.text
|
||||||
.globl _zxt_dispatch
|
.globl _zxt_dispatch
|
||||||
|
@ -26,8 +26,7 @@
|
||||||
.align 4
|
.align 4
|
||||||
_zxt_dispatch:
|
_zxt_dispatch:
|
||||||
/* Updated current thread: _kernel.current := _kernel.ready_q.cache */
|
/* Updated current thread: _kernel.current := _kernel.ready_q.cache */
|
||||||
l32i a3, a2, KERNEL_OFFSET(ready_q_cache)
|
s32i a3, a2, KERNEL_OFFSET(current) /* _kernel.current := _thread */
|
||||||
s32i a3, a2, KERNEL_OFFSET(current) /* _kernel.current := a3 */
|
|
||||||
l32i sp, a3, THREAD_OFFSET(sp) /* sp := _thread->topOfStack; */
|
l32i sp, a3, THREAD_OFFSET(sp) /* sp := _thread->topOfStack; */
|
||||||
|
|
||||||
/* Determine the type of stack frame. */
|
/* Determine the type of stack frame. */
|
||||||
|
@ -182,10 +181,21 @@ _zxt_int_exit:
|
||||||
movi a3, 0
|
movi a3, 0
|
||||||
wsr a3, CPENABLE /* disable all co-processors */
|
wsr a3, CPENABLE /* disable all co-processors */
|
||||||
#endif
|
#endif
|
||||||
|
l32i a3, a2, KERNEL_OFFSET(current) /* _thread := _kernel.current */
|
||||||
|
/*
|
||||||
|
* Non-preemptible thread ? Do not schedule (see explanation of
|
||||||
|
* preempt field in kernel_struct.h).
|
||||||
|
*/
|
||||||
|
movi a4, _NON_PREEMPT_THRESHOLD
|
||||||
|
l16ui a5, a3, THREAD_OFFSET(preempt)
|
||||||
|
bgeu a5, a4, .noReschedule
|
||||||
|
/* _thread := _kernel.ready_q.cache */
|
||||||
|
l32i a3, a2, KERNEL_OFFSET(ready_q_cache)
|
||||||
|
.noReschedule:
|
||||||
/*
|
/*
|
||||||
* Swap threads if any is to be swapped in.
|
* Swap threads if any is to be swapped in.
|
||||||
*/
|
*/
|
||||||
call0 _zxt_dispatch /* tail-call dispatcher */
|
call0 _zxt_dispatch /* (_kernel@a2, _thread@a3) */
|
||||||
/* Never returns here. */
|
/* Never returns here. */
|
||||||
|
|
||||||
.Lnesting:
|
.Lnesting:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue