[PATCH 2/9] rtems: Add interrupt locks
Gedare Bloom
gedare at rtems.org
Mon Jun 10 13:51:21 UTC 2013
The new directives could use documentation in doc/user/intr.t
On Mon, Jun 10, 2013 at 9:11 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> Interrupt locks are low-level lock to protect critical sections accessed
> by threads and interrupt service routines.
> ---
> cpukit/rtems/include/rtems/rtems/intr.h | 135 +++++++++++++++++++++++++++++++
> testsuites/sptests/sp37/init.c | 17 ++++
> 2 files changed, 152 insertions(+), 0 deletions(-)
>
> diff --git a/cpukit/rtems/include/rtems/rtems/intr.h b/cpukit/rtems/include/rtems/rtems/intr.h
> index ea6dc6b..d687e46 100644
> --- a/cpukit/rtems/include/rtems/rtems/intr.h
> +++ b/cpukit/rtems/include/rtems/rtems/intr.h
> @@ -26,6 +26,7 @@ extern "C" {
> #endif
>
> #include <rtems/score/isr.h>
> +#include <rtems/score/smplock.h>
>
> /**
> * @defgroup ClassicINTR Interrupts
> @@ -134,6 +135,140 @@ rtems_status_code rtems_interrupt_catch(
> */
> #define rtems_interrupt_clear( _interrupt_to_clear )
>
> +/**
> + * @defgroup ClassicINTRLocks Interrupt Locks
> + *
> + * @ingroup ClassicINTR
> + *
> + * @brief Low-level lock to protect critical sections accessed by threads and
> + * interrupt service routines.
> + *
> + * This synchronization primitive is supported on SMP configurations.
> + *
> + * @{
> + */
> +
> +/**
> + * @brief Interrupt lock control.
> + */
> +typedef struct {
> + #if defined( RTEMS_SMP )
> + SMP_lock_Control lock;
> + #endif
> +} rtems_interrupt_lock;
> +
> +/**
> + * @brief Initializer for static initialization of interrupt locks.
> + */
> +#if defined( RTEMS_SMP )
> + #define RTEMS_INTERRUPT_LOCK_INITIALIZER \
> + { SMP_LOCK_INITIALIZER }
> +#else
> + #define RTEMS_INTERRUPT_LOCK_INITIALIZER \
> + { }
> +#endif
> +
> +/**
> + * @brief Initializes an interrupt lock.
> + *
> + * Concurrent initialization leads to unpredictable results.
> + */
> +#if defined( RTEMS_SMP )
> + #define rtems_interrupt_lock_initialize( _lock ) \
> + _SMP_lock_Initialize( &( _lock )->lock )
> +#else
> + #define rtems_interrupt_lock_initialize( _lock ) \
> + do { \
> + (void) _lock; \
> + } while (0)
> +#endif
> +
> +/**
> + * @brief Acquires an interrupt lock.
> + *
> + * Interrupts will be disabled. On SMP configurations this function acquires a
> + * SMP lock.
> + *
> + * This function can be used in thread and interrupt context.
> + *
> + * @see rtems_interrupt_lock_release().
> + */
> +#if defined( RTEMS_SMP )
> + #define rtems_interrupt_lock_acquire( _lock, _isr_cookie ) \
> + _SMP_lock_ISR_disable_and_acquire( &( _lock )->lock, _isr_cookie )
> +#else
> + #define rtems_interrupt_lock_acquire( _lock, _isr_cookie ) \
> + do { \
> + (void) _lock; \
> + rtems_interrupt_disable( _isr_cookie ); \
> + } while (0)
> +#endif
> +
> +/**
> + * @brief Releases an interrupt lock.
> + *
> + * The interrupt status will be restored. On SMP configurations this function
> + * releases a SMP lock.
> + *
> + * This function can be used in thread and interrupt context.
> + *
> + * @see rtems_interrupt_lock_acquire().
> + */
> +#if defined( RTEMS_SMP )
> + #define rtems_interrupt_lock_release( _lock, _isr_cookie ) \
> + _SMP_lock_Release_and_ISR_enable( &( _lock )->lock, _isr_cookie )
> +#else
> + #define rtems_interrupt_lock_release( _lock, _isr_cookie ) \
> + do { \
> + (void) _lock; \
> + rtems_interrupt_enable( _isr_cookie ); \
> + } while (0)
> +#endif
> +
> +/**
> + * @brief Acquires an interrupt lock in the corresponding interrupt service
> + * routine.
> + *
> + * The interrupt status will remain unchanged. On SMP configurations this
> + * function acquires a SMP lock.
> + *
> + * In case the corresponding interrupt service routine can be interrupted by
> + * higher priority interrupts and these interrupts enter the critical section
> + * protected by this lock, then the result is unpredictable.
> + *
> + * @see rtems_interrupt_lock_release_isr().
> + */
> +#if defined( RTEMS_SMP )
> + #define rtems_interrupt_lock_acquire_isr( _lock ) \
> + _SMP_lock_Acquire( &( _lock )->lock )
> +#else
> + #define rtems_interrupt_lock_acquire_isr( _lock ) \
> + do { \
> + (void) _lock; \
> + } while (0)
> +#endif
> +
> +/**
> + * @brief Releases an interrupt lock in the corresponding interrupt service
> + * routine.
> + *
> + * The interrupt status will remain unchanged. On SMP configurations this
> + * function releases a SMP lock.
> + *
> + * @see rtems_interrupt_lock_acquire_isr().
> + */
> +#if defined( RTEMS_SMP )
> + #define rtems_interrupt_lock_release_isr( _lock ) \
> + _SMP_lock_Release( &( _lock )->lock )
> +#else
> + #define rtems_interrupt_lock_release_isr( _lock ) \
> + do { \
> + (void) _lock; \
> + } while (0)
> +#endif
> +
> +/** @} */
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/testsuites/sptests/sp37/init.c b/testsuites/sptests/sp37/init.c
> index 870316a..956c91d 100644
> --- a/testsuites/sptests/sp37/init.c
> +++ b/testsuites/sptests/sp37/init.c
> @@ -43,6 +43,21 @@ rtems_timer_service_routine test_isr_in_progress(
> );
>
> /* test bodies */
> +
> +static void test_interrupt_locks( void )
> +{
> + rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
> + rtems_interrupt_level level;
> +
> + rtems_interrupt_lock_initialize( &lock );
> +
> + rtems_interrupt_lock_acquire( &lock, level );
> + rtems_interrupt_lock_release( &lock, level );
> +
> + rtems_interrupt_lock_acquire_isr( &lock );
> + rtems_interrupt_lock_release_isr( &lock );
> +}
> +
> void test_interrupt_inline(void)
> {
> rtems_interrupt_level level;
> @@ -318,6 +333,8 @@ rtems_task Init(
>
> check_isr_worked( "body", isr_in_progress_body );
>
> + test_interrupt_locks();
> +
> puts( "*** END OF TEST 37 ***" );
> rtems_test_exit( 0 );
> }
> --
> 1.7.7
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel
More information about the devel
mailing list