summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-02-18 08:36:16 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-03-04 13:36:10 +0100
commit90d8567d34a6d80da04b1cb37b667a3173f584c4 (patch)
tree221e66b9da1dd9dd79d01e507f0026bfb477b810 /cpukit
parentscore: Add _SMP_Before_multitasking_action() (diff)
downloadrtems-90d8567d34a6d80da04b1cb37b667a3173f584c4.tar.bz2
score: Distribute clock tick to all online CPUs
Update #2554.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/score/include/rtems/score/smpimpl.h34
-rw-r--r--cpukit/score/include/rtems/score/watchdogimpl.h7
-rw-r--r--cpukit/score/src/kern_tc.c9
-rw-r--r--cpukit/score/src/smp.c5
-rw-r--r--cpukit/score/src/watchdogtick.c10
5 files changed, 43 insertions, 22 deletions
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
@@ -60,6 +60,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.
*/
typedef enum {
@@ -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 <rtems/score/assert.h>
#include <rtems/score/chainimpl.h>
#include <rtems/score/isrlock.h>
+#include <rtems/score/percpu.h>
#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();
+ }
}