sched: irq: Change irq_waitlock() from private to public
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
parent
8d0118569c
commit
a24905059e
@ -46,6 +46,9 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <stdint.h>
|
||||
# include <assert.h>
|
||||
# ifdef CONFIG_SMP
|
||||
# include <stdbool.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Now include architecture-specific types */
|
||||
@ -170,6 +173,53 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg);
|
||||
# define irqchain_detach(irq, isr, arg) irq_detach(irq)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: irq_waitlock
|
||||
*
|
||||
* Description:
|
||||
* Spin to get g_irq_waitlock, handling a known deadlock condition:
|
||||
*
|
||||
* A deadlock may occur if enter_critical_section is called from an
|
||||
* interrupt handler. Suppose:
|
||||
*
|
||||
* - CPUn is in a critical section and has the g_cpu_irqlock spinlock.
|
||||
* - CPUm takes an interrupt and attempts to enter the critical section.
|
||||
* - It spins waiting on g_cpu_irqlock with interrupts disabled.
|
||||
* - CPUn calls up_cpu_pause() to pause operation on CPUm. This will
|
||||
* issue an inter-CPU interrupt to CPUm
|
||||
* - But interrupts are disabled on CPUm so the up_cpu_pause() is never
|
||||
* handled, causing the deadlock.
|
||||
*
|
||||
* This same deadlock can occur in the normal tasking case:
|
||||
*
|
||||
* - A task on CPUn enters a critical section and has the g_cpu_irqlock
|
||||
* spinlock.
|
||||
* - Another task on CPUm attempts to enter the critical section but has
|
||||
* to wait, spinning to get g_cpu_irqlock with interrupts disabled.
|
||||
* - The task on CPUn causes a new task to become ready-to-run and the
|
||||
* scheduler selects CPUm. CPUm is requested to pause via a pause
|
||||
* interrupt.
|
||||
* - But the task on CPUm is also attempting to enter the critical
|
||||
* section. Since it is spinning with interrupts disabled, CPUm cannot
|
||||
* process the pending pause interrupt, causing the deadlock.
|
||||
*
|
||||
* This function detects this deadlock condition while spinning with \
|
||||
* interrupts disabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The index of CPU that is trying to enter the critical section.
|
||||
*
|
||||
* Returned Value:
|
||||
* True: The g_cpu_irqlock spinlock has been taken.
|
||||
* False: The g_cpu_irqlock spinlock has not been taken yet, but there is
|
||||
* a pending pause interrupt request.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
bool irq_waitlock(int cpu);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: enter_critical_section
|
||||
*
|
||||
|
@ -105,7 +105,7 @@ volatile uint8_t g_cpu_nestcount[CONFIG_SMP_NCPUS];
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static inline bool irq_waitlock(int cpu)
|
||||
bool irq_waitlock(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
|
||||
FAR struct tcb_s *tcb = current_task(cpu);
|
||||
|
Loading…
Reference in New Issue
Block a user