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:
Mazen NEIFER 2017-02-09 22:30:29 +01:00 committed by Andrew Boie
commit 74ff1092d4
2 changed files with 18 additions and 6 deletions

View file

@ -84,9 +84,11 @@ _Swap:
call4 _sys_k_event_logger_context_switch
#endif
#endif
/* _thread := _kernel.ready_q.cache */
l32i a3, a2, KERNEL_OFFSET(ready_q_cache)
/*
* Swap threads if any is to be swapped in.
*/
call0 _zxt_dispatch
call0 _zxt_dispatch /* (_kernel@a2, _thread@a3) */
/* Never reaches here. */

View file

@ -16,9 +16,9 @@
.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
* thread to be swapped in is in _kernel.ready_q.cache.
* thread to be swapped in (&_thread) is in a3.
*/
.text
.globl _zxt_dispatch
@ -26,8 +26,7 @@
.align 4
_zxt_dispatch:
/* 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 := a3 */
s32i a3, a2, KERNEL_OFFSET(current) /* _kernel.current := _thread */
l32i sp, a3, THREAD_OFFSET(sp) /* sp := _thread->topOfStack; */
/* Determine the type of stack frame. */
@ -182,10 +181,21 @@ _zxt_int_exit:
movi a3, 0
wsr a3, CPENABLE /* disable all co-processors */
#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.
*/
call0 _zxt_dispatch /* tail-call dispatcher */
call0 _zxt_dispatch /* (_kernel@a2, _thread@a3) */
/* Never returns here. */
.Lnesting: