summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/smpimpl.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/smpimpl.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 '')
-rw-r--r--cpukit/score/include/rtems/score/smpimpl.h18
1 files changed, 10 insertions, 8 deletions
diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h
index d1b7214bbb..7f2de5ff70 100644
--- a/cpukit/score/include/rtems/score/smpimpl.h
+++ b/cpukit/score/include/rtems/score/smpimpl.h
@@ -167,8 +167,10 @@ void _SMP_Multicast_actions_process( void );
*/
static inline long unsigned _SMP_Inter_processor_interrupt_handler( void )
{
- Per_CPU_Control *cpu_self = _Per_CPU_Get();
- unsigned long message = 0;
+ Per_CPU_Control *cpu_self;
+ unsigned long message;
+
+ cpu_self = _Per_CPU_Get();
/*
* In the common case the inter-processor interrupt is issued to carry out a
@@ -176,13 +178,13 @@ static inline long unsigned _SMP_Inter_processor_interrupt_handler( void )
*/
cpu_self->dispatch_necessary = true;
- if ( _Atomic_Load_ulong( &cpu_self->message, ATOMIC_ORDER_RELAXED ) != 0 ) {
- message = _Atomic_Exchange_ulong(
- &cpu_self->message,
- 0UL,
- ATOMIC_ORDER_RELAXED
- );
+ message = _Atomic_Exchange_ulong(
+ &cpu_self->message,
+ 0,
+ ATOMIC_ORDER_ACQUIRE
+ );
+ if ( message != 0 ) {
if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
_SMP_Fatal( SMP_FATAL_SHUTDOWN_RESPONSE );
/* does not continue past here */