[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