diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-06 06:44:41 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-12 13:24:40 +0200 |
commit | 6e4f929296b1cfd50fc8f41f117459e65214b816 (patch) | |
tree | 9819ea160f6c745dae1936ae296709026d3d47a2 /cpukit/score/include/rtems | |
parent | score: Add _Thread_queue_Is_lock_owner() (diff) | |
download | rtems-6e4f929296b1cfd50fc8f41f117459e65214b816.tar.bz2 |
score: Introduce thread state lock
Update #2556.
Diffstat (limited to '')
-rw-r--r-- | cpukit/score/include/rtems/score/thread.h | 54 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 98 |
2 files changed, 85 insertions, 67 deletions
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 8ea2db2cc1..d4ca5056ce 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -343,9 +343,14 @@ typedef struct { typedef struct { /** This field is the object management structure for each proxy. */ Objects_Control Object; + + /** + * @see Thread_Control::Join_queue + */ + Thread_queue_Control Join_queue; + /** This field is the current execution state of this proxy. */ States_Control current_state; - /** * @brief This field is the current priority state of this thread. * @@ -445,24 +450,23 @@ 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. + * The thread action handler will be called with interrupts disabled and a + * corresponding lock acquired, e.g. _Thread_State_acquire(). The handler must + * release the corresponding lock, e.g. _Thread_State_release(). So, the + * corresponding lock may be used to protect private data used by the + * particular action. * - * Since the action is passed to the handler private data fields can be added - * below the common thread action fields. + * Since the action is passed to the handler additional data may be accessed + * via RTEMS_CONTAINER_OF(). * - * @param[in] thread The thread performing the action. + * @param[in] the_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(). + * @param[in] lock_context The lock context to use for the lock release. */ typedef void ( *Thread_Action_handler )( - Thread_Control *thread, - Thread_Action *action, - struct Per_CPU_Control *cpu, - ISR_Level level + Thread_Control *the_thread, + Thread_Action *action, + ISR_lock_Context *lock_context ); /** @@ -474,13 +478,10 @@ typedef void ( *Thread_Action_handler )( * * 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). + * - POSIX signals delivery, and + * - thread life-cycle changes. * - * @see _Thread_Run_post_switch_actions(). + * @see _Thread_Add_post_switch_action() and _Thread_Run_post_switch_actions(). */ struct Thread_Action { Chain_Node Node; @@ -710,6 +711,19 @@ typedef struct { struct _Thread_Control { /** This field is the object management structure for each thread. */ Objects_Control Object; + + /** + * @brief Thread queue for thread join operations and multi-purpose lock. + * + * The lock of this thread queue is used for various purposes. It protects + * the following fields + * + * - Thread_Control::Post_switch_actions. + * + * @see _Thread_State_acquire(). + */ + Thread_queue_Control Join_queue; + /** This field is the current execution state of this thread. */ States_Control current_state; diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 1d0421f0ce..931eec0d1b 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -200,13 +200,6 @@ void _Thread_Yield( Thread_Control *executing ); bool _Thread_Set_life_protection( bool protect ); -void _Thread_Life_action_handler( - Thread_Control *executing, - Thread_Action *action, - Per_CPU_Control *cpu, - ISR_Level level -); - /** * @brief Kills all zombie threads in the system. * @@ -337,6 +330,52 @@ void _Thread_Delay_ended( void *ignored ); +RTEMS_INLINE_ROUTINE void _Thread_State_acquire_critical( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _Thread_queue_Acquire_critical( &the_thread->Join_queue, lock_context ); +} + +RTEMS_INLINE_ROUTINE void _Thread_State_acquire( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _Thread_queue_Acquire( &the_thread->Join_queue, lock_context ); +} + +RTEMS_INLINE_ROUTINE Thread_Control *_Thread_State_acquire_for_executing( + ISR_lock_Context *lock_context +) +{ + Thread_Control *executing; + + _ISR_lock_ISR_disable( lock_context ); + executing = _Thread_Executing; + _Thread_State_acquire_critical( executing, lock_context ); + + return executing; +} + +RTEMS_INLINE_ROUTINE void _Thread_State_release( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _Thread_queue_Release( &the_thread->Join_queue, lock_context ); +} + +#if defined(RTEMS_DEBUG) +RTEMS_INLINE_ROUTINE bool _Thread_State_is_owner( + const Thread_Control *the_thread +) +{ + return _Thread_queue_Is_lock_owner( &the_thread->Join_queue ); +} +#endif + /** * @brief Returns true if the left thread priority is less than the right * thread priority in the intuitive sense of priority and false otherwise. @@ -841,50 +880,17 @@ RTEMS_INLINE_ROUTINE void _Thread_Action_initialize( _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_Control *the_thread, Thread_Action *action, Thread_Action_handler handler ) { Per_CPU_Control *cpu_of_thread; - ISR_Level level; - cpu_of_thread = _Thread_Action_ISR_disable_and_acquire( thread, &level ); + _Assert( _Thread_State_is_owner( the_thread ) ); + + cpu_of_thread = _Thread_Get_CPU( the_thread ); action->handler = handler; @@ -899,11 +905,9 @@ RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action( #endif _Chain_Append_if_is_off_chain_unprotected( - &thread->Post_switch_actions.Chain, + &the_thread->Post_switch_actions.Chain, &action->Node ); - - _Thread_Action_release_and_ISR_enable( cpu_of_thread, level ); } RTEMS_INLINE_ROUTINE bool _Thread_Is_life_restarting( |