diff --git a/cpukit/include/rtems/rtems/intr.h b/cpukit/include/rtems/rtems/intr.h index 0457c9f534..23bd164361 100644 --- a/cpukit/include/rtems/rtems/intr.h +++ b/cpukit/include/rtems/rtems/intr.h @@ -500,8 +500,53 @@ rtems_status_code rtems_interrupt_catch( * @ingroup RTEMSAPIClassicIntr * * @brief This structure represents an ISR lock. + * + * @par Notes + * @parblock + * Lock objects are only needed in some RTEMS build configurations, for example + * where the SMP support is enabled. The #RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT + * constant can be usused to determine whether a lock object is needded or not. + * This may help to reduce the memory demands of an application. All lock + * operations do not use the lock object parameter if lock objects are not + * needed. + * + * @code + * #include + * + * #if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT + * rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER( "name" ); + * #endif + * + * struct s { + * #if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT + * rtems_interrupt_lock lock; + * #endif + * int foobar; + * }; + * @endcode + * @endparblock */ -typedef ISR_lock_Control rtems_interrupt_lock; +#if ISR_LOCK_NEEDS_OBJECT + typedef ISR_lock_Control rtems_interrupt_lock; +#else + typedef char rtems_interrupt_lock; +#endif + +/* Generated from spec:/rtems/intr/if/lock-needs-object */ + +/** + * @ingroup RTEMSAPIClassicIntr + * + * @brief If this define has a non-zero value, then the interrupt lock + * operations require an object of type ::rtems_interrupt_lock, otherwise no + * lock object is required. + * + * @par Notes + * This indication can be used to avoid the space overhead for lock objects + * when they are not needed. In this case, the lock operations will not use a + * lock objects parameter. + */ +#define RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT ISR_LOCK_NEEDS_OBJECT /* Generated from spec:/rtems/intr/if/lock-context */ @@ -708,7 +753,7 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * * The directive will not cause the calling task to be preempted. * @endparblock */ -#if defined(RTEMS_SMP) +#if ISR_LOCK_NEEDS_OBJECT #define rtems_interrupt_lock_acquire_isr( _lock, _lock_context ) \ _SMP_lock_Acquire( \ &( _lock )->Lock, \ @@ -754,7 +799,7 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * * The directive will not cause the calling task to be preempted. * @endparblock */ -#if defined(RTEMS_SMP) +#if ISR_LOCK_NEEDS_OBJECT #define rtems_interrupt_lock_release_isr( _lock, _lock_context ) \ _SMP_lock_Release( \ &( _lock )->Lock, \ @@ -805,8 +850,12 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * @par Notes * Do not add a ";" after this macro. */ -#define RTEMS_INTERRUPT_LOCK_DECLARE( _specifier, _designator ) \ - ISR_LOCK_DECLARE( _specifier, _designator ) +#if ISR_LOCK_NEEDS_OBJECT + #define RTEMS_INTERRUPT_LOCK_DECLARE( _specifier, _designator ) \ + _specifier rtems_interrupt_lock _designator; +#else + #define RTEMS_INTERRUPT_LOCK_DECLARE( _specifier, _designator ) +#endif /* Generated from spec:/rtems/intr/if/lock-define */ @@ -832,8 +881,12 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * RTEMS_INTERRUPT_LOCK_INITIALIZER(). * @endparblock */ -#define RTEMS_INTERRUPT_LOCK_DEFINE( _specifier, _designator, _name ) \ - ISR_LOCK_DEFINE( _specifier, _designator, _name ) +#if ISR_LOCK_NEEDS_OBJECT + #define RTEMS_INTERRUPT_LOCK_DEFINE( _specifier, _designator, _name ) \ + _specifier rtems_interrupt_lock _designator = ISR_LOCK_INITIALIZER( _name ); +#else + #define RTEMS_INTERRUPT_LOCK_DEFINE( _specifier, _designator, _name ) +#endif /* Generated from spec:/rtems/intr/if/lock-initializer */ @@ -850,7 +903,11 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * rtems_interrupt_lock_initialize() or statically defined by * RTEMS_INTERRUPT_LOCK_DEFINE(). */ -#define RTEMS_INTERRUPT_LOCK_INITIALIZER( _name ) ISR_LOCK_INITIALIZER( _name ) +#if ISR_LOCK_NEEDS_OBJECT + #define RTEMS_INTERRUPT_LOCK_INITIALIZER( _name ) ISR_LOCK_INITIALIZER( _name ) +#else + #define RTEMS_INTERRUPT_LOCK_INITIALIZER( _name ) 0 +#endif /* Generated from spec:/rtems/intr/if/lock-member */ @@ -864,8 +921,12 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * @par Notes * Do not add a ";" after this macro. */ -#define RTEMS_INTERRUPT_LOCK_MEMBER( _designator ) \ - ISR_LOCK_MEMBER( _designator ) +#if ISR_LOCK_NEEDS_OBJECT + #define RTEMS_INTERRUPT_LOCK_MEMBER( _designator ) \ + rtems_interrupt_lock _designator; +#else + #define RTEMS_INTERRUPT_LOCK_MEMBER( _designator ) +#endif /* Generated from spec:/rtems/intr/if/lock-reference */ @@ -881,8 +942,12 @@ typedef ISR_lock_Context rtems_interrupt_lock_context; * @par Notes * Do not add a ";" after this macro. */ -#define RTEMS_INTERRUPT_LOCK_REFERENCE( _designator, _target ) \ - ISR_LOCK_REFERENCE( _designator, _target ) +#if ISR_LOCK_NEEDS_OBJECT + #define RTEMS_INTERRUPT_LOCK_REFERENCE( _designator, _target ) \ + rtems_interrupt_lock *_designator = _target; +#else + #define RTEMS_INTERRUPT_LOCK_REFERENCE( _designator, _target ) +#endif /* Generated from spec:/rtems/intr/if/shared */ diff --git a/cpukit/include/rtems/score/isrlock.h b/cpukit/include/rtems/score/isrlock.h index d411e30c6d..230650ebc8 100644 --- a/cpukit/include/rtems/score/isrlock.h +++ b/cpukit/include/rtems/score/isrlock.h @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2013, 2019 embedded brains GmbH & Co. KG + * Copyright (C) 2013, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -63,6 +63,22 @@ extern "C" { * @{ */ +/** + * @brief If this define has a non-zero value, then the interrupt lock + * operations require an object of type ::ISR_lock_Control, otherwise no + * lock object is required. + * + * @par Notes + * This indication can be used to avoid the space overhead for lock objects + * when they are not needed. In this case, the lock operations will not use a + * lock objects parameter. + */ +#if defined( RTEMS_SMP ) + #define ISR_LOCK_NEEDS_OBJECT 1 +#else + #define ISR_LOCK_NEEDS_OBJECT 0 +#endif + /** * @brief ISR lock control. * diff --git a/testsuites/validation/tc-intr-non-smp.c b/testsuites/validation/tc-intr-non-smp.c index 909301bc62..d4c907c3fe 100644 --- a/testsuites/validation/tc-intr-non-smp.c +++ b/testsuites/validation/tc-intr-non-smp.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -69,6 +69,9 @@ * * - Validate some interrupt lock macros. * + * - Assert that RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT is a constant expression + * which evaluates to a value of zero. + * * - Check that RTEMS_INTERRUPT_LOCK_DECLARE() expands to white space only. * * - Check that RTEMS_INTERRUPT_LOCK_DEFINE() expands to white space only. @@ -79,8 +82,8 @@ * * - Check that rtems_interrupt_lock_destroy() expands to white space only. * - * - Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to an empty - * structure initializer. + * - Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to a character + * literal initializer. * * - Check that rtems_interrupt_lock_initialize() expands to a code block * which marks the second parameter as used. @@ -101,6 +104,12 @@ static void RtemsIntrValIntrNonSmp_Action_0( void ) { const char *s; + /* + * Assert that RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT is a constant expression + * which evaluates to a value of zero. + */ + RTEMS_STATIC_ASSERT( !RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT, LOCK_NEEDS_OBJECT ); + /* * Check that RTEMS_INTERRUPT_LOCK_DECLARE() expands to white space only. */ @@ -132,11 +141,11 @@ static void RtemsIntrValIntrNonSmp_Action_0( void ) T_true( IsWhiteSpaceOnly( s ) ); /* - * Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to an empty - * structure initializer. + * Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to a character + * literal initializer. */ s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_INITIALIZER( x ) ); - T_true( IsEqualIgnoreWhiteSpace( s, "{}" ) ); + T_true( IsEqualIgnoreWhiteSpace( s, "0" ) ); /* * Check that rtems_interrupt_lock_initialize() expands to a code block which diff --git a/testsuites/validation/tc-intr-smp-only.c b/testsuites/validation/tc-intr-smp-only.c index 4d1f64b699..31c6bd2470 100644 --- a/testsuites/validation/tc-intr-smp-only.c +++ b/testsuites/validation/tc-intr-smp-only.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -69,6 +69,9 @@ * * - Validate the interrupt lock directives. * + * - Assert that RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT is a constant expression + * which evaluates to a non-zero value. + * * - Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expanded to a lock reference * definition. Check that the lock is available after static * initialization. @@ -125,6 +128,12 @@ static void RtemsIntrValIntrSmpOnly_Action_0( void ) RTEMS_INTERRUPT_LOCK_REFERENCE( ref, &the_lock ) rtems_interrupt_lock_context lock_context; + /* + * Assert that RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT is a constant expression + * which evaluates to a non-zero value. + */ + RTEMS_STATIC_ASSERT( RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT, LOCK_NEEDS_OBJECT ); + /* * Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expanded to a lock reference * definition. Check that the lock is available after static initialization.