<div dir="ltr">The git log message needs more but it looks good otherwise.<div><br></div><div>--joel</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 3, 2016 at 8:47 AM, Sebastian Huber <span dir="ltr"><<a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Update #2554.<br>
---<br>
 cpukit/score/include/rtems/score/percpu.h  |  8 +++<br>
 cpukit/score/include/rtems/score/smpimpl.h | 48 +++++++++++++++-<br>
 cpukit/score/src/percpu.c  Â  Â  Â  Â  Â  Â  Â  Â  | 92 +++++++++++++++++++++++++++---<br>
 cpukit/score/src/smp.c  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â | 23 ++++++++<br>
 cpukit/score/src/smpmulticastaction.c  Â  Â  |  4 +-<br>
 5 files changed, 164 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h<br>
index 19f46d2..39be1e3 100644<br>
--- a/cpukit/score/include/rtems/score/percpu.h<br>
+++ b/cpukit/score/include/rtems/score/percpu.h<br>
@@ -361,6 +361,14 @@ typedef struct Per_CPU_Control {<br>
  Â  Â Per_CPU_State state;<br>
<br>
  Â  Â /**<br>
+  Â  Â * @brief Action to be executed by this processor in the<br>
+  Â  Â * SYSTEM_STATE_BEFORE_MULTITASKING state on behalf of the boot processor.<br>
+  Â  Â *<br>
+  Â  Â * @see _SMP_Before_multitasking_action().<br>
+  Â  Â */<br>
+  Â  Atomic_Uintptr before_multitasking_action;<br>
+<br>
+  Â  /**<br>
  Â  Â  * @brief Indicates if the processor has been successfully started via<br>
  Â  Â  * _CPU_SMP_Start_processor().<br>
  Â  Â  */<br>
diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h<br>
index 386216f..59a99ec 100644<br>
--- a/cpukit/score/include/rtems/score/smpimpl.h<br>
+++ b/cpukit/score/include/rtems/score/smpimpl.h<br>
@@ -235,7 +235,7 @@ void _SMP_Send_message_multicast(<br>
  Â unsigned long message<br>
 );<br>
<br>
-typedef void ( *SMP_Multicast_action_handler )( void *arg );<br>
+typedef void ( *SMP_Action_handler )( void *arg );<br>
<br>
 /**<br>
  *  @brief Initiates a SMP multicast action to a set of processors.<br>
@@ -250,10 +250,54 @@ typedef void ( *SMP_Multicast_action_handler )( void *arg );<br>
 void _SMP_Multicast_action(<br>
  Â const size_t setsize,<br>
  Â const cpu_set_t *cpus,<br>
-  SMP_Multicast_action_handler handler,<br>
+  SMP_Action_handler handler,<br>
  Â void *arg<br>
 );<br>
<br>
+/**<br>
+ * @brief Executes a handler with argument on the specified processor on behalf<br>
+ * of the boot processor.<br>
+ *<br>
+ * The calling processor must be the boot processor.  In case the specified<br>
+ * processor is not online or not in the<br>
+ * PER_CPU_STATE_READY_TO_START_MULTITASKING state, then no action is<br>
+ * performed.<br>
+ *<br>
+ * @param cpu The processor to execute the action.<br>
+ * @param handler The handler of the action.<br>
+ * @param arg The argument of the action.<br>
+ *<br>
+ * @retval true The handler executed on the specified processor.<br>
+ * @retval false Otherwise.<br>
+ *<br>
+ * @see _SMP_Before_multitasking_action_broadcast().<br>
+ */<br>
+bool _SMP_Before_multitasking_action(<br>
+  Per_CPU_Control  Â  *cpu,<br>
+  SMP_Action_handler  handler,<br>
+  void  Â  Â  Â  Â  Â  Â  Â *arg<br>
+);<br>
+<br>
+/**<br>
+ * @brief Executes a handler with argument on all online processors except the<br>
+ * boot processor on behalf of the boot processor.<br>
+ *<br>
+ * The calling processor must be the boot processor.<br>
+ *<br>
+ * @param handler The handler of the action.<br>
+ * @param arg The argument of the action.<br>
+ *<br>
+ * @retval true The handler executed on all online processors except the boot<br>
+ * processor.<br>
+ * @retval false Otherwise.<br>
+ *<br>
+ * @see _SMP_Before_multitasking_action().<br>
+ */<br>
+bool _SMP_Before_multitasking_action_broadcast(<br>
+  SMP_Action_handler  handler,<br>
+  void  Â  Â  Â  Â  Â  Â  Â *arg<br>
+);<br>
+<br>
 #endif /* defined( RTEMS_SMP ) */<br>
<br>
 /**<br>
diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c<br>
index 730528a..0e4c067 100644<br>
--- a/cpukit/score/src/percpu.c<br>
+++ b/cpukit/score/src/percpu.c<br>
@@ -20,6 +20,7 @@<br>
<br>
 #include <rtems/score/percpu.h><br>
 #include <rtems/score/assert.h><br>
+#include <rtems/score/isrlock.h><br>
 #include <rtems/score/smpimpl.h><br>
 #include <rtems/config.h><br>
<br>
@@ -35,11 +36,48 @@ RTEMS_STATIC_ASSERT(<br>
<br>
 #if defined(RTEMS_SMP)<br>
<br>
-static SMP_lock_Control _Per_CPU_State_lock =<br>
-  SMP_LOCK_INITIALIZER("per-CPU state");<br>
+typedef struct {<br>
+  SMP_Action_handler handler;<br>
+  void *arg;<br>
+} SMP_Before_multicast_action;<br>
+<br>
+ISR_LOCK_DEFINE( static, _Per_CPU_State_lock, "Per-CPU State" )<br>
+<br>
+static void _Per_CPU_State_acquire( ISR_lock_Context *lock_context )<br>
+{<br>
+  _ISR_lock_ISR_disable_and_acquire( &_Per_CPU_State_lock, lock_context );<br>
+}<br>
+<br>
+static void _Per_CPU_State_release( ISR_lock_Context *lock_context )<br>
+{<br>
+  _ISR_lock_Release_and_ISR_enable( &_Per_CPU_State_lock, lock_context );<br>
+}<br>
+<br>
+static void _Per_CPU_State_before_multitasking_action( Per_CPU_Control *cpu )<br>
+{<br>
+  uintptr_t action_value;<br>
+<br>
+  action_value = _Atomic_Load_uintptr(<br>
+  Â  &cpu->before_multitasking_action,<br>
+  Â  ATOMIC_ORDER_ACQUIRE<br>
+  );<br>
+<br>
+  if ( action_value != 0 ) {<br>
+  Â  SMP_Before_multicast_action *action =<br>
+  Â  Â  (SMP_Before_multicast_action *) action_value;<br>
+<br>
+  Â  ( *action->handler )( action->arg );<br>
+<br>
+  Â  _Atomic_Store_uintptr(<br>
+  Â  Â  &cpu->before_multitasking_action,<br>
+  Â  Â  0,<br>
+  Â  Â  ATOMIC_ORDER_RELEASE<br>
+  Â  );<br>
+  }<br>
+}<br>
<br>
 static void _Per_CPU_State_busy_wait(<br>
-  const Per_CPU_Control *cpu,<br>
+  Per_CPU_Control *cpu,<br>
  Â Per_CPU_State new_state<br>
 )<br>
 {<br>
@@ -60,6 +98,7 @@ static void _Per_CPU_State_busy_wait(<br>
  Â  Â  Â  Â state != PER_CPU_STATE_REQUEST_START_MULTITASKING<br>
  Â  Â  Â  Â  Â && state != PER_CPU_STATE_SHUTDOWN<br>
  Â  Â  Â ) {<br>
+  Â  Â  Â  _Per_CPU_State_before_multitasking_action( cpu );<br>
  Â  Â  Â  Â _CPU_SMP_Processor_event_receive();<br>
  Â  Â  Â  Â state = cpu->state;<br>
  Â  Â  Â }<br>
@@ -122,13 +161,12 @@ void _Per_CPU_State_change(<br>
  Â Per_CPU_State new_state<br>
 )<br>
 {<br>
-  SMP_lock_Control *lock = &_Per_CPU_State_lock;<br>
-  SMP_lock_Context lock_context;<br>
+  ISR_lock_Context lock_context;<br>
  Â Per_CPU_State next_state;<br>
<br>
  Â _Per_CPU_State_busy_wait( cpu, new_state );<br>
<br>
-  _SMP_lock_ISR_disable_and_acquire( lock, &lock_context );<br>
+  _Per_CPU_State_acquire( &lock_context );<br>
<br>
  Â next_state = _Per_CPU_State_get_next( cpu->state, new_state );<br>
  Â cpu->state = next_state;<br>
@@ -157,7 +195,7 @@ void _Per_CPU_State_change(<br>
<br>
  Â _CPU_SMP_Processor_event_broadcast();<br>
<br>
-  _SMP_lock_Release_and_ISR_enable( lock, &lock_context );<br>
+  _Per_CPU_State_release( &lock_context );<br>
<br>
  Â if (<br>
  Â  Â next_state == PER_CPU_STATE_SHUTDOWN<br>
@@ -167,6 +205,46 @@ void _Per_CPU_State_change(<br>
  Â }<br>
 }<br>
<br>
+bool _SMP_Before_multitasking_action(<br>
+  Per_CPU_Control  Â  *cpu,<br>
+  SMP_Action_handler  handler,<br>
+  void  Â  Â  Â  Â  Â  Â  Â *arg<br>
+)<br>
+{<br>
+  bool done;<br>
+<br>
+  _Assert( _Per_CPU_Is_boot_processor( _Per_CPU_Get() ) );<br>
+<br>
+  if ( _Per_CPU_Is_processor_online( cpu ) ) {<br>
+  Â  SMP_Before_multicast_action action = {<br>
+  Â  Â  .handler = handler,<br>
+  Â  Â  .arg = arg<br>
+  Â  };<br>
+  Â  Per_CPU_State expected_state = PER_CPU_STATE_READY_TO_START_MULTITASKING;<br>
+<br>
+  Â  _Atomic_Store_uintptr(<br>
+  Â  Â  &cpu->before_multitasking_action,<br>
+  Â  Â  (uintptr_t) &action,<br>
+  Â  Â  ATOMIC_ORDER_RELEASE<br>
+  Â  );<br>
+<br>
+  Â  _CPU_SMP_Processor_event_broadcast();<br>
+<br>
+  Â  _Per_CPU_State_busy_wait( cpu, expected_state );<br>
+<br>
+  Â  do {<br>
+  Â  Â  done = _Atomic_Load_uintptr(<br>
+  Â  Â  Â  &cpu->before_multitasking_action,<br>
+  Â  Â  Â  ATOMIC_ORDER_ACQUIRE<br>
+  Â  Â  ) == 0;<br>
+  Â  } while ( !done && cpu->state == expected_state );<br>
+  } else {<br>
+  Â  done = false;<br>
+  }<br>
+<br>
+  return done;<br>
+}<br>
+<br>
 #else<br>
  Â /*<br>
  Â  * On single core systems, we can efficiently directly access a single<br>
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c<br>
index 8049643..4dacd4e 100644<br>
--- a/cpukit/score/src/smp.c<br>
+++ b/cpukit/score/src/smp.c<br>
@@ -211,4 +211,27 @@ void _SMP_Send_message_multicast(<br>
  Â }<br>
 }<br>
<br>
+bool _SMP_Before_multitasking_action_broadcast(<br>
+  SMP_Action_handler  handler,<br>
+  void  Â  Â  Â  Â  Â  Â  Â *arg<br>
+)<br>
+{<br>
+  bool done = true;<br>
+  uint32_t cpu_count = _SMP_Get_processor_count();<br>
+  uint32_t cpu_index;<br>
+<br>
+  for ( cpu_index = 0 ; done && cpu_index < cpu_count ; ++cpu_index ) {<br>
+  Â  Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );<br>
+<br>
+  Â  if (<br>
+  Â  Â  !_Per_CPU_Is_boot_processor( cpu )<br>
+  Â  Â  Â  && _Per_CPU_Is_processor_online( cpu )<br>
+  Â  ) {<br>
+  Â  Â  done = _SMP_Before_multitasking_action( cpu, handler, arg );<br>
+  Â  }<br>
+  }<br>
+<br>
+  return done;<br>
+}<br>
+<br>
 SMP_Test_message_handler _SMP_Test_message_handler;<br>
diff --git a/cpukit/score/src/smpmulticastaction.c b/cpukit/score/src/smpmulticastaction.c<br>
index 2e59262..d5d0064 100644<br>
--- a/cpukit/score/src/smpmulticastaction.c<br>
+++ b/cpukit/score/src/smpmulticastaction.c<br>
@@ -17,7 +17,7 @@<br>
<br>
 typedef struct {<br>
  Â Chain_Node Node;<br>
-  SMP_Multicast_action_handler handler;<br>
+  SMP_Action_handler handler;<br>
  Â void *arg;<br>
  Â cpu_set_t *recipients;<br>
  Â size_t setsize;<br>
@@ -94,7 +94,7 @@ _SMP_Multicast_actions_try_process( void )<br>
 void _SMP_Multicast_action(<br>
  Â const size_t setsize,<br>
  Â const cpu_set_t *cpus,<br>
-  SMP_Multicast_action_handler handler,<br>
+  SMP_Action_handler handler,<br>
  Â void *arg<br>
 )<br>
 {<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.4.5<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</font></span></blockquote></div><br></div>