On Tue, Mar 25, 2014 at 8:49 AM, Sebastian Huber <sebastian.hu...@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@rtems.org > http://www.rtems.org/mailman/listinfo/rtems-devel _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel