From 90d8567d34a6d80da04b1cb37b667a3173f584c4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 18 Feb 2016 08:36:16 +0100 Subject: score: Distribute clock tick to all online CPUs Update #2554. --- cpukit/score/include/rtems/score/smpimpl.h | 34 ++++++++++++++++--------- cpukit/score/include/rtems/score/watchdogimpl.h | 7 ++--- cpukit/score/src/kern_tc.c | 9 +++++-- cpukit/score/src/smp.c | 5 +++- cpukit/score/src/watchdogtick.c | 10 +++++--- 5 files changed, 43 insertions(+), 22 deletions(-) (limited to 'cpukit/score') diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h index 59a99ec6b3..d1b7214bbb 100644 --- a/cpukit/score/include/rtems/score/smpimpl.h +++ b/cpukit/score/include/rtems/score/smpimpl.h @@ -59,6 +59,16 @@ extern "C" { */ #define SMP_MESSAGE_MULTICAST_ACTION 0x4UL +/** + * @brief SMP message to request a clock tick. + * + * This message is provided for systems without a proper interrupt affinity + * support and may be used by the clock driver. + * + * @see _SMP_Send_message(). + */ +#define SMP_MESSAGE_CLOCK_TICK 0x8UL + /** * @brief SMP fatal codes. */ @@ -152,10 +162,13 @@ void _SMP_Multicast_actions_process( void ); /** * @brief Interrupt handler for inter-processor interrupts. + * + * @return The received message. */ -static inline void _SMP_Inter_processor_interrupt_handler( void ) +static inline long unsigned _SMP_Inter_processor_interrupt_handler( void ) { Per_CPU_Control *cpu_self = _Per_CPU_Get(); + unsigned long message = 0; /* * In the common case the inter-processor interrupt is issued to carry out a @@ -164,7 +177,7 @@ static inline void _SMP_Inter_processor_interrupt_handler( void ) cpu_self->dispatch_necessary = true; if ( _Atomic_Load_ulong( &cpu_self->message, ATOMIC_ORDER_RELAXED ) != 0 ) { - unsigned long message = _Atomic_Exchange_ulong( + message = _Atomic_Exchange_ulong( &cpu_self->message, 0UL, ATOMIC_ORDER_RELAXED @@ -183,6 +196,8 @@ static inline void _SMP_Inter_processor_interrupt_handler( void ) _SMP_Multicast_actions_process(); } } + + return message; } /** @@ -197,7 +212,7 @@ static inline void _SMP_Inter_processor_interrupt_handler( void ) bool _SMP_Should_start_processor( uint32_t cpu_index ); /** - * @brief Sends a SMP message to a processor. + * @brief Sends an SMP message to a processor. * * The target processor may be the sending processor. * @@ -207,21 +222,16 @@ bool _SMP_Should_start_processor( uint32_t cpu_index ); void _SMP_Send_message( uint32_t cpu_index, unsigned long message ); /** - * @brief Request of others CPUs. + * @brief Sends an SMP message to all other online processors. * - * This method is invoked by RTEMS when it needs to make a request - * of the other CPUs. It should be implemented using some type of - * interprocessor interrupt. CPUs not including the originating - * CPU should receive the message. - * - * @param [in] message is message to send + * @param[in] message The message. */ void _SMP_Send_message_broadcast( unsigned long message ); /** - * @brief Sends a SMP message to a set of processors. + * @brief Sends an SMP message to a set of processors. * * The sending processor may be part of the set. * @@ -238,7 +248,7 @@ void _SMP_Send_message_multicast( typedef void ( *SMP_Action_handler )( void *arg ); /** - * @brief Initiates a SMP multicast action to a set of processors. + * @brief Initiates an SMP multicast action to a set of processors. * * The current processor may be part of the set. * diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h b/cpukit/score/include/rtems/score/watchdogimpl.h index 8064c77447..49ac2a12b1 100644 --- a/cpukit/score/include/rtems/score/watchdogimpl.h +++ b/cpukit/score/include/rtems/score/watchdogimpl.h @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -139,11 +140,11 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Flash( void _Watchdog_Handler_initialization( void ); /** - * @brief Triggers a watchdog tick. + * @brief Performs a watchdog tick. * - * This routine executes TOD, watchdog and scheduler ticks. + * @param cpu The processor for this watchdog tick. */ -void _Watchdog_Tick( void ); +void _Watchdog_Tick( Per_CPU_Control *cpu ); /** * @brief Removes @a the_watchdog from the watchdog chain. diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 16d76a1789..e56c292ea3 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1974,10 +1974,15 @@ tc_ticktock(int cnt) void _Timecounter_Tick(void) { + Per_CPU_Control *cpu_self = _Per_CPU_Get(); + + if (_Per_CPU_Is_boot_processor(cpu_self)) { #endif /* __rtems__ */ tc_windup(); #ifdef __rtems__ - _Watchdog_Tick(); + }; + + _Watchdog_Tick(cpu_self); #endif /* __rtems__ */ } #ifdef __rtems__ @@ -2016,7 +2021,7 @@ _Timecounter_Tick_simple(uint32_t delta, uint32_t offset, _Timecounter_Release(lock_context); - _Watchdog_Tick(); + _Watchdog_Tick(_Per_CPU_Get()); } #endif /* __rtems__ */ diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c index 4dacd4ed5c..9d9507d1b9 100644 --- a/cpukit/score/src/smp.c +++ b/cpukit/score/src/smp.c @@ -189,7 +189,10 @@ void _SMP_Send_message_broadcast( unsigned long message ) _Assert( _Debug_Is_thread_dispatching_allowed() ); for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { - if ( cpu_index != cpu_index_self ) { + if ( + cpu_index != cpu_index_self + && _Processor_mask_Is_set( _SMP_Online_processors, cpu_index ) + ) { _SMP_Send_message( cpu_index, message ); } } diff --git a/cpukit/score/src/watchdogtick.c b/cpukit/score/src/watchdogtick.c index cb68ea2f02..e89c088350 100644 --- a/cpukit/score/src/watchdogtick.c +++ b/cpukit/score/src/watchdogtick.c @@ -22,13 +22,15 @@ #include "config.h" #endif -void _Watchdog_Tick( void ) +void _Watchdog_Tick( Per_CPU_Control *cpu ) { _Assert( !_Thread_Dispatch_is_enabled() ); - _TOD_Tickle_ticks(); + if ( _Per_CPU_Is_boot_processor( cpu ) ) { + _TOD_Tickle_ticks(); - _Watchdog_Tickle_ticks(); + _Watchdog_Tickle_ticks(); - _Scheduler_Tick(); + _Scheduler_Tick(); + } } -- cgit v1.2.3