Changeset 9bb3ce39 in rtems


Ignore:
Timestamp:
Jun 29, 2016, 7:50:47 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
891fa3e
Parents:
b83c23e6
Message:

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.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c

    rb83c23e6 r9bb3ce39  
    6363void _CPU_SMP_Send_interrupt( uint32_t target_processor_index )
    6464{
    65   _ARM_Data_memory_barrier();
    6665  arm_gic_irq_generate_software_irq(
    6766    ARM_GIC_IRQ_SGI_0,
  • c/src/lib/libbsp/powerpc/qoriq/startup/bspsmp.c

    rb83c23e6 r9bb3ce39  
    268268void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
    269269{
    270 #ifdef __PPC_CPU_E6500__
    271   ppc_light_weight_synchronize();
    272 #else
    273   ppc_synchronize_data();
    274 #endif
    275270  qoriq.pic.ipidr [IPI_INDEX].reg = 1U << target_processor_index;
    276271}
  • cpukit/score/include/rtems/score/percpu.h

    rb83c23e6 r9bb3ce39  
    620620#if defined( RTEMS_SMP )
    621621
    622 static inline void _Per_CPU_Send_interrupt( const Per_CPU_Control *cpu )
    623 {
    624   _CPU_SMP_Send_interrupt( _Per_CPU_Get_index( cpu ) );
    625 }
    626 
    627622/**
    628623 *  @brief Allocate and Initialize Per CPU Structures
  • cpukit/score/include/rtems/score/smpimpl.h

    rb83c23e6 r9bb3ce39  
    168168static inline long unsigned _SMP_Inter_processor_interrupt_handler( void )
    169169{
    170   Per_CPU_Control *cpu_self = _Per_CPU_Get();
    171   unsigned long message = 0;
     170  Per_CPU_Control *cpu_self;
     171  unsigned long    message;
     172
     173  cpu_self = _Per_CPU_Get();
    172174
    173175  /*
     
    177179  cpu_self->dispatch_necessary = true;
    178180
    179   if ( _Atomic_Load_ulong( &cpu_self->message, ATOMIC_ORDER_RELAXED ) != 0 ) {
    180     message = _Atomic_Exchange_ulong(
    181       &cpu_self->message,
    182       0UL,
    183       ATOMIC_ORDER_RELAXED
    184     );
    185 
     181  message = _Atomic_Exchange_ulong(
     182    &cpu_self->message,
     183    0,
     184    ATOMIC_ORDER_ACQUIRE
     185  );
     186
     187  if ( message != 0 ) {
    186188    if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
    187189      _SMP_Fatal( SMP_FATAL_SHUTDOWN_RESPONSE );
  • cpukit/score/include/rtems/score/threaddispatch.h

    rb83c23e6 r9bb3ce39  
    227227}
    228228
     229/**
     230 * @brief Requests a thread dispatch on the target processor.
     231 *
     232 * @param[in] cpu_self The current processor.
     233 * @param[in] cpu_target The target processor to request a thread dispatch.
     234 */
     235RTEMS_INLINE_ROUTINE void _Thread_Dispatch_request(
     236  Per_CPU_Control *cpu_self,
     237  Per_CPU_Control *cpu_target
     238)
     239{
     240#if defined( RTEMS_SMP )
     241  if ( cpu_self == cpu_target ) {
     242    cpu_self->dispatch_necessary = true;
     243  } else {
     244    _Atomic_Fetch_or_ulong( &cpu_target->message, 0, ATOMIC_ORDER_RELEASE );
     245    _CPU_SMP_Send_interrupt( _Per_CPU_Get_index( cpu_target ) );
     246  }
     247#else
     248 cpu_self->dispatch_necessary = true;
     249 (void) cpu_target;
     250#endif
     251}
     252
    229253/** @} */
    230254
  • cpukit/score/include/rtems/score/threadimpl.h

    rb83c23e6 r9bb3ce39  
    845845  cpu_for_heir->heir = heir;
    846846
    847   if ( cpu_for_heir == cpu_self ) {
    848     cpu_self->dispatch_necessary = true;
    849   } else {
    850     _Per_CPU_Send_interrupt( cpu_for_heir );
    851   }
     847  _Thread_Dispatch_request( cpu_self, cpu_for_heir );
    852848}
    853849#endif
     
    886882  action->handler = handler;
    887883
    888 #if defined(RTEMS_SMP)
    889   if ( _Per_CPU_Get() == cpu_of_thread ) {
    890     cpu_of_thread->dispatch_necessary = true;
    891   } else {
    892     _Per_CPU_Send_interrupt( cpu_of_thread );
    893   }
    894 #else
    895   cpu_of_thread->dispatch_necessary = true;
    896 #endif
     884  _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
    897885
    898886  _Chain_Append_if_is_off_chain_unprotected(
  • cpukit/score/src/smp.c

    rb83c23e6 r9bb3ce39  
    168168  Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
    169169
    170   _Atomic_Fetch_or_ulong( &cpu->message, message, ATOMIC_ORDER_RELAXED );
     170  _Atomic_Fetch_or_ulong( &cpu->message, message, ATOMIC_ORDER_RELEASE );
    171171
    172172  _CPU_SMP_Send_interrupt( cpu_index );
Note: See TracChangeset for help on using the changeset viewer.