bool _Scheduler_Set_affinity( Thread_Control *the_thread, size_t cpusetsize, const cpu_set_t *cpuset ) { Processor_mask affinity; Processor_mask_Copy_status status; const Scheduler_Control *scheduler; Scheduler_Node *node; ISR_lock_Context lock_context; bool ok; status = _Processor_mask_From_cpu_set_t( &affinity, cpusetsize, cpuset ); if ( !_Processor_mask_Is_at_most_partial_loss( status ) ) { return false; } /* * Reduce affinity set to the online processors to be in line with * _Thread_Initialize() which sets the default affinity to the set of online * processors. */ _Processor_mask_And( &affinity, _SMP_Get_online_processors(), &affinity ); scheduler = _Thread_Scheduler_get_home( the_thread ); _Scheduler_Acquire_critical( scheduler, &lock_context ); node = _Thread_Scheduler_get_home_node( the_thread ); #if defined(RTEMS_SMP) ok = ( *scheduler->Operations.set_affinity )( scheduler, the_thread, node, &affinity ); if ( ok ) { _Processor_mask_Assign( &the_thread->Scheduler.Affinity, &affinity ); } #else ok = _Scheduler_default_Set_affinity_body( scheduler, the_thread, node, &affinity ); #endif _Scheduler_Release_critical( scheduler, &lock_context ); return ok; }
static void _Thread_Free( Thread_Control *the_thread ) { Thread_Information *information = (Thread_Information *) _Objects_Get_information_id( the_thread->Object.id ); _User_extensions_Thread_delete( the_thread ); _User_extensions_Destroy_iterators( the_thread ); _ISR_lock_Destroy( &the_thread->Keys.Lock ); _Scheduler_Node_destroy( _Thread_Scheduler_get_home( the_thread ), _Thread_Scheduler_get_home_node( the_thread ) ); _ISR_lock_Destroy( &the_thread->Timer.Lock ); /* * The thread might have been FP. So deal with that. */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) if ( _Thread_Is_allocated_fp( the_thread ) ) _Thread_Deallocate_fp(); #endif _Workspace_Free( the_thread->Start.fp_context ); #endif _Freechain_Put( &information->Free_thread_queue_heads, the_thread->Wait.spare_heads ); /* * Free the rest of the memory associated with this task * and set the associated pointers to NULL for safety. */ _Thread_Stack_Free( the_thread ); _Workspace_Free( the_thread->Start.tls_area ); #if defined(RTEMS_SMP) _ISR_lock_Destroy( &the_thread->Scheduler.Lock ); _ISR_lock_Destroy( &the_thread->Wait.Lock.Default ); _SMP_lock_Stats_destroy( &the_thread->Potpourri_stats ); #endif _Thread_queue_Destroy( &the_thread->Join_queue ); _Objects_Free( &information->Objects, &the_thread->Object ); }
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; Thread_queue_Context queue_context; const Scheduler_Control *scheduler; Priority_Control old_priority; rtems_status_code status; if ( old_priority_p == NULL ) { return RTEMS_INVALID_ADDRESS; } _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_clear_priority_updates( &queue_context ); the_thread = _Thread_Get( id, &queue_context.Lock_context.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 } _Thread_Wait_acquire_critical( the_thread, &queue_context ); scheduler = _Thread_Scheduler_get_home( the_thread ); old_priority = _Thread_Get_priority( the_thread ); if ( new_priority != RTEMS_CURRENT_PRIORITY ) { status = _RTEMS_tasks_Set_priority( the_thread, scheduler, new_priority, &queue_context ); } else { _Thread_Wait_release( the_thread, &queue_context ); status = RTEMS_SUCCESSFUL; } *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority ); return status; }
static int _POSIX_Set_sched_param( Thread_Control *the_thread, int policy, struct sched_param *param, Thread_CPU_budget_algorithms budget_algorithm, Thread_CPU_budget_algorithm_callout budget_callout, Thread_queue_Context *queue_context ) { const Scheduler_Control *scheduler; POSIX_API_Control *api; int normal_prio; int low_prio; bool valid; Priority_Control core_normal_prio; Priority_Control core_low_prio; normal_prio = param->sched_priority; scheduler = _Thread_Scheduler_get_home( the_thread ); core_normal_prio = _POSIX_Priority_To_core( scheduler, normal_prio, &valid ); if ( !valid ) { return EINVAL; } if ( policy == SCHED_SPORADIC ) { low_prio = param->sched_ss_low_priority; } else { low_prio = normal_prio; } core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid ); if ( !valid ) { return EINVAL; } api = the_thread->API_Extensions[ THREAD_API_POSIX ]; _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer ); _Priority_Node_set_priority( &the_thread->Real_priority, core_normal_prio ); if ( _Priority_Node_is_active( &api->Sporadic.Low_priority ) ) { _Thread_Priority_add( the_thread, &the_thread->Real_priority, queue_context ); _Thread_Priority_remove( the_thread, &api->Sporadic.Low_priority, queue_context ); _Priority_Node_set_inactive( &api->Sporadic.Low_priority ); } else { _Thread_Priority_changed( the_thread, &the_thread->Real_priority, false, queue_context ); } the_thread->budget_algorithm = budget_algorithm; the_thread->budget_callout = budget_callout; _Priority_Node_set_priority( &api->Sporadic.Low_priority, core_low_prio ); api->Sporadic.sched_ss_repl_period = param->sched_ss_repl_period; api->Sporadic.sched_ss_init_budget = param->sched_ss_init_budget; api->Sporadic.sched_ss_max_repl = param->sched_ss_max_repl; if ( policy == SCHED_SPORADIC ) { _POSIX_Threads_Sporadic_timer_insert( the_thread, api ); } else { the_thread->cpu_time_budget = rtems_configuration_get_ticks_per_timeslice(); } return 0; }