static Thread_Life_state _Thread_Change_life_locked(
  Thread_Control    *the_thread,
  Thread_Life_state  clear,
  Thread_Life_state  set,
  Thread_Life_state  ignore
)
{
  Thread_Life_state previous;
  Thread_Life_state state;

  previous = the_thread->Life.state;
  state = previous;
  state &= ~clear;
  state |= set;
  the_thread->Life.state = state;

  state &= ~ignore;

  if (
    _Thread_Is_life_change_allowed( state )
      && _Thread_Is_life_changing( state )
  ) {
    the_thread->is_preemptible   = the_thread->Start.is_preemptible;
    the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
    the_thread->budget_callout   = the_thread->Start.budget_callout;

    _Thread_Add_post_switch_action(
      the_thread,
      &the_thread->Life.Action,
      _Thread_Life_action_handler
    );
  }

  return previous;
}
Esempio n. 2
0
static void _Thread_Add_life_change_action(
  Thread_Control *the_thread
)
{
  _Thread_Add_post_switch_action(
    the_thread,
    &the_thread->Life.Action,
    _Thread_Life_action_handler
  );
}
Esempio n. 3
0
static void _Thread_Start_life_change_for_executing(
  Thread_Control *executing
)
{
  _Assert( executing->Timer.state == WATCHDOG_INACTIVE );
  _Assert(
    executing->current_state == STATES_READY
      || executing->current_state == STATES_SUSPENDED
  );

  _Thread_Add_post_switch_action( executing, &executing->Life.Action );
}
Esempio n. 4
0
static bool _POSIX_signals_Unblock_thread_done(
  Thread_Control    *the_thread,
  POSIX_API_Control *api,
  bool               status
)
{
  ISR_lock_Context lock_context;

  _Thread_State_acquire( the_thread, &lock_context );
  _Thread_Add_post_switch_action(
    the_thread,
    &api->Signal_action,
    _POSIX_signals_Action_handler
  );
  _Thread_State_release( the_thread, &lock_context );

  return status;
}
Esempio n. 5
0
static void _Thread_Start_life_change(
  Thread_Control          *the_thread,
  const Scheduler_Control *scheduler,
  Priority_Control         priority
)
{
  the_thread->is_preemptible   = the_thread->Start.is_preemptible;
  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
  the_thread->budget_callout   = the_thread->Start.budget_callout;
  the_thread->real_priority    = priority;

  _Thread_Set_state( the_thread, STATES_RESTARTING );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove( &the_thread->Timer );
  _Scheduler_Set_priority_if_higher( scheduler, the_thread, priority );
  _Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
  _Thread_Ready( the_thread );
  _Thread_Request_dispatch_if_executing( the_thread );
}
Esempio n. 6
0
static void _Thread_Start_life_change(
  Thread_Control          *the_thread,
  const Scheduler_Control *scheduler,
  Priority_Control         priority
)
{
  the_thread->is_preemptible   = the_thread->Start.is_preemptible;
  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
  the_thread->budget_callout   = the_thread->Start.budget_callout;

  _Thread_Set_state( the_thread, STATES_RESTARTING );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove_ticks( &the_thread->Timer );
  _Thread_Change_priority(
    the_thread,
    priority,
    NULL,
    _Thread_Raise_real_priority_filter,
    false
  );
  _Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
  _Thread_Ready( the_thread );
}
Esempio n. 7
0
rtems_status_code rtems_task_mode(
  rtems_mode  mode_set,
  rtems_mode  mask,
  rtems_mode *previous_mode_set
)
{
  Thread_Control     *executing;
  RTEMS_API_Control  *api;
  ASR_Information    *asr;
  bool                preempt_enabled;
  bool                needs_asr_dispatching;
  rtems_mode          old_mode;

  if ( !previous_mode_set )
    return RTEMS_INVALID_ADDRESS;

  executing     = _Thread_Get_executing();
  api = executing->API_Extensions[ THREAD_API_RTEMS ];
  asr = &api->Signal;

  old_mode  = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;

  if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )
    old_mode |= RTEMS_NO_TIMESLICE;
  else
    old_mode |= RTEMS_TIMESLICE;

  old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
  old_mode |= _ISR_Get_level();

  *previous_mode_set = old_mode;

  /*
   *  These are generic thread scheduling characteristics.
   */
  preempt_enabled = false;
  if ( mask & RTEMS_PREEMPT_MASK ) {
#if defined( RTEMS_SMP )
    if ( rtems_configuration_is_smp_enabled() &&
         !_Modes_Is_preempt( mode_set ) ) {
      return RTEMS_NOT_IMPLEMENTED;
    }
#endif
    bool is_preempt_enabled = _Modes_Is_preempt( mode_set );

    preempt_enabled = !executing->is_preemptible && is_preempt_enabled;
    executing->is_preemptible = is_preempt_enabled;
  }

  if ( mask & RTEMS_TIMESLICE_MASK ) {
    if ( _Modes_Is_timeslice(mode_set) ) {
      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
      executing->cpu_time_budget =
        rtems_configuration_get_ticks_per_timeslice();
    } else
      executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
  }

  /*
   *  Set the new interrupt level
   */
  if ( mask & RTEMS_INTERRUPT_MASK )
    _Modes_Set_interrupt_level( mode_set );

  /*
   *  This is specific to the RTEMS API
   */
  needs_asr_dispatching = false;
  if ( mask & RTEMS_ASR_MASK ) {
    bool is_asr_enabled = !_Modes_Is_asr_disabled( mode_set );

    if ( is_asr_enabled != asr->is_enabled ) {
      asr->is_enabled = is_asr_enabled;
      _ASR_Swap_signals( asr );
      if ( _ASR_Are_signals_pending( asr ) ) {
        needs_asr_dispatching = true;
        _Thread_Add_post_switch_action(
          executing,
          &api->Signal_action,
          _Signal_Action_handler
        );
      }
    }
  }

  if ( preempt_enabled || needs_asr_dispatching ) {
    Per_CPU_Control  *cpu_self;
    ISR_lock_Context  lock_context;

    cpu_self = _Thread_Dispatch_disable();
    _Scheduler_Acquire( executing, &lock_context );
    _Scheduler_Schedule( executing );
    _Scheduler_Release( executing, &lock_context );
    _Thread_Dispatch_enable( cpu_self );
  }

  return RTEMS_SUCCESSFUL;
}