SMP: Implement enter/leave_critical_section

This commit is contained in:
Gregory Nutt 2016-02-13 10:23:16 -06:00
parent 8ac699b63d
commit 97cbd7112f
7 changed files with 87 additions and 34 deletions

View File

@ -40,8 +40,11 @@
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <assert.h>
# include <arch/irq.h>
#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
}

View File

@ -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 */

View File

@ -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

View File

@ -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 <gnutt@nuttx.org>
#
# 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

View File

@ -41,25 +41,31 @@
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/compiler.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Type Declarations
****************************************************************************/
extern FAR xcpt_t g_irqvector[NR_IRQS+1];
#include <nuttx/spinlock.h>
/****************************************************************************
* 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
****************************************************************************/

View File

@ -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;
}
}

View File

@ -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);