示例#1
0
bool _Thread_Set_life_protection( bool protect )
{
  bool previous_life_protection;
  ISR_Level level;
  Per_CPU_Control *cpu;
  Thread_Control *executing;
  Thread_Life_state previous_life_state;

  cpu = _Thread_Action_ISR_disable_and_acquire_for_executing( &level );
  executing = cpu->executing;

  previous_life_state = executing->Life.state;
  previous_life_protection = _Thread_Is_life_protected( previous_life_state );

  if ( protect ) {
    executing->Life.state = previous_life_state | THREAD_LIFE_PROTECTED;
  } else {
    executing->Life.state = previous_life_state & ~THREAD_LIFE_PROTECTED;
  }

  _Thread_Action_release_and_ISR_enable( cpu, level );

#if defined(RTEMS_SMP)
  /*
   * On SMP configurations it is possible that a life change of an executing
   * thread is requested, but this thread didn't notice it yet.  The life
   * change is first marked in the life state field and then all scheduling and
   * other thread state updates are performed.  The last step is to issues an
   * inter-processor interrupt if necessary.  Since this takes some time we
   * have to synchronize here.
   */
  if (
    !_Thread_Is_life_protected( previous_life_state )
      && _Thread_Is_life_changing( previous_life_state )
  ) {
    _Thread_Disable_dispatch();
    _Thread_Enable_dispatch();
  }
#endif

  if (
    !protect
      && _Thread_Is_life_changing( previous_life_state )
  ) {
    _Thread_Disable_dispatch();
    _Thread_Start_life_change_for_executing( executing );
    _Thread_Enable_dispatch();
  }

  return previous_life_protection;
}
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;
}