[PATCH 04/17] score: Add thread actions

Gedare Bloom gedare at rtems.org
Tue Mar 25 15:36:25 UTC 2014


On Tue, Mar 25, 2014 at 8:49 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> 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 7147110..153537a 100644
> --- a/cpukit/score/include/rtems/score/thread.h
> +++ b/cpukit/score/include/rtems/score/thread.h
> @@ -356,6 +356,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.
> + *
Why doesn't the caller of the handler release the lock and enable ISRs
after the handler returns?

> + * 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).
>   */
> @@ -473,6 +529,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;
> +}
Is this "for_executing" variant required for some SMP uses? On non-smp
it is the same the next function. I do not see the function is used in
this patch.

> +
> +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
>     */
> --
> 1.7.7
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel



More information about the devel mailing list