mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
sched: irq: Change irq_waitlock() from private to public
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
committed by
Alin Jerpelea
parent
8d0118569c
commit
a24905059e
@@ -46,6 +46,9 @@
|
|||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
# ifdef CONFIG_SMP
|
||||||
|
# include <stdbool.h>
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Now include architecture-specific types */
|
/* 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)
|
# define irqchain_detach(irq, isr, arg) irq_detach(irq)
|
||||||
#endif
|
#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
|
* Name: enter_critical_section
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ volatile uint8_t g_cpu_nestcount[CONFIG_SMP_NCPUS];
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static inline bool irq_waitlock(int cpu)
|
bool irq_waitlock(int cpu)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
|
||||||
FAR struct tcb_s *tcb = current_task(cpu);
|
FAR struct tcb_s *tcb = current_task(cpu);
|
||||||
|
|||||||
Reference in New Issue
Block a user