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