[rtems commit] score: Add thread actions

Sebastian Huber sebh at rtems.org
Mon Mar 31 08:09:15 UTC 2014


Module:    rtems
Branch:    master
Commit:    0dd732ddac636e4b568172fa1b0a87e9191c8aba
Changeset: http://git.rtems.org/rtems/commit/?id=0dd732ddac636e4b568172fa1b0a87e9191c8aba

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Mar 14 11:50:58 2014 +0100

score: Add thread actions

Thread actions are the building block for efficient implementation of
  - Classic signals delivery,
  - POSIX signals delivery,
  - thread restart notification,
  - thread delete notification,
  - forced thread migration on SMP configurations, and
  - the Multiprocessor Resource Sharing Protocol (MrsP).

---

 cpukit/score/include/rtems/score/thread.h     |   59 ++++++++++++++++++++++
 cpukit/score/include/rtems/score/threadimpl.h |   67 +++++++++++++++++++++++++
 cpukit/score/src/threaddispatch.c             |   33 ++++++++++++
 cpukit/score/src/threadinitialize.c           |    2 +
 4 files changed, 161 insertions(+), 0 deletions(-)

diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 3dc423f..e5a1a55 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -340,6 +340,62 @@ typedef enum {
 /** This macro defines the last API which has threads. */
 #define THREAD_API_LAST  THREAD_API_POSIX
 
+typedef struct Thread_Action Thread_Action;
+
+/**
+ * @brief Thread action handler.
+ *
+ * The thread action handler will be called with interrupts disabled and the
+ * thread action lock acquired.  The handler must release the thread action
+ * lock with _Thread_Action_release_and_ISR_enable().  So the thread action
+ * lock can be used to protect private data fields of the particular action.
+ *
+ * Since the action is passed to the handler private data fields can be added
+ * below the common thread action fields.
+ *
+ * @param[in] thread The thread performing the action.
+ * @param[in] action The thread action.
+ * @param[in] cpu The processor of the thread.
+ * @param[in] level The ISR level for _Thread_Action_release_and_ISR_enable().
+ */
+typedef void ( *Thread_Action_handler )(
+  Thread_Control  *thread,
+  Thread_Action   *action,
+  Per_CPU_Control *cpu,
+  ISR_Level        level
+);
+
+/**
+ * @brief Thread action.
+ *
+ * Thread actions can be chained together to trigger a set of actions on
+ * particular events like for example a thread post-switch.  Use
+ * _Thread_Action_initialize() to initialize this structure.
+ *
+ * Thread actions are the building block for efficient implementation of
+ * - Classic signals delivery,
+ * - POSIX signals delivery,
+ * - thread restart notification,
+ * - thread delete notification,
+ * - forced thread migration on SMP configurations, and
+ * - the Multiprocessor Resource Sharing Protocol (MrsP).
+ *
+ * @see _Thread_Run_post_switch_actions().
+ */
+struct Thread_Action {
+  Chain_Node            Node;
+  Thread_Action_handler handler;
+};
+
+/**
+ * @brief Control block to manage thread actions.
+ *
+ * Use _Thread_Action_control_initialize() to initialize this structure.
+ */
+typedef struct {
+  Chain_Control Chain;
+} Thread_Action_control;
+
 /**
  *  This structure defines the Thread Control Block (TCB).
  */
@@ -457,6 +513,9 @@ struct Thread_Control_struct {
    *  this thread.
    */
   Thread_Start_information              Start;
+
+  Thread_Action_control                 Post_switch_actions;
+
   /** This field contains the context of this thread. */
   Context_Control                       Registers;
 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index cc0d818..bbaa10a 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -20,6 +20,7 @@
 #define _RTEMS_SCORE_THREADIMPL_H
 
 #include <rtems/score/thread.h>
+#include <rtems/score/chainimpl.h>
 #include <rtems/score/interr.h>
 #include <rtems/score/isr.h>
 #include <rtems/score/objectimpl.h>
@@ -639,6 +640,72 @@ RTEMS_INLINE_ROUTINE void _Thread_Update_cpu_time_used(
   _Timestamp_Add_to( &executing->cpu_time_used, &ran );
 }
 
+RTEMS_INLINE_ROUTINE void _Thread_Action_control_initialize(
+  Thread_Action_control *action_control
+)
+{
+  _Chain_Initialize_empty( &action_control->Chain );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Action_initialize(
+  Thread_Action         *action,
+  Thread_Action_handler  handler
+)
+{
+  action->handler = handler;
+  _Chain_Set_off_chain( &action->Node );
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *
+  _Thread_Action_ISR_disable_and_acquire_for_executing( ISR_Level *level )
+{
+  Per_CPU_Control *cpu;
+
+  _ISR_Disable_without_giant( *level );
+  cpu = _Per_CPU_Get();
+  _Per_CPU_Acquire( cpu );
+
+  return cpu;
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Action_ISR_disable_and_acquire(
+  Thread_Control *thread,
+  ISR_Level      *level
+)
+{
+  Per_CPU_Control *cpu;
+
+  _ISR_Disable_without_giant( *level );
+  cpu = _Thread_Get_CPU( thread );
+  _Per_CPU_Acquire( cpu );
+
+  return cpu;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Action_release_and_ISR_enable(
+  Per_CPU_Control *cpu,
+  ISR_Level level
+)
+{
+  _Per_CPU_Release_and_ISR_enable( cpu, level );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action(
+  Thread_Control *thread,
+  Thread_Action  *action
+)
+{
+  Per_CPU_Control *cpu;
+  ISR_Level        level;
+
+  cpu = _Thread_Action_ISR_disable_and_acquire( thread, &level );
+  _Chain_Append_if_is_off_chain_unprotected(
+    &thread->Post_switch_actions.Chain,
+    &action->Node
+  );
+  _Thread_Action_release_and_ISR_enable( cpu, level );
+}
+
 #if !defined(__DYNAMIC_REENT__)
 /**
  * This routine returns the C library re-enterant pointer.
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index 22a4f88..ae30c0c 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -9,6 +9,8 @@
  *  COPYRIGHT (c) 1989-2009.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (c) 2014 embedded brains GmbH.
+ *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.org/license/LICENSE.
@@ -27,6 +29,36 @@
 #include <rtems/score/userextimpl.h>
 #include <rtems/score/wkspace.h>
 
+static Thread_Action *_Thread_Get_post_switch_action(
+  Thread_Control *executing
+)
+{
+  Chain_Control *chain = &executing->Post_switch_actions.Chain;
+
+  return (Thread_Action *) _Chain_Get_unprotected( chain );
+}
+
+static void _Thread_Run_post_switch_actions( Thread_Control *executing )
+{
+  ISR_Level        level;
+  Per_CPU_Control *cpu;
+  Thread_Action   *action;
+
+  cpu = _Thread_Action_ISR_disable_and_acquire( executing, &level );
+  action = _Thread_Get_post_switch_action( executing );
+
+  while ( action != NULL ) {
+    _Chain_Set_off_chain( &action->Node );
+
+    ( *action->handler )( executing, action, cpu, level );
+
+    cpu = _Thread_Action_ISR_disable_and_acquire( executing, &level );
+    action = _Thread_Get_post_switch_action( executing );
+  }
+
+  _Thread_Action_release_and_ISR_enable( cpu, level );
+}
+
 void _Thread_Dispatch( void )
 {
   Per_CPU_Control  *per_cpu;
@@ -176,4 +208,5 @@ post_switch:
   _Per_CPU_Release_and_ISR_enable( per_cpu, level );
 
   _API_extensions_Run_post_switch( executing );
+  _Thread_Run_post_switch_actions( executing );
 }
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index df49184..315156e 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -238,6 +238,8 @@ bool _Thread_Initialize(
    */
   _Chain_Initialize_empty( &the_thread->Key_Chain );
 
+  _Thread_Action_control_initialize( &the_thread->Post_switch_actions );
+
   /*
    *  Open the object
    */




More information about the vc mailing list