summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/threaddispatch.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-29 09:50:47 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-29 09:50:47 +0200
commit9bb3ce3918261c5392abbe4b65902e5d4b6dff07 (patch)
treea0ce25f5619672f3afd222cfe79460e88858d2da /cpukit/score/include/rtems/score/threaddispatch.h
parentarm/raspberrypi: resolve BSP warnings. (diff)
downloadrtems-9bb3ce3918261c5392abbe4b65902e5d4b6dff07.tar.bz2
score: Fix SMP message handling
According to the C11 standard only atomic read-modify-write operations guarantee that the last value written in modification order is read, see "7.17.3 Order and consistency". Thus we must use a read-modify-write in _SMP_Inter_processor_interrupt_handler() to make sure we read an up-to-date message.
Diffstat (limited to 'cpukit/score/include/rtems/score/threaddispatch.h')
-rw-r--r--cpukit/score/include/rtems/score/threaddispatch.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/cpukit/score/include/rtems/score/threaddispatch.h b/cpukit/score/include/rtems/score/threaddispatch.h
index 573d1be2b3..4cb223b147 100644
--- a/cpukit/score/include/rtems/score/threaddispatch.h
+++ b/cpukit/score/include/rtems/score/threaddispatch.h
@@ -226,6 +226,30 @@ RTEMS_INLINE_ROUTINE void _Thread_Dispatch_unnest( Per_CPU_Control *cpu_self )
--cpu_self->thread_dispatch_disable_level;
}
+/**
+ * @brief Requests a thread dispatch on the target processor.
+ *
+ * @param[in] cpu_self The current processor.
+ * @param[in] cpu_target The target processor to request a thread dispatch.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_request(
+ Per_CPU_Control *cpu_self,
+ Per_CPU_Control *cpu_target
+)
+{
+#if defined( RTEMS_SMP )
+ if ( cpu_self == cpu_target ) {
+ cpu_self->dispatch_necessary = true;
+ } else {
+ _Atomic_Fetch_or_ulong( &cpu_target->message, 0, ATOMIC_ORDER_RELEASE );
+ _CPU_SMP_Send_interrupt( _Per_CPU_Get_index( cpu_target ) );
+ }
+#else
+ cpu_self->dispatch_necessary = true;
+ (void) cpu_target;
+#endif
+}
+
/** @} */
#ifdef __cplusplus