static void _Rate_monotonic_Release_job( Rate_monotonic_Control *the_period, Thread_Control *owner, rtems_interval next_length, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; Thread_queue_Context queue_context; uint64_t deadline; cpu_self = _Thread_Dispatch_disable_critical( lock_context ); deadline = _Watchdog_Per_CPU_insert_ticks( &the_period->Timer, cpu_self, next_length ); _Scheduler_Release_job( owner, &the_period->Priority, deadline, &queue_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_enable( cpu_self ); }
void _Thread_queue_Surrender_sticky( Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations ) { Thread_Control *new_owner; Per_CPU_Control *cpu_self; _Assert( heads != NULL ); _Thread_queue_Context_clear_priority_updates( queue_context ); new_owner = ( *operations->surrender )( queue, heads, previous_owner, queue_context ); queue->owner = new_owner; _Thread_queue_Make_ready_again( new_owner ); cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context.Lock_context ); _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context ); _Thread_Priority_and_sticky_update( previous_owner, -1 ); _Thread_Priority_and_sticky_update( new_owner, 0 ); _Thread_Dispatch_enable( cpu_self ); }
bool _Thread_Start( Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; _Thread_State_acquire_critical( the_thread, lock_context ); if ( !_States_Is_dormant( the_thread->current_state ) ) { _Thread_State_release( the_thread, lock_context ); return false; } the_thread->Start.Entry = *entry; _Thread_Load_environment( the_thread ); _Thread_Clear_state_locked( the_thread, STATES_ALL_SET ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Thread_State_release( the_thread, lock_context ); _User_extensions_Thread_start( the_thread ); _Thread_Dispatch_enable( cpu_self ); return true; }
rtems_status_code rtems_task_wake_after( rtems_interval ticks ) { /* * It is critical to obtain the executing thread after thread dispatching is * disabled on SMP configurations. */ Thread_Control *executing; Per_CPU_Control *cpu_self; cpu_self = _Thread_Dispatch_disable(); executing = _Thread_Executing; if ( ticks == 0 ) { _Thread_Yield( executing ); } else { _Thread_Set_state( executing, STATES_DELAYING ); _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED ); _Watchdog_Initialize( &executing->Timer, _Thread_Timeout, 0, executing ); _Watchdog_Insert_ticks( &executing->Timer, ticks ); } _Thread_Dispatch_enable( cpu_self ); return RTEMS_SUCCESSFUL; }
static void _Mutex_Release_slow( Mutex_Control *mutex, Thread_Control *executing, Thread_queue_Heads *heads, bool keep_priority, ISR_lock_Context *lock_context ) { if (heads != NULL) { const Thread_queue_Operations *operations; Thread_Control *first; operations = MUTEX_TQ_OPERATIONS; first = ( *operations->first )( heads ); mutex->owner = first; _Thread_queue_Extract_critical( &mutex->Queue.Queue, operations, first, lock_context ); } else { _Mutex_Queue_release( mutex, lock_context); } if ( !keep_priority ) { Per_CPU_Control *cpu_self; cpu_self = _Thread_Dispatch_disable(); _Thread_Restore_priority( executing ); _Thread_Dispatch_enable( cpu_self ); } }
int pthread_kill( pthread_t thread, int sig ) { Thread_Control *the_thread; ISR_lock_Context lock_context; POSIX_API_Control *api; Per_CPU_Control *cpu_self; if ( !is_valid_signo( sig ) ) { return EINVAL; } the_thread = _Thread_Get( thread, &lock_context ); if ( the_thread == NULL ) { return ESRCH; } api = the_thread->API_Extensions[ THREAD_API_POSIX ]; if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) { _ISR_lock_ISR_enable( &lock_context ); return 0; } /* XXX critical section */ api->signals_pending |= signo_to_mask( sig ); cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); _ISR_lock_ISR_enable( &lock_context ); (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL ); _Thread_Dispatch_enable( cpu_self ); return 0; }
static Per_CPU_Control *_Thread_Wait_for_join( Thread_Control *executing, Per_CPU_Control *cpu_self ) { #if defined(RTEMS_POSIX_API) ISR_lock_Context lock_context; _Thread_State_acquire( executing, &lock_context ); if ( _Thread_Is_joinable( executing ) && _Thread_queue_Is_empty( &executing->Join_queue.Queue ) ) { _Thread_Set_state_locked( executing, STATES_WAITING_FOR_JOIN_AT_EXIT ); _Thread_State_release( executing, &lock_context ); _Thread_Dispatch_enable( cpu_self ); /* Let other threads run */ cpu_self = _Thread_Dispatch_disable(); } else { _Thread_State_release( executing, &lock_context ); } #endif return cpu_self; }
rtems_task Init( rtems_task_argument argument ) { rtems_status_code sc; rtems_id mutex; Per_CPU_Control *cpu_self; TEST_BEGIN(); sc = rtems_semaphore_create( rtems_build_name('M', 'U', 'T', 'X'), 0, RTEMS_BINARY_SEMAPHORE, 0, &mutex ); directive_failed(sc, "rtems_semaphore_create"); /* * Call semaphore obtain with dispatching disabled. Reenable * dispatching before checking the status returned since * directive_failed() checks for dispatching being enabled. */ puts( "rtems_semaphore_obtain - with dispatching disabled" ); cpu_self = _Thread_Dispatch_disable(); sc = rtems_semaphore_obtain(mutex, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT); _Thread_Dispatch_enable(cpu_self); directive_failed(sc, "rtems_semaphore_obtain"); TEST_END(); rtems_test_exit(0); }
static rtems_status_code _RTEMS_tasks_Set_priority( Thread_Control *the_thread, const Scheduler_Control *scheduler, Priority_Control new_priority, Thread_queue_Context *queue_context ) { Priority_Control core_new_priority; bool valid; Per_CPU_Control *cpu_self; core_new_priority = _RTEMS_Priority_To_core( scheduler, new_priority, &valid ); if ( !valid ) { _Thread_Wait_release( the_thread, queue_context ); return RTEMS_INVALID_PRIORITY; } _Thread_Priority_change( the_thread, &the_thread->Real_priority, core_new_priority, false, queue_context ); cpu_self = _Thread_queue_Dispatch_disable( queue_context ); _Thread_Wait_release( the_thread, queue_context ); _Thread_Priority_update( queue_context ); _Thread_Dispatch_enable( cpu_self ); return RTEMS_SUCCESSFUL; }
static int _POSIX_Threads_Join( pthread_t thread, void **value_ptr ) { Thread_Control *the_thread; Thread_queue_Context queue_context; Per_CPU_Control *cpu_self; Thread_Control *executing; void *value; _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_set_expected_level( &queue_context, 1 ); the_thread = _Thread_Get( thread, &queue_context.Lock_context ); if ( the_thread == NULL ) { return ESRCH; } cpu_self = _Per_CPU_Get(); executing = _Per_CPU_Get_executing( cpu_self ); if ( executing == the_thread ) { _ISR_lock_ISR_enable( &queue_context.Lock_context ); return EDEADLK; } _Thread_State_acquire_critical( the_thread, &queue_context.Lock_context ); if ( !_Thread_Is_joinable( the_thread ) ) { _Thread_State_release( the_thread, &queue_context.Lock_context ); return EINVAL; } if ( _States_Is_waiting_for_join_at_exit( the_thread->current_state ) ) { value = the_thread->Life.exit_value; _Thread_Clear_state_locked( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT ); _Thread_Dispatch_disable_with_CPU( cpu_self, &queue_context.Lock_context ); _Thread_State_release( the_thread, &queue_context.Lock_context ); _Thread_Dispatch_enable( cpu_self ); } else { _Thread_Join( the_thread, STATES_INTERRUPTIBLE_BY_SIGNAL | STATES_WAITING_FOR_JOIN, executing, &queue_context ); if ( _POSIX_Get_error_after_wait( executing ) != 0 ) { _Assert( _POSIX_Get_error_after_wait( executing ) == EINTR ); return EINTR; } value = executing->Wait.return_argument; } if ( value_ptr != NULL ) { *value_ptr = value; } return 0; }
/** * POSIX 1003.1b 4.5.2 - Get Process Times */ clock_t _times( struct tms *ptms ) { rtems_interval ticks, us_per_tick; Thread_Control *executing; if ( !ptms ) rtems_set_errno_and_return_minus_one( EFAULT ); /* * This call does not depend on TOD being initialized and can't fail. */ ticks = rtems_clock_get_ticks_since_boot(); us_per_tick = rtems_configuration_get_microseconds_per_tick(); /* * RTEMS technically has no notion of system versus user time * since there is no separation of OS from application tasks. * But we can at least make a distinction between the number * of ticks since boot and the number of ticks executed by this * this thread. */ { Timestamp_Control per_tick; uint32_t ticks_of_executing; uint32_t fractional_ticks; Per_CPU_Control *cpu_self; _Timestamp_Set( &per_tick, rtems_configuration_get_microseconds_per_tick() / TOD_MICROSECONDS_PER_SECOND, (rtems_configuration_get_nanoseconds_per_tick() % TOD_NANOSECONDS_PER_SECOND) ); cpu_self = _Thread_Dispatch_disable(); executing = _Thread_Executing; _Thread_Update_cpu_time_used( executing, &_Thread_Time_of_last_context_switch ); _Timestamp_Divide( &executing->cpu_time_used, &per_tick, &ticks_of_executing, &fractional_ticks ); _Thread_Dispatch_enable( cpu_self ); ptms->tms_utime = ticks_of_executing * us_per_tick; } ptms->tms_stime = ticks * us_per_tick; ptms->tms_cutime = 0; ptms->tms_cstime = 0; return ticks * us_per_tick; }
rtems_status_code rtems_task_set_priority( rtems_id id, rtems_task_priority new_priority, rtems_task_priority *old_priority_p ) { Thread_Control *the_thread; ISR_lock_Context lock_context; const Scheduler_Control *scheduler; Priority_Control old_priority; rtems_status_code status; if ( old_priority_p == NULL ) { return RTEMS_INVALID_ADDRESS; } the_thread = _Thread_Get( id, &lock_context ); if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p ); #else return RTEMS_INVALID_ID; #endif } if ( new_priority != RTEMS_CURRENT_PRIORITY ) { RTEMS_tasks_Set_priority_context context; Per_CPU_Control *cpu_self; cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); _ISR_lock_ISR_enable( &lock_context ); context.new_priority = new_priority; _Thread_Change_priority( the_thread, 0, &context, _RTEMS_tasks_Set_priority_filter, false ); _Thread_Dispatch_enable( cpu_self ); scheduler = context.scheduler; old_priority = context.old_priority; status = context.status; } else { _Thread_State_acquire_critical( the_thread, &lock_context ); scheduler = _Scheduler_Get_own( the_thread ); old_priority = _Thread_Get_priority( the_thread ); _Thread_State_release( the_thread, &lock_context ); status = RTEMS_SUCCESSFUL; } *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority ); return status; }
rtems_task High_task( rtems_task_argument argument ) { rtems_interrupt_level level; _Thread_Dispatch_disable(); benchmark_timer_initialize(); rtems_interrupt_local_disable( level ); isr_disable_time = benchmark_timer_read(); benchmark_timer_initialize(); #if defined(RTEMS_SMP) rtems_interrupt_local_enable( level ); rtems_interrupt_local_disable( level ); #else rtems_interrupt_flash( level ); #endif isr_flash_time = benchmark_timer_read(); benchmark_timer_initialize(); rtems_interrupt_local_enable( level ); isr_enable_time = benchmark_timer_read(); _Thread_Dispatch_enable( _Per_CPU_Get() ); benchmark_timer_initialize(); _Thread_Dispatch_disable(); thread_disable_dispatch_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Dispatch_enable( _Per_CPU_Get() ); thread_enable_dispatch_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED ); thread_set_state_time = benchmark_timer_read(); set_thread_dispatch_necessary( true ); benchmark_timer_initialize(); _Thread_Dispatch(); /* dispatches Middle_task */ }
Status_Control _Thread_queue_Enqueue_sticky( Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context ) { Per_CPU_Control *cpu_self; _Thread_Wait_claim( the_thread, queue ); if ( !_Thread_queue_Path_acquire_critical( queue, the_thread, queue_context ) ) { _Thread_queue_Path_release_critical( queue_context ); _Thread_Wait_restore_default( the_thread ); _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context ); _Thread_Wait_tranquilize( the_thread ); ( *queue_context->deadlock_callout )( the_thread ); return _Thread_Wait_get_status( the_thread ); } _Thread_queue_Context_clear_priority_updates( queue_context ); _Thread_Wait_claim_finalize( the_thread, operations ); ( *operations->enqueue )( queue, the_thread, queue_context ); _Thread_queue_Path_release_critical( queue_context ); the_thread->Wait.return_code = STATUS_SUCCESSFUL; _Thread_Wait_flags_set( the_thread, THREAD_QUEUE_INTEND_TO_BLOCK ); cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context.Lock_context ); _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context ); if ( cpu_self->thread_dispatch_disable_level != 1 ) { _Internal_error( INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE ); } _Thread_queue_Timeout( the_thread, cpu_self, queue_context ); _Thread_Priority_update( queue_context ); _Thread_Priority_and_sticky_update( the_thread, 1 ); _Thread_Dispatch_enable( cpu_self ); while ( _Thread_Wait_flags_get_acquire( the_thread ) == THREAD_QUEUE_INTEND_TO_BLOCK ) { /* Wait */ } _Thread_Wait_tranquilize( the_thread ); _Thread_Timer_remove( the_thread ); return _Thread_Wait_get_status( the_thread ); }
Status_Control _CORE_mutex_Surrender_slow( CORE_mutex_Control *the_mutex, Thread_Control *executing, Thread_queue_Heads *heads, bool keep_priority, Thread_queue_Context *queue_context ) { if ( heads != NULL ) { const Thread_queue_Operations *operations; Thread_Control *new_owner; bool unblock; operations = CORE_MUTEX_TQ_OPERATIONS; new_owner = ( *operations->first )( heads ); _CORE_mutex_Set_owner( the_mutex, new_owner ); unblock = _Thread_queue_Extract_locked( &the_mutex->Wait_queue.Queue, operations, new_owner, queue_context ); #if defined(RTEMS_MULTIPROCESSING) if ( _Objects_Is_local_id( new_owner->Object.id ) ) #endif { ++new_owner->resource_count; _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, new_owner ); } _Thread_queue_Unblock_critical( unblock, &the_mutex->Wait_queue.Queue, new_owner, &queue_context->Lock_context ); } else { _CORE_mutex_Release( the_mutex, queue_context ); } if ( !keep_priority ) { Per_CPU_Control *cpu_self; cpu_self = _Thread_Dispatch_disable(); _Thread_Restore_priority( executing ); _Thread_Dispatch_enable( cpu_self ); } return STATUS_SUCCESSFUL; }
static void test_rtems_heap_allocate_aligned_with_boundary(void) { void *p = NULL; p = rtems_heap_allocate_aligned_with_boundary(1, 1, 1); rtems_test_assert( p != NULL ); free(p); _Thread_Dispatch_disable(); p = rtems_heap_allocate_aligned_with_boundary(1, 1, 1); _Thread_Dispatch_enable( _Per_CPU_Get() ); rtems_test_assert( p == NULL ); }
void pthread_exit( void *value_ptr ) { Thread_Control *executing; Per_CPU_Control *cpu_self; cpu_self = _Thread_Dispatch_disable(); executing = _Per_CPU_Get_executing( cpu_self ); _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr ); _Thread_Dispatch_enable( cpu_self ); RTEMS_UNREACHABLE(); }
rtems_status_code rtems_task_set_scheduler( rtems_id task_id, rtems_id scheduler_id, rtems_task_priority priority ) { const Scheduler_Control *scheduler; Thread_Control *the_thread; Thread_queue_Context queue_context; ISR_lock_Context state_context; Per_CPU_Control *cpu_self; bool valid; Priority_Control core_priority; Status_Control status; if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) { return RTEMS_INVALID_ID; } core_priority = _RTEMS_Priority_To_core( scheduler, priority, &valid ); if ( !valid ) { return RTEMS_INVALID_PRIORITY; } _Thread_queue_Context_initialize( &queue_context ); the_thread = _Thread_Get( task_id, &queue_context.Lock_context.Lock_context ); if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) if ( _Thread_MP_Is_remote( task_id ) ) { return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } #endif return RTEMS_INVALID_ID; } cpu_self = _Thread_Dispatch_disable_critical( &queue_context.Lock_context.Lock_context ); _Thread_Wait_acquire_critical( the_thread, &queue_context ); _Thread_State_acquire_critical( the_thread, &state_context ); status = _Scheduler_Set( scheduler, the_thread, core_priority ); _Thread_State_release_critical( the_thread, &state_context ); _Thread_Wait_release( the_thread, &queue_context ); _Thread_Dispatch_enable( cpu_self ); return _Status_Get( status ); }
void _CORE_mutex_Seize_interrupt_blocking( CORE_mutex_Control *the_mutex, Thread_Control *executing, Watchdog_Interval timeout, ISR_lock_Context *lock_context ) { #if !defined(RTEMS_SMP) /* * We must disable thread dispatching here since we enable the interrupts for * priority inheritance mutexes. */ _Thread_Dispatch_disable(); #endif if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) { Thread_Control *holder = the_mutex->holder; #if !defined(RTEMS_SMP) /* * To enable interrupts here works only since exactly one executing thread * exists and only threads are allowed to seize and surrender mutexes with * the priority inheritance protocol. On SMP configurations more than one * executing thread may exist, so here we must not release the lock, since * otherwise the current holder may be no longer the holder of the mutex * once we released the lock. */ _Thread_queue_Release( &the_mutex->Wait_queue, lock_context ); #endif _Thread_Inherit_priority( holder, executing ); #if !defined(RTEMS_SMP) _Thread_queue_Acquire( &the_mutex->Wait_queue, lock_context ); #endif } _Thread_queue_Enqueue_critical( &the_mutex->Wait_queue.Queue, the_mutex->operations, executing, STATES_WAITING_FOR_MUTEX, timeout, CORE_MUTEX_TIMEOUT, lock_context ); #if !defined(RTEMS_SMP) _Thread_Dispatch_enable( _Per_CPU_Get() ); #endif }
void __ISR_Handler( uint32_t vector) { ISR_Level level; _ISR_Local_disable( level ); _Thread_Dispatch_disable(); #if (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE) if ( _ISR_Nest_level == 0 ) { /* Install irq stack */ _old_stack_ptr = stack_ptr; stack_ptr = _CPU_Interrupt_stack_high; } #endif _ISR_Nest_level++; _ISR_Local_enable( level ); /* call isp */ if ( _ISR_Vector_table[ vector]) (*_ISR_Vector_table[ vector ])( vector ); _ISR_Local_disable( level ); _Thread_Dispatch_enable( _Per_CPU_Get() ); _ISR_Nest_level--; #if (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE) if ( _ISR_Nest_level == 0 ) /* restore old stack pointer */ stack_ptr = _old_stack_ptr; #endif _ISR_Local_enable( level ); if ( _ISR_Nest_level ) return; if ( !_Thread_Dispatch_is_enabled() ) { return; } if ( _Thread_Dispatch_necessary ) { _Thread_Dispatch(); } }
int pthread_setschedparam( pthread_t thread, int policy, struct sched_param *param ) { Thread_CPU_budget_algorithms budget_algorithm; Thread_CPU_budget_algorithm_callout budget_callout; Thread_Control *the_thread; Per_CPU_Control *cpu_self; Thread_queue_Context queue_context; int error; if ( param == NULL ) { return EINVAL; } error = _POSIX_Thread_Translate_sched_param( policy, param, &budget_algorithm, &budget_callout ); if ( error != 0 ) { return error; } _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_clear_priority_updates( &queue_context ); the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context ); if ( the_thread == NULL ) { return ESRCH; } _Thread_Wait_acquire_critical( the_thread, &queue_context ); error = _POSIX_Set_sched_param( the_thread, policy, param, budget_algorithm, budget_callout, &queue_context ); cpu_self = _Thread_queue_Dispatch_disable( &queue_context ); _Thread_Wait_release( the_thread, &queue_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_enable( cpu_self ); return error; }
void _Condition_Wait( struct _Condition_Control *_condition, struct _Mutex_Control *_mutex ) { ISR_lock_Context lock_context; Per_CPU_Control *cpu_self; _ISR_lock_ISR_disable( &lock_context ); cpu_self = _Condition_Do_wait( _condition, 0, &lock_context ); _Mutex_Release( _mutex ); _Thread_Dispatch_enable( cpu_self ); _Mutex_Acquire( _mutex ); }
void _Thread_queue_Surrender( Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations ) { Thread_Control *new_owner; bool unblock; Per_CPU_Control *cpu_self; _Assert( heads != NULL ); _Thread_queue_Context_clear_priority_updates( queue_context ); new_owner = ( *operations->surrender )( queue, heads, previous_owner, queue_context ); queue->owner = new_owner; #if defined(RTEMS_MULTIPROCESSING) if ( !_Thread_queue_MP_set_callout( new_owner, queue_context ) ) #endif { _Thread_Resource_count_increment( new_owner ); } unblock = _Thread_queue_Make_ready_again( new_owner ); cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context.Lock_context ); _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context ); _Thread_Priority_update( queue_context ); if ( unblock ) { _Thread_Remove_timer_and_unblock( new_owner, queue ); } _Thread_Dispatch_enable( cpu_self ); }
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_Cancel( Thread_Control *the_thread, Thread_Control *executing, void *exit_value ) { ISR_lock_Context lock_context; Thread_Life_state previous; Per_CPU_Control *cpu_self; Priority_Control priority; _Assert( the_thread != executing ); _Thread_State_acquire( the_thread, &lock_context ); _Thread_Set_exit_value( the_thread, exit_value ); previous = _Thread_Change_life_locked( the_thread, 0, THREAD_LIFE_TERMINATING, 0 ); cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); priority = _Thread_Get_priority( executing ); if ( _States_Is_dormant( the_thread->current_state ) ) { _Thread_State_release( the_thread, &lock_context ); _Thread_Make_zombie( the_thread ); } else if ( _Thread_Is_life_change_allowed( previous ) ) { _Thread_Add_life_change_request( the_thread ); _Thread_State_release( the_thread, &lock_context ); _Thread_Finalize_life_change( the_thread, priority ); } else { _Thread_Add_life_change_request( the_thread ); _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED ); _Thread_State_release( the_thread, &lock_context ); _Thread_Raise_real_priority( the_thread, priority ); _Thread_Remove_life_change_request( the_thread ); } _Thread_Dispatch_enable( cpu_self ); }
int pthread_setschedprio( pthread_t thread, int prio ) { Thread_Control *the_thread; Per_CPU_Control *cpu_self; Thread_queue_Context queue_context; const Scheduler_Control *scheduler; Priority_Control new_priority; bool valid; the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context ); if ( the_thread == NULL ) { return ESRCH; } _Thread_queue_Context_clear_priority_updates( &queue_context ); _Thread_Wait_acquire_critical( the_thread, &queue_context ); scheduler = _Scheduler_Get_own( the_thread ); new_priority = _POSIX_Priority_To_core( scheduler, prio, &valid ); if ( !valid ) { _Thread_Wait_release( the_thread, &queue_context ); return EINVAL; } _Thread_Priority_change( the_thread, &the_thread->Real_priority, new_priority, true, &queue_context ); cpu_self = _Thread_Dispatch_disable_critical( &queue_context.Lock_context.Lock_context ); _Thread_Wait_release( the_thread, &queue_context ); _Thread_Priority_update( &queue_context ); _Thread_Dispatch_enable( cpu_self ); return 0; }
static bool test_body(void *arg) { test_context *ctx = arg; int busy; Per_CPU_Control *cpu_self; cpu_self = _Thread_Dispatch_disable(); rtems_test_assert( _Thread_Wait_get_status( ctx->semaphore_task_tcb ) == STATUS_SUCCESSFUL ); /* * Spend some time to make it more likely that we hit the test condition * below. */ for (busy = 0; busy < 1000; ++busy) { __asm__ volatile (""); } if (ctx->semaphore_task_tcb->Wait.queue == NULL) { ctx->thread_queue_was_null = true; } _Thread_Timeout(&ctx->semaphore_task_tcb->Timer.Watchdog); switch (_Thread_Wait_get_status(ctx->semaphore_task_tcb)) { case STATUS_SUCCESSFUL: ctx->status_was_successful = true; break; case STATUS_TIMEOUT: ctx->status_was_timeout = true; break; default: rtems_test_assert(0); break; } _Thread_Dispatch_enable(cpu_self); return ctx->thread_queue_was_null && ctx->status_was_successful && ctx->status_was_timeout; }
static rtems_status_code _Rate_monotonic_Block_while_active( Rate_monotonic_Control *the_period, rtems_interval length, Thread_Control *executing, ISR_lock_Context *lock_context ) { Per_CPU_Control *cpu_self; bool success; /* * Update statistics from the concluding period. */ _Rate_monotonic_Update_statistics( the_period ); /* * This tells the _Rate_monotonic_Timeout that this task is * in the process of blocking on the period and that we * may be changing the length of the next period. */ the_period->next_length = length; executing->Wait.return_argument = the_period; _Thread_Wait_flags_set( executing, RATE_MONOTONIC_INTEND_TO_BLOCK ); cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Rate_monotonic_Release( the_period, lock_context ); _Thread_Set_state( executing, STATES_WAITING_FOR_PERIOD ); success = _Thread_Wait_flags_try_change_acquire( executing, RATE_MONOTONIC_INTEND_TO_BLOCK, RATE_MONOTONIC_BLOCKED ); if ( !success ) { _Assert( _Thread_Wait_flags_get( executing ) == RATE_MONOTONIC_READY_AGAIN ); _Thread_Unblock( executing ); } _Thread_Dispatch_enable( cpu_self ); return RTEMS_SUCCESSFUL; }
void _Condition_Wait_recursive( struct _Condition_Control *_condition, struct _Mutex_recursive_Control *_mutex ) { ISR_lock_Context lock_context; Per_CPU_Control *cpu_self; unsigned int nest_level; _ISR_lock_ISR_disable( &lock_context ); cpu_self = _Condition_Do_wait( _condition, 0, &lock_context ); nest_level = _mutex->_nest_level; _mutex->_nest_level = 0; _Mutex_recursive_Release( _mutex ); _Thread_Dispatch_enable( cpu_self ); _Mutex_recursive_Acquire( _mutex ); _mutex->_nest_level = nest_level; }
rtems_status_code rtems_task_delete( rtems_id id ) { Thread_Control *the_thread; ISR_lock_Context lock_context; Thread_Control *executing; Per_CPU_Control *cpu_self; the_thread = _Thread_Get( id, &lock_context ); if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) if ( _Thread_MP_Is_remote( id ) ) { return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } #endif return RTEMS_INVALID_ID; } cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); _ISR_lock_ISR_enable( &lock_context ); executing = _Per_CPU_Get_executing( cpu_self ); if ( the_thread == executing ) { /* * The Classic tasks are neither detached nor joinable. In case of * self deletion, they are detached, otherwise joinable by default. */ _Thread_Exit( executing, THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED, NULL ); } else { _Thread_Close( the_thread, executing ); } _Thread_Dispatch_enable( cpu_self ); return RTEMS_SUCCESSFUL; }