diff --git a/include/nuttx/irq.h b/include/nuttx/irq.h index 0c94f71a3a..e978c270ee 100644 --- a/include/nuttx/irq.h +++ b/include/nuttx/irq.h @@ -258,9 +258,19 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg); ****************************************************************************/ #ifdef CONFIG_IRQCOUNT + +# if (defined(CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION) && \ + CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0) || \ + defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) irqstate_t enter_critical_section(void) noinstrument_function; +# else +# define enter_critical_section() enter_critical_section_wo_note() +# endif + +irqstate_t enter_critical_section_wo_note(void) noinstrument_function; #else # define enter_critical_section() up_irq_save() +# define enter_critical_section_wo_note() up_irq_save() #endif /**************************************************************************** @@ -288,9 +298,19 @@ irqstate_t enter_critical_section(void) noinstrument_function; ****************************************************************************/ #ifdef CONFIG_IRQCOUNT + +# if (defined(CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION) && \ + CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0) || \ + defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) void leave_critical_section(irqstate_t flags) noinstrument_function; +# else +# define leave_critical_section(f) leave_critical_section_wo_note(f) +# endif + +void leave_critical_section_wo_note(irqstate_t flags) noinstrument_function; #else # define leave_critical_section(f) up_irq_restore(f) +# define leave_critical_section_wo_note(f) up_irq_restore(f) #endif /**************************************************************************** diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index b8277c758f..c1b239e55a 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -80,7 +80,7 @@ volatile uint8_t g_cpu_nestcount[CONFIG_SMP_NCPUS]; ****************************************************************************/ /**************************************************************************** - * Name: enter_critical_section + * Name: enter_critical_section_wo_note * * Description: * Take the CPU IRQ lock and disable interrupts on all CPUs. A thread- @@ -90,7 +90,7 @@ volatile uint8_t g_cpu_nestcount[CONFIG_SMP_NCPUS]; ****************************************************************************/ #ifdef CONFIG_SMP -irqstate_t enter_critical_section(void) +irqstate_t enter_critical_section_wo_note(void) { FAR struct tcb_s *rtcb; irqstate_t ret; @@ -246,15 +246,6 @@ irqstate_t enter_critical_section(void) cpu_irqlock_set(cpu); rtcb->irqcount = 1; - - /* Note that we have entered the critical section */ - -#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 - nxsched_critmon_csection(rtcb, true, return_address(0)); -#endif -#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - sched_note_csection(rtcb, true); -#endif } } @@ -265,7 +256,7 @@ irqstate_t enter_critical_section(void) #else -irqstate_t enter_critical_section(void) +irqstate_t enter_critical_section_wo_note(void) { irqstate_t ret; @@ -285,10 +276,28 @@ irqstate_t enter_critical_section(void) */ DEBUGASSERT(rtcb->irqcount >= 0 && rtcb->irqcount < INT16_MAX); - if (++rtcb->irqcount == 1) - { - /* Note that we have entered the critical section */ + rtcb->irqcount++; + } + /* Return interrupt status */ + + return ret; +} +#endif + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 ||\ + defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) +irqstate_t enter_critical_section(void) +{ + FAR struct tcb_s *rtcb; + irqstate_t flags; + flags = enter_critical_section_wo_note(); + + if (!up_interrupt_context()) + { + rtcb = this_task(); + if (rtcb->irqcount == 1) + { #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 nxsched_critmon_csection(rtcb, true, return_address(0)); #endif @@ -298,14 +307,12 @@ irqstate_t enter_critical_section(void) } } - /* Return interrupt status */ - - return ret; + return flags; } #endif /**************************************************************************** - * Name: leave_critical_section + * Name: leave_critical_section_wo_note * * Description: * Decrement the IRQ lock count and if it decrements to zero then release @@ -314,7 +321,7 @@ irqstate_t enter_critical_section(void) ****************************************************************************/ #ifdef CONFIG_SMP -void leave_critical_section(irqstate_t flags) +void leave_critical_section_wo_note(irqstate_t flags) { int cpu; @@ -388,14 +395,6 @@ void leave_critical_section(irqstate_t flags) } else { - /* No.. Note that we have left the critical section */ - -#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 - nxsched_critmon_csection(rtcb, false, return_address(0)); -#endif -#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - sched_note_csection(rtcb, false); -#endif /* Decrement our count on the lock. If all CPUs have * released, then unlock the spinlock. */ @@ -421,10 +420,8 @@ void leave_critical_section(irqstate_t flags) up_irq_restore(flags); } - #else - -void leave_critical_section(irqstate_t flags) +void leave_critical_section_wo_note(irqstate_t flags) { /* Check if we were called from an interrupt handler and that the tasks * lists have been initialized. @@ -440,17 +437,7 @@ void leave_critical_section(irqstate_t flags) */ DEBUGASSERT(rtcb->irqcount > 0); - if (--rtcb->irqcount <= 0) - { - /* Note that we have left the critical section */ - -#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 - nxsched_critmon_csection(rtcb, false, return_address(0)); -#endif -#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - sched_note_csection(rtcb, false); -#endif - } + --rtcb->irqcount; } /* Restore the previous interrupt state. */ @@ -458,4 +445,29 @@ void leave_critical_section(irqstate_t flags) up_irq_restore(flags); } #endif + +#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 ||\ + defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) +void leave_critical_section(irqstate_t flags) +{ + FAR struct tcb_s *rtcb; + + if (!up_interrupt_context()) + { + rtcb = this_task(); + if (rtcb->irqcount == 1) + { +# if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 + nxsched_critmon_csection(rtcb, false, return_address(0)); +# endif +# ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION + sched_note_csection(rtcb, false); +# endif + } + } + + leave_critical_section_wo_note(flags); +} +#endif + #endif /* CONFIG_IRQCOUNT */