void _Thread_Exit( Thread_Control *executing, Thread_Life_state set, void *exit_value ) { ISR_lock_Context lock_context; _Assert( _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE ); _Assert( executing->current_state == STATES_READY || executing->current_state == STATES_SUSPENDED ); _Thread_State_acquire( executing, &lock_context ); _Thread_Set_exit_value( executing, exit_value ); _Thread_Change_life_locked( executing, 0, set, THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ); _Thread_State_release( executing, &lock_context ); }
void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer ) { Timer_Classes the_class; the_class = the_timer->the_class; if ( _Watchdog_Is_scheduled( &the_timer->Ticker ) ) { the_timer->stop_time = _Timer_Get_CPU_ticks( cpu ); _Watchdog_Remove( &cpu->Watchdog.Header[ _Timer_Watchdog_header_index( the_class ) ], &the_timer->Ticker ); } else if ( _Timer_Is_on_task_class( the_class ) ) { Timer_server_Control *timer_server; ISR_lock_Context lock_context; timer_server = _Timer_server; _Assert( timer_server != NULL ); _Timer_server_Acquire_critical( timer_server, &lock_context ); if ( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_PENDING ) { _Watchdog_Set_state( &the_timer->Ticker, WATCHDOG_INACTIVE ); _Chain_Extract_unprotected( &the_timer->Ticker.Node.Chain ); } _Timer_server_Release_critical( timer_server, &lock_context ); } }
void _Thread_Restart_self( Thread_Control *executing, const Thread_Entry_information *entry, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; Thread_queue_Context queue_context; _Assert( _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE ); _Assert( executing->current_state == STATES_READY || executing->current_state == STATES_SUSPENDED ); _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_clear_priority_updates( &queue_context ); _Thread_State_acquire_critical( executing, lock_context ); executing->Start.Entry = *entry; _Thread_Change_life_locked( executing, 0, THREAD_LIFE_RESTARTING, THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Thread_State_release( executing, lock_context ); _Thread_Wait_acquire_default( executing, lock_context ); _Thread_Priority_change( executing, &executing->Real_priority, executing->Start.initial_priority, false, &queue_context ); _Thread_Wait_release_default( executing, lock_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_enable( cpu_self ); RTEMS_UNREACHABLE(); }
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 | THREAD_LIFE_CHANGE_DEFERRED ); 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(); }
void _Watchdog_Insert( Watchdog_Header *header, Watchdog_Control *the_watchdog, uint64_t expire ) { RBTree_Node **link; RBTree_Node *parent; RBTree_Node *old_first; RBTree_Node *new_first; _Assert( _Watchdog_Get_state( the_watchdog ) == WATCHDOG_INACTIVE ); link = _RBTree_Root_reference( &header->Watchdogs ); parent = NULL; old_first = header->first; new_first = &the_watchdog->Node.RBTree; the_watchdog->expire = expire; while ( *link != NULL ) { Watchdog_Control *parent_watchdog; parent = *link; parent_watchdog = (Watchdog_Control *) parent; if ( expire < parent_watchdog->expire ) { link = _RBTree_Left_reference( parent ); } else { link = _RBTree_Right_reference( parent ); new_first = old_first; } } header->first = new_first; _RBTree_Add_child( &the_watchdog->Node.RBTree, parent, link ); _RBTree_Insert_color( &header->Watchdogs, &the_watchdog->Node.RBTree ); }
void _Thread_Life_action_handler( Thread_Control *executing, Thread_Action *action, ISR_lock_Context *lock_context ) { Thread_Life_state previous_life_state; Per_CPU_Control *cpu_self; (void) action; previous_life_state = executing->Life.state; executing->Life.state = previous_life_state | THREAD_LIFE_PROTECTED; _Thread_State_release( executing, lock_context ); if ( _Thread_Is_life_terminating( previous_life_state ) ) { _User_extensions_Thread_terminate( executing ); } else { _Assert( _Thread_Is_life_restarting( previous_life_state ) ); _User_extensions_Thread_restart( executing ); } cpu_self = _Thread_Dispatch_disable(); if ( _Thread_Is_life_terminating( previous_life_state ) ) { cpu_self = _Thread_Wait_for_join( executing, cpu_self ); _Thread_Make_zombie( executing ); /* FIXME: Workaround for https://devel.rtems.org/ticket/2751 */ cpu_self->dispatch_necessary = true; _Assert( cpu_self->heir != executing ); _Thread_Dispatch_enable( cpu_self ); RTEMS_UNREACHABLE(); } _Assert( _Thread_Is_life_restarting( previous_life_state ) ); _Thread_State_acquire( executing, lock_context ); _Thread_Change_life_locked( executing, THREAD_LIFE_PROTECTED | THREAD_LIFE_RESTARTING, 0, 0 ); _Thread_State_release( executing, lock_context ); _Assert( _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE ); _Assert( executing->current_state == STATES_READY || executing->current_state == STATES_SUSPENDED ); _User_extensions_Destroy_iterators( executing ); _Thread_Load_environment( executing ); #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) if ( executing->fp_context != NULL ) { _Context_Restore_fp( &executing->fp_context ); } #endif _Context_Restart_self( &executing->Registers ); RTEMS_UNREACHABLE(); }
static bool test_watchdog_is_inactive( test_watchdog *watchdog ) { return _Watchdog_Get_state( &watchdog->Base ) == WATCHDOG_INACTIVE; }