[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