[PATCH 13/32] score: Split _Thread_Restart()
Gedare Bloom
gedare at rtems.org
Thu May 19 23:03:40 UTC 2016
Clarify the distinction between Thread_Do_self_restart() and
Thread_Restart_self(). Probably want comments to indicate the
difference.
On Wed, May 18, 2016 at 5:20 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> Rename _Thread_Restart_self() into _Thread_Do_self_restart(). Split
> _Thread_Restart() into _Thread_Restart_self() and
> _Thread_Restart_other(). Avoid Giant lock for thread restart.
> _Thread_Restart_self() is a no-return function and used by
> _Thread_Global_construction().
>
> Update #2555.
> Update #2626.
> ---
> cpukit/rtems/src/taskrestart.c | 42 +++++++--------
> cpukit/score/include/rtems/score/threadimpl.h | 14 +++--
> cpukit/score/src/threadglobalconstruction.c | 10 ++--
> cpukit/score/src/threadrestart.c | 78 ++++++++++++++++++++++-----
> 4 files changed, 99 insertions(+), 45 deletions(-)
>
> diff --git a/cpukit/rtems/src/taskrestart.c b/cpukit/rtems/src/taskrestart.c
> index 8aa7c73..6e4ad96 100644
> --- a/cpukit/rtems/src/taskrestart.c
> +++ b/cpukit/rtems/src/taskrestart.c
> @@ -26,32 +26,32 @@ rtems_status_code rtems_task_restart(
> uint32_t argument
> )
> {
> - Thread_Control *the_thread;
> - Objects_Locations location;
> - Thread_Entry_information entry;
> -
> - the_thread = _Thread_Get( id, &location );
> - switch ( location ) {
> -
> - case OBJECTS_LOCAL:
> - entry = the_thread->Start.Entry;
> - entry.Kinds.Numeric.argument = argument;
> - if ( _Thread_Restart( the_thread, _Thread_Executing, &entry ) ) {
> - _Objects_Put( &the_thread->Object );
> - return RTEMS_SUCCESSFUL;
> - }
> - _Objects_Put( &the_thread->Object );
> - return RTEMS_INCORRECT_STATE;
> + Thread_Control *the_thread;
> + ISR_lock_Context lock_context;
> + Thread_Entry_information entry;
> + bool ok;
>
> + the_thread = _Thread_Get_interrupt_disable( id, &lock_context );
> +
> + if ( the_thread == NULL ) {
> #if defined(RTEMS_MULTIPROCESSING)
> - case OBJECTS_REMOTE:
> - _Thread_Dispatch();
> + if ( _Thread_MP_Is_remote( id ) ) {
> return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
> + }
> #endif
>
> - case OBJECTS_ERROR:
> - break;
> + return RTEMS_INVALID_ID;
> }
>
> - return RTEMS_INVALID_ID;
> + entry = the_thread->Start.Entry;
> + entry.Kinds.Numeric.argument = argument;
> +
> + if ( the_thread == _Thread_Executing ) {
> + _Thread_Restart_self( the_thread, &entry, &lock_context );
> + RTEMS_UNREACHABLE();
> + }
> +
> + ok = _Thread_Restart_other( the_thread, &entry, &lock_context );
> +
> + return ok ? RTEMS_SUCCESSFUL : RTEMS_INCORRECT_STATE;
> }
> diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
> index 68b9e72..0784b50 100644
> --- a/cpukit/score/include/rtems/score/threadimpl.h
> +++ b/cpukit/score/include/rtems/score/threadimpl.h
> @@ -190,10 +190,16 @@ bool _Thread_Start(
> const Thread_Entry_information *entry
> );
>
> -bool _Thread_Restart(
> - Thread_Control *the_thread,
> +void _Thread_Restart_self(
> Thread_Control *executing,
> - const Thread_Entry_information *entry
> + const Thread_Entry_information *entry,
> + ISR_lock_Context *lock_context
> +) RTEMS_NO_RETURN;
> +
> +bool _Thread_Restart_other(
> + Thread_Control *the_thread,
> + const Thread_Entry_information *entry,
> + ISR_lock_Context *lock_context
> );
>
> void _Thread_Yield( Thread_Control *executing );
> @@ -691,7 +697,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Unblock (
> * to that of its initial state.
> */
>
> -RTEMS_INLINE_ROUTINE void _Thread_Restart_self( Thread_Control *executing )
> +RTEMS_INLINE_ROUTINE void _Thread_Do_self_restart( Thread_Control *executing )
> {
> #if defined(RTEMS_SMP)
> ISR_Level level;
> diff --git a/cpukit/score/src/threadglobalconstruction.c b/cpukit/score/src/threadglobalconstruction.c
> index 997f285..7ce1862 100644
> --- a/cpukit/score/src/threadglobalconstruction.c
> +++ b/cpukit/score/src/threadglobalconstruction.c
> @@ -20,8 +20,6 @@
> #endif
>
> #include <rtems/score/threadimpl.h>
> -#include <rtems/score/assert.h>
> -#include <rtems/config.h>
>
> /*
> * Conditional magic to determine what style of C++ constructor
> @@ -49,6 +47,8 @@ void _Thread_Global_construction(
> const Thread_Entry_information *entry
> )
> {
> + ISR_lock_Context lock_context;
> +
> #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
> /*
> * _init could be a weak symbol and we SHOULD test it but it isn't
> @@ -58,8 +58,6 @@ void _Thread_Global_construction(
> INIT_NAME();
> #endif
>
> - _Thread_Disable_dispatch();
> - _Thread_Restart( executing, executing, entry );
> - _Thread_Enable_dispatch();
> - RTEMS_UNREACHABLE();
> + _ISR_lock_ISR_disable( &lock_context );
> + _Thread_Restart_self( _Thread_Executing, entry, &lock_context );
> }
> diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
> index 9ab053c..1ebefa7 100644
> --- a/cpukit/score/src/threadrestart.c
> +++ b/cpukit/score/src/threadrestart.c
> @@ -335,7 +335,7 @@ void _Thread_Life_action_handler(
>
> _User_extensions_Destroy_iterators( executing );
> _Thread_Load_environment( executing );
> - _Thread_Restart_self( executing );
> + _Thread_Do_self_restart( executing );
> RTEMS_UNREACHABLE();
> }
> }
> @@ -462,26 +462,76 @@ void _Thread_Exit( Thread_Control *executing )
> _Thread_State_release( executing, &lock_context );
> }
>
> -bool _Thread_Restart(
> +bool _Thread_Restart_other(
> Thread_Control *the_thread,
> - Thread_Control *executing,
> - const Thread_Entry_information *entry
> + const Thread_Entry_information *entry,
> + ISR_lock_Context *lock_context
> )
> {
> - if ( !_States_Is_dormant( the_thread->current_state ) ) {
> - the_thread->Start.Entry = *entry;
> + Per_CPU_Control *cpu_self;
>
> - _Thread_Request_life_change(
> - the_thread,
> - executing,
> - the_thread->Start.initial_priority,
> - THREAD_LIFE_RESTARTING
> - );
> + _Thread_State_acquire_critical( the_thread, lock_context );
>
> - return true;
> + if ( _States_Is_dormant( the_thread->current_state ) ) {
> + _Thread_State_release( the_thread, lock_context );
> + return false;
> }
>
> - return false;
> + the_thread->Start.Entry = *entry;
> +
> + cpu_self = _Thread_Dispatch_disable_critical( lock_context );
> + _Thread_State_release( the_thread, lock_context );
> +
> + _Thread_Request_life_change(
> + the_thread,
> + NULL,
> + the_thread->Start.initial_priority,
> + THREAD_LIFE_RESTARTING
> + );
> +
> + _Thread_Dispatch_enable( cpu_self );
> + return true;
> +}
> +
> +void _Thread_Restart_self(
> + Thread_Control *executing,
> + const Thread_Entry_information *entry,
> + ISR_lock_Context *lock_context
> +)
> +{
> + Per_CPU_Control *cpu_self;
> + Priority_Control unused;
> +
> + _Assert(
> + _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE
> + );
> + _Assert(
> + executing->current_state == STATES_READY
> + || executing->current_state == STATES_SUSPENDED
> + );
> +
> + _Thread_State_acquire_critical( executing, lock_context );
> +
> + executing->Start.Entry = *entry;
> + _Thread_Change_life_locked(
> + executing,
> + 0,
> + THREAD_LIFE_RESTARTING,
> + THREAD_LIFE_PROTECTED
> + );
> +
> + cpu_self = _Thread_Dispatch_disable_critical( lock_context );
> + _Thread_State_release( executing, lock_context );
> +
> + _Thread_Set_priority(
> + executing,
> + executing->Start.initial_priority,
> + &unused,
> + true
> + );
> +
> + _Thread_Dispatch_enable( cpu_self );
> + RTEMS_UNREACHABLE();
> }
>
> static Thread_Life_state _Thread_Change_life(
> --
> 1.8.4.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list