From d811daca691e1fe9e8166fe20118148442f266a1 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 25 Jun 2015 11:24:44 +0200 Subject: score: Hide SMP lock profiling impl if disabled The problem is that empty structures have a different size in C and C++. --- cpukit/score/include/rtems/score/percpu.h | 17 ++- cpukit/score/include/rtems/score/smplock.h | 175 ++++++++++++++++++----------- cpukit/score/src/profilingsmplock.c | 18 +-- cpukit/score/src/smp.c | 3 +- testsuites/sptests/sp37/init.c | 4 +- 5 files changed, 133 insertions(+), 84 deletions(-) diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h index a6f7a25cc6..088c31f916 100644 --- a/cpukit/score/include/rtems/score/percpu.h +++ b/cpukit/score/include/rtems/score/percpu.h @@ -319,10 +319,17 @@ typedef struct Per_CPU_Control { */ SMP_ticket_lock_Control Lock; - /** - * @brief Lock statistics context for the per-CPU lock. - */ - SMP_lock_Stats_context Lock_stats_context; + #if defined( RTEMS_PROFILING ) + /** + * @brief Lock statistics for the per-CPU lock. + */ + SMP_lock_Stats Lock_stats; + + /** + * @brief Lock statistics context for the per-CPU lock. + */ + SMP_lock_Stats_context Lock_stats_context; + #endif /** * @brief Context for the Giant lock acquire and release pair of this @@ -385,6 +392,7 @@ extern Per_CPU_Control_envelope _Per_CPU_Information[] CPU_STRUCTURE_ALIGNMENT; #define _Per_CPU_Acquire( cpu ) \ _SMP_ticket_lock_Acquire( \ &( cpu )->Lock, \ + &( cpu )->Lock_stats, \ &( cpu )->Lock_stats_context \ ) #else @@ -398,6 +406,7 @@ extern Per_CPU_Control_envelope _Per_CPU_Information[] CPU_STRUCTURE_ALIGNMENT; #define _Per_CPU_Release( cpu ) \ _SMP_ticket_lock_Release( \ &( cpu )->Lock, \ + &( cpu )->Lock_stats, \ &( cpu )->Lock_stats_context \ ) #else diff --git a/cpukit/score/include/rtems/score/smplock.h b/cpukit/score/include/rtems/score/smplock.h index 50a0662ca9..da510d17ea 100644 --- a/cpukit/score/include/rtems/score/smplock.h +++ b/cpukit/score/include/rtems/score/smplock.h @@ -58,6 +58,8 @@ extern "C" { * @{ */ +#if defined( RTEMS_PROFILING ) + /** * @brief Count of lock contention counters for lock statistics. */ @@ -82,7 +84,6 @@ extern "C" { * instant and the lock acquire instant. */ typedef struct { -#if defined( RTEMS_PROFILING ) /** * @brief Node for SMP lock statistics chain. */ @@ -142,33 +143,25 @@ typedef struct { * @brief The lock name. */ const char *name; -#endif /* defined( RTEMS_PROFILING ) */ } SMP_lock_Stats; /** * @brief Local context for SMP lock statistics. */ typedef struct { -#if defined( RTEMS_PROFILING ) /** * @brief The last lock acquire instant in CPU counter ticks. * * This value is used to measure the lock section time. */ CPU_Counter_ticks acquire_instant; -#endif } SMP_lock_Stats_context; /** * @brief SMP lock statistics initializer for static initialization. */ -#if defined( RTEMS_PROFILING ) #define SMP_LOCK_STATS_INITIALIZER( name ) \ { { NULL, NULL }, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, name } -#else -#define SMP_LOCK_STATS_INITIALIZER( name ) \ - { } -#endif /** * @brief Initializes an SMP lock statistics block. @@ -190,14 +183,14 @@ static inline void _SMP_lock_Stats_initialize( /** * @brief Destroys an SMP lock statistics block. * - * @param[in,out] stats The SMP lock statistics block. + * @param[in] stats The SMP lock statistics block. */ static inline void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats ); /** * @brief Destroys an SMP lock statistics block. * - * @param[in,out] stats The SMP lock statistics block. + * @param[in] stats The SMP lock statistics block. * @param[in] stats_context The SMP lock statistics context. */ static inline void _SMP_lock_Stats_release_update( @@ -205,23 +198,29 @@ static inline void _SMP_lock_Stats_release_update( const SMP_lock_Stats_context *stats_context ); +#else /* RTEMS_PROFILING */ + +#define _SMP_lock_Stats_initialize( stats, name ) do { } while ( 0 ) + +#define _SMP_lock_Stats_destroy( stats ) do { } while ( 0 ) + +#endif /* RTEMS_PROFILING */ + /** * @brief SMP ticket lock control. */ typedef struct { Atomic_Uint next_ticket; Atomic_Uint now_serving; - SMP_lock_Stats Stats; } SMP_ticket_lock_Control; /** * @brief SMP ticket lock control initializer for static initialization. */ -#define SMP_TICKET_LOCK_INITIALIZER( name ) \ +#define SMP_TICKET_LOCK_INITIALIZER \ { \ ATOMIC_INITIALIZER_UINT( 0U ), \ - ATOMIC_INITIALIZER_UINT( 0U ), \ - SMP_LOCK_STATS_INITIALIZER( name ) \ + ATOMIC_INITIALIZER_UINT( 0U ) \ } /** @@ -229,18 +228,16 @@ typedef struct { * * Concurrent initialization leads to unpredictable results. * - * @param[in,out] lock The SMP ticket lock control. + * @param[in] lock The SMP ticket lock control. * @param[in] name The name for the SMP ticket lock. This name must be * persistent throughout the life time of this lock. */ static inline void _SMP_ticket_lock_Initialize( - SMP_ticket_lock_Control *lock, - const char *name + SMP_ticket_lock_Control *lock ) { _Atomic_Init_uint( &lock->next_ticket, 0U ); _Atomic_Init_uint( &lock->now_serving, 0U ); - _SMP_lock_Stats_initialize( &lock->Stats, name ); } /** @@ -248,33 +245,26 @@ static inline void _SMP_ticket_lock_Initialize( * * Concurrent destruction leads to unpredictable results. * - * @param[in,out] lock The SMP ticket lock control. + * @param[in] lock The SMP ticket lock control. */ static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock ) { - _SMP_lock_Stats_destroy( &lock->Stats ); + (void) lock; } -/** - * @brief Acquires an SMP ticket lock. - * - * This function will not disable interrupts. The caller must ensure that the - * current thread of execution is not interrupted indefinite once it obtained - * the SMP ticket lock. - * - * @param[in,out] lock The SMP ticket lock control. - * @param[out] stats_context The SMP lock statistics context. - */ -static inline void _SMP_ticket_lock_Acquire( - SMP_ticket_lock_Control *lock, +static inline void _SMP_ticket_lock_Do_acquire( + SMP_ticket_lock_Control *lock +#if defined( RTEMS_PROFILING ) + , + SMP_lock_Stats *stats, SMP_lock_Stats_context *stats_context +#endif ) { unsigned int my_ticket; unsigned int now_serving; #if defined( RTEMS_PROFILING ) - SMP_lock_Stats *stats = &lock->Stats; CPU_Counter_ticks first; CPU_Counter_ticks second; CPU_Counter_ticks delta; @@ -318,36 +308,71 @@ static inline void _SMP_ticket_lock_Acquire( initial_queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1; } ++stats->contention_counts[initial_queue_length]; -#else - (void) stats_context; #endif } /** - * @brief Releases an SMP ticket lock. + * @brief Acquires an SMP ticket lock. * - * @param[in,out] lock The SMP ticket lock control. - * @param[in] stats_context The SMP lock statistics context. + * This function will not disable interrupts. The caller must ensure that the + * current thread of execution is not interrupted indefinite once it obtained + * the SMP ticket lock. + * + * @param[in] lock The SMP ticket lock control. + * @param[in] stats The SMP lock statistics. + * @param[out] stats_context The SMP lock statistics context. */ -static inline void _SMP_ticket_lock_Release( - SMP_ticket_lock_Control *lock, +#if defined( RTEMS_PROFILING ) + #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \ + _SMP_ticket_lock_Do_acquire( lock, stats, stats_context ) +#else + #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \ + _SMP_ticket_lock_Do_acquire( lock ) +#endif + +static inline void _SMP_ticket_lock_Do_release( + SMP_ticket_lock_Control *lock +#if defined( RTEMS_PROFILING ) + , + SMP_lock_Stats *stats, const SMP_lock_Stats_context *stats_context +#endif ) { unsigned int current_ticket = _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED ); unsigned int next_ticket = current_ticket + 1U; - _SMP_lock_Stats_release_update( &lock->Stats, stats_context ); +#if defined( RTEMS_PROFILING ) + _SMP_lock_Stats_release_update( stats, stats_context ); +#endif _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE ); } +/** + * @brief Releases an SMP ticket lock. + * + * @param[in] lock The SMP ticket lock control. + * @param[in] stats The SMP lock statistics. + * @param[in] stats_context The SMP lock statistics context. + */ +#if defined( RTEMS_PROFILING ) + #define _SMP_ticket_lock_Release( lock, stats, stats_context ) \ + _SMP_ticket_lock_Do_release( lock, stats, stats_context ) +#else + #define _SMP_ticket_lock_Release( lock, stats, stats_context ) \ + _SMP_ticket_lock_Do_release( lock ) +#endif + /** * @brief SMP lock control. */ typedef struct { - SMP_ticket_lock_Control ticket_lock; + SMP_ticket_lock_Control Ticket_lock; +#if defined( RTEMS_PROFILING ) + SMP_lock_Stats Stats; +#endif } SMP_lock_Control; /** @@ -355,20 +380,27 @@ typedef struct { */ typedef struct { ISR_Level isr_level; +#if defined( RTEMS_PROFILING ) SMP_lock_Stats_context Stats_context; +#endif } SMP_lock_Context; /** * @brief SMP lock control initializer for static initialization. */ -#define SMP_LOCK_INITIALIZER( name ) { SMP_TICKET_LOCK_INITIALIZER( name ) } +#if defined( RTEMS_PROFILING ) + #define SMP_LOCK_INITIALIZER( name ) \ + { SMP_TICKET_LOCK_INITIALIZER, SMP_LOCK_STATS_INITIALIZER( name ) } +#else + #define SMP_LOCK_INITIALIZER( name ) { SMP_TICKET_LOCK_INITIALIZER } +#endif /** * @brief Initializes an SMP lock. * * Concurrent initialization leads to unpredictable results. * - * @param[in,out] lock The SMP lock control. + * @param[in] lock The SMP lock control. * @param[in] name The name for the SMP lock statistics. This name must be * persistent throughout the life time of this statistics block. */ @@ -386,7 +418,12 @@ static inline void _SMP_lock_Initialize( const char *name ) { - _SMP_ticket_lock_Initialize( &lock->ticket_lock, name ); + _SMP_ticket_lock_Initialize( &lock->Ticket_lock ); +#if defined( RTEMS_PROFILING ) + _SMP_lock_Stats_initialize( &lock->Stats, name ); +#else + (void) name; +#endif } /** @@ -394,7 +431,7 @@ static inline void _SMP_lock_Initialize( * * Concurrent destruction leads to unpredictable results. * - * @param[in,out] lock The SMP lock control. + * @param[in] lock The SMP lock control. */ #if defined( RTEMS_SMP_LOCK_DO_NOT_INLINE ) void _SMP_lock_Destroy( SMP_lock_Control *lock ); @@ -404,7 +441,8 @@ static inline void _SMP_lock_Destroy_body( SMP_lock_Control *lock ) static inline void _SMP_lock_Destroy( SMP_lock_Control *lock ) #endif { - _SMP_ticket_lock_Destroy( &lock->ticket_lock ); + _SMP_ticket_lock_Destroy( &lock->Ticket_lock ); + _SMP_lock_Stats_destroy( &lock->Stats ); } /** @@ -414,8 +452,8 @@ static inline void _SMP_lock_Destroy( SMP_lock_Control *lock ) * current thread of execution is not interrupted indefinite once it obtained * the SMP lock. * - * @param[in,out] lock The SMP lock control. - * @param[in,out] context The local SMP lock context for an acquire and release + * @param[in] lock The SMP lock control. + * @param[in] context The local SMP lock context for an acquire and release * pair. */ #if defined( RTEMS_SMP_LOCK_DO_NOT_INLINE ) @@ -433,14 +471,18 @@ static inline void _SMP_lock_Acquire( ) { (void) context; - _SMP_ticket_lock_Acquire( &lock->ticket_lock, &context->Stats_context ); + _SMP_ticket_lock_Acquire( + &lock->Ticket_lock, + &lock->Stats, + &context->Stats_context + ); } /** * @brief Releases an SMP lock. * - * @param[in,out] lock The SMP lock control. - * @param[in,out] context The local SMP lock context for an acquire and release + * @param[in] lock The SMP lock control. + * @param[in] context The local SMP lock context for an acquire and release * pair. */ #if defined( RTEMS_SMP_LOCK_DO_NOT_INLINE ) @@ -458,14 +500,18 @@ static inline void _SMP_lock_Release( ) { (void) context; - _SMP_ticket_lock_Release( &lock->ticket_lock, &context->Stats_context ); + _SMP_ticket_lock_Release( + &lock->Ticket_lock, + &lock->Stats, + &context->Stats_context + ); } /** * @brief Disables interrupts and acquires the SMP lock. * - * @param[in,out] lock The SMP lock control. - * @param[in,out] context The local SMP lock context for an acquire and release + * @param[in] lock The SMP lock control. + * @param[in] context The local SMP lock context for an acquire and release * pair. */ #if defined( RTEMS_SMP_LOCK_DO_NOT_INLINE ) @@ -489,8 +535,8 @@ static inline void _SMP_lock_ISR_disable_and_acquire( /** * @brief Releases the SMP lock and enables interrupts. * - * @param[in,out] lock The SMP lock control. - * @param[in,out] context The local SMP lock context for an acquire and release + * @param[in] lock The SMP lock control. + * @param[in] context The local SMP lock context for an acquire and release * pair. */ #if defined( RTEMS_SMP_LOCK_DO_NOT_INLINE ) @@ -512,6 +558,7 @@ static inline void _SMP_lock_Release_and_ISR_enable( } #if defined( RTEMS_PROFILING ) + typedef struct { SMP_lock_Control Lock; Chain_Control Stats_chain; @@ -596,11 +643,9 @@ static inline void _SMP_lock_Stats_iteration_stop( _Chain_Extract_unprotected( &iteration_context->Node ); _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context ); } -#endif static inline void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats ) { -#if defined( RTEMS_PROFILING ) if ( !_Chain_Is_node_off_chain( &stats->Node ) ) { SMP_lock_Stats_control *control = &_SMP_lock_Stats_control; SMP_lock_Context lock_context; @@ -629,9 +674,6 @@ static inline void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats ) _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context ); } -#else - (void) stats; -#endif } static inline void _SMP_lock_Stats_release_update( @@ -639,7 +681,6 @@ static inline void _SMP_lock_Stats_release_update( const SMP_lock_Stats_context *stats_context ) { -#if defined( RTEMS_PROFILING ) CPU_Counter_ticks first = stats_context->acquire_instant; CPU_Counter_ticks second = _CPU_Counter_read(); CPU_Counter_ticks delta = _CPU_Counter_difference( second, first ); @@ -658,12 +699,10 @@ static inline void _SMP_lock_Stats_release_update( _SMP_lock_Release_and_ISR_enable( &control->Lock, &lock_context ); } } -#else - (void) stats; - (void) stats_context; -#endif } +#endif /* RTEMS_PROFILING */ + /**@}*/ #ifdef __cplusplus diff --git a/cpukit/score/src/profilingsmplock.c b/cpukit/score/src/profilingsmplock.c index be60ba9dee..a77e1a1092 100644 --- a/cpukit/score/src/profilingsmplock.c +++ b/cpukit/score/src/profilingsmplock.c @@ -21,19 +21,19 @@ #if defined( RTEMS_PROFILING ) SMP_lock_Stats_control _SMP_lock_Stats_control = { .Lock = { - .ticket_lock = { + .Ticket_lock = { .next_ticket = ATOMIC_INITIALIZER_UINT( 0U ), - .now_serving = ATOMIC_INITIALIZER_UINT( 0U ), - .Stats = { - .Node = CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( - &_SMP_lock_Stats_control.Stats_chain - ), - .name = "SMP lock stats" - } + .now_serving = ATOMIC_INITIALIZER_UINT( 0U ) + }, + .Stats = { + .Node = CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( + &_SMP_lock_Stats_control.Stats_chain + ), + .name = "SMP Lock Stats" } }, .Stats_chain = CHAIN_INITIALIZER_ONE_NODE( - &_SMP_lock_Stats_control.Lock.ticket_lock.Stats.Node + &_SMP_lock_Stats_control.Lock.Stats.Node ), .Iterator_chain = CHAIN_INITIALIZER_EMPTY( _SMP_lock_Stats_control.Iterator_chain diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c index 8ffeb1d828..a64287e51a 100644 --- a/cpukit/score/src/smp.c +++ b/cpukit/score/src/smp.c @@ -80,7 +80,8 @@ void _SMP_Handler_initialize( void ) for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) { Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index ); - _SMP_ticket_lock_Initialize( &cpu->Lock, "per-CPU" ); + _SMP_ticket_lock_Initialize( &cpu->Lock ); + _SMP_lock_Stats_initialize( &cpu->Lock_stats, "Per-CPU" ); } /* diff --git a/testsuites/sptests/sp37/init.c b/testsuites/sptests/sp37/init.c index 1dd434f52c..2fbe1172c1 100644 --- a/testsuites/sptests/sp37/init.c +++ b/testsuites/sptests/sp37/init.c @@ -161,8 +161,8 @@ static void test_isr_level( void ) #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) static const size_t lock_size = - offsetof( ISR_lock_Control, Lock.ticket_lock.Stats.name ) - + sizeof( ((ISR_lock_Control *) 0)->Lock.ticket_lock.Stats.name ); + offsetof( ISR_lock_Control, Lock.Stats.name ) + + sizeof( ((ISR_lock_Control *) 0)->Lock.Stats.name ); #else static const size_t lock_size = sizeof( ISR_lock_Control ); #endif -- cgit v1.2.3