/** * @file * * @brief Function sets scheduling policy and parameters of the thread * @ingroup POSIXAPI */ /* * 13.5.2 Dynamic Thread Scheduling Parameters Access, * P1003.1c/Draft 10, p. 124 */ /* COPYRIGHT (c) 1989-2014. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include 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 low_prio; int high_prio; bool valid; Priority_Control core_normal_prio; Priority_Control core_low_prio; if ( policy == SCHED_SPORADIC ) { low_prio = param->sched_ss_low_priority; high_prio = param->sched_priority; } else { low_prio = param->sched_priority; high_prio = low_prio; } scheduler = _Thread_Scheduler_get_home( the_thread ); core_normal_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid ); if ( !valid ) { return EINVAL; } core_low_prio = _POSIX_Priority_To_core( scheduler, high_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 ); } api->schedpolicy = policy; api->schedparam = *param; the_thread->budget_algorithm = budget_algorithm; the_thread->budget_callout = budget_callout; if ( policy == SCHED_SPORADIC ) { _Priority_Node_set_priority( &api->Sporadic.Low_priority, core_low_prio ); _POSIX_Threads_Sporadic_timer_insert( the_thread, api ); } else { the_thread->cpu_time_budget = rtems_configuration_get_ticks_per_timeslice(); } return 0; } 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; }