diff --git a/include/nuttx/irq.h b/include/nuttx/irq.h index 43b9992cfd..519059c7f6 100644 --- a/include/nuttx/irq.h +++ b/include/nuttx/irq.h @@ -40,8 +40,11 @@ * Included Files ****************************************************************************/ +#include + #ifndef __ASSEMBLY__ # include +# include #endif /**************************************************************************** @@ -97,6 +100,43 @@ extern "C" int irq_attach(int irq, xcpt_t isr); +/**************************************************************************** + * Name: enter_critical_section + * + * Description: + * If SMP is enabled: + * Take the CPU IRQ lock and disable interrupts on all CPUs. A thread- + * specific counter is increment to indicate that the thread has IRQs + * disabled and to support nested calls to enter_critical_section(). + * If SMP is not enabled: + * This function is equivalent to irqsave(). + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +irqstate_t enter_critical_section(void); +#else +# define enter_critical_section(f) irqsave(f) +#endif + +/**************************************************************************** + * Name: leave_critical_section + * + * Description: + * If SMP is enabled: + * Decrement the IRQ lock count and if it decrements to zero then release + * the spinlock. + * If SMP is not enabled: + * This function is equivalent to irqrestore(). + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +void leave_critical_section(irqstate_t flags); +#else +# define leave_critical_section(f) irqrestore(f) +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index a0f3d13792..cade6cde3e 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -560,6 +560,9 @@ struct tcb_s #endif uint16_t flags; /* Misc. general status flags */ int16_t lockcount; /* 0=preemptable (not-locked) */ +#ifdef CONFIG_SMP + int16_t irqcount; /* 0=interrupts enabled */ +#endif #if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) int32_t timeslice; /* RR timeslice OR Sporadic budget */ diff --git a/include/nuttx/spinlock.h b/include/nuttx/spinlock.h index 9305c40d50..ad034fa650 100644 --- a/include/nuttx/spinlock.h +++ b/include/nuttx/spinlock.h @@ -103,7 +103,7 @@ spinlock_t up_testset(volatile FAR spinlock_t *lock); * Name: spin_initialize * * Description: - * Initialize a spinlock object to its initial, unlocked state. + * Initialize a non-reentrant spinlock object to its initial, unlocked state. * * Input Parameters: * lock - A reference to the spinlock object to be initialized. @@ -113,7 +113,24 @@ spinlock_t up_testset(volatile FAR spinlock_t *lock); * ****************************************************************************/ -void spin_initialize(FAR struct spinlock_s *lock); +/* void spin_initialize(FAR spinlock_t *lock); */ +#define spin_initialize(i) do { (l) = SPI_UNLOCKED; } while (0) + +/**************************************************************************** + * Name: spin_initializer + * + * Description: + * Initialize a re-entrant spinlock object to its initial, unlocked state. + * + * Input Parameters: + * lock - A reference to the spinlock object to be initialized. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void spin_initializer(FAR struct spinlock_s *lock); /**************************************************************************** * Name: spin_lock diff --git a/sched/irq/Make.defs b/sched/irq/Make.defs index 706569f66b..905720750e 100644 --- a/sched/irq/Make.defs +++ b/sched/irq/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # sched/irq/Make.defs # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -35,6 +35,10 @@ CSRCS += irq_initialize.c irq_attach.c irq_dispatch.c irq_unexpectedisr.c +ifeq ($(CONFIG_SMP),y) +CSRCS += irq_csection.c +endif + # Include irq build support DEPPATH += --dep-path irq diff --git a/sched/irq/irq.h b/sched/irq/irq.h index 2e0269243b..d2c6321968 100644 --- a/sched/irq/irq.h +++ b/sched/irq/irq.h @@ -41,25 +41,31 @@ ****************************************************************************/ #include +#include #include #include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Type Declarations - ****************************************************************************/ - -extern FAR xcpt_t g_irqvector[NR_IRQS+1]; +#include /**************************************************************************** * Public Data ****************************************************************************/ +/* This is the list of interrupt handlers, one for each IRQ. This is used + * by irq_dispatch to transfer control to interrupt handlers after the + * occurrence of an interrupt. + */ + +extern FAR xcpt_t g_irqvector[NR_IRQS+1]; + +#ifdef CONFIG_SMP +/* This is the spinlock that enforces critical sections when interrupts are + * disabled. + */ + +extern spinlock_t g_cpu_irqlock; +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/sched/irq/irq_initialize.c b/sched/irq/irq_initialize.c index 9043260914..d558ff97e1 100644 --- a/sched/irq/irq_initialize.c +++ b/sched/irq/irq_initialize.c @@ -43,28 +43,12 @@ #include "irq/irq.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ FAR xcpt_t g_irqvector[NR_IRQS+1]; -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -88,4 +72,3 @@ void irq_initialize(void) g_irqvector[i] = irq_unexpected_isr; } } - diff --git a/sched/semaphore/spinlock.c b/sched/semaphore/spinlock.c index b5396273a8..7b12ffaf18 100644 --- a/sched/semaphore/spinlock.c +++ b/sched/semaphore/spinlock.c @@ -68,10 +68,10 @@ ****************************************************************************/ /**************************************************************************** - * Name: spin_initialize + * Name: spin_initializer * * Description: - * Initialize a spinlock object to its initial, unlocked state. + * Initialize a re-entrant spinlock object to its initial, unlocked state. * * Input Parameters: * lock - A reference to the spinlock object to be initialized. @@ -81,7 +81,7 @@ * ****************************************************************************/ -void spin_initialize(FAR struct spinlock_s *lock) +void spin_initializer(FAR struct spinlock_s *lock) { DEBUGASSERT(lock != NULL);