File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #ifdef HAVE_CONFIG_H
0042 #include "config.h"
0043 #endif
0044
0045 #include <pthread.h>
0046 #include <string.h>
0047 #include <errno.h>
0048
0049 #include <rtems/posix/pthreadimpl.h>
0050 #include <rtems/posix/priorityimpl.h>
0051 #include <rtems/score/threadimpl.h>
0052
0053 static int _POSIX_Set_sched_param(
0054 Thread_Control *the_thread,
0055 int policy,
0056 const struct sched_param *param,
0057 const Thread_Configuration *config,
0058 Thread_queue_Context *queue_context
0059 )
0060 {
0061 const Scheduler_Control *scheduler;
0062 int normal_prio;
0063 bool valid;
0064 Priority_Control core_normal_prio;
0065 const Thread_CPU_budget_operations *cpu_budget_operations;
0066 #if defined(RTEMS_POSIX_API)
0067 POSIX_API_Control *api;
0068 int low_prio;
0069 Priority_Control core_low_prio;
0070 #endif
0071
0072 normal_prio = param->sched_priority;
0073
0074 scheduler = _Thread_Scheduler_get_home( the_thread );
0075
0076 core_normal_prio = _POSIX_Priority_To_core( scheduler, normal_prio, &valid );
0077 if ( !valid ) {
0078 return EINVAL;
0079 }
0080
0081 #if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS)
0082 the_thread->is_scheduler_change_inhibited = ( policy == SCHED_SPORADIC );
0083 #endif
0084
0085 #if defined(RTEMS_POSIX_API)
0086 if ( policy == SCHED_SPORADIC ) {
0087 low_prio = param->sched_ss_low_priority;
0088 } else {
0089 low_prio = normal_prio;
0090 }
0091
0092 core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid );
0093 if ( !valid ) {
0094 return EINVAL;
0095 }
0096
0097 api = the_thread->API_Extensions[ THREAD_API_POSIX ];
0098
0099 _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
0100 #endif
0101
0102 _Priority_Node_set_priority( &the_thread->Real_priority, core_normal_prio );
0103
0104 #if defined(RTEMS_POSIX_API)
0105 if ( !_Priority_Node_is_active( &the_thread->Real_priority ) ) {
0106 _Thread_Priority_add(
0107 the_thread,
0108 &the_thread->Real_priority,
0109 queue_context
0110 );
0111 _Thread_Priority_remove(
0112 the_thread,
0113 &api->Sporadic.Low_priority,
0114 queue_context
0115 );
0116 } else {
0117 #endif
0118 _Thread_Priority_changed(
0119 the_thread,
0120 &the_thread->Real_priority,
0121 PRIORITY_GROUP_LAST,
0122 queue_context
0123 );
0124 #if defined(RTEMS_POSIX_API)
0125 }
0126 #endif
0127
0128 cpu_budget_operations = config->cpu_budget_operations;
0129 the_thread->CPU_budget.operations = cpu_budget_operations;
0130
0131 if ( cpu_budget_operations != NULL ) {
0132 ( *cpu_budget_operations->initialize )( the_thread );
0133 }
0134
0135 #if defined(RTEMS_POSIX_API)
0136 _Priority_Node_set_priority( &api->Sporadic.Low_priority, core_low_prio );
0137 api->Sporadic.sched_ss_repl_period = param->sched_ss_repl_period;
0138 api->Sporadic.sched_ss_init_budget = param->sched_ss_init_budget;
0139 api->Sporadic.sched_ss_max_repl = param->sched_ss_max_repl;
0140
0141 if ( policy == SCHED_SPORADIC ) {
0142 _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
0143 }
0144 #endif
0145
0146 return 0;
0147 }
0148
0149 int pthread_setschedparam(
0150 pthread_t thread,
0151 int policy,
0152 #ifdef HAVE_PTHREAD_SETSCHEDPARAM_CONST
0153 const struct sched_param *param
0154 #else
0155 struct sched_param *param
0156 #endif
0157 )
0158 {
0159 Thread_Configuration config;
0160 Thread_Control *the_thread;
0161 Per_CPU_Control *cpu_self;
0162 Thread_queue_Context queue_context;
0163 int error;
0164
0165 if ( param == NULL ) {
0166 return EINVAL;
0167 }
0168
0169 memset( &config, 0, sizeof( config ) );
0170 error = _POSIX_Thread_Translate_sched_param( policy, param, &config );
0171 if ( error != 0 ) {
0172 return error;
0173 }
0174
0175 _Thread_queue_Context_initialize( &queue_context );
0176 _Thread_queue_Context_clear_priority_updates( &queue_context );
0177 the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context );
0178
0179 if ( the_thread == NULL ) {
0180 return ESRCH;
0181 }
0182
0183 _Thread_Wait_acquire_critical( the_thread, &queue_context );
0184 error = _POSIX_Set_sched_param(
0185 the_thread,
0186 policy,
0187 param,
0188 &config,
0189 &queue_context
0190 );
0191 cpu_self = _Thread_queue_Dispatch_disable( &queue_context );
0192 _Thread_Wait_release( the_thread, &queue_context );
0193 _Thread_Priority_update( &queue_context );
0194 _Thread_Dispatch_enable( cpu_self );
0195 return error;
0196 }