diff --git a/cpukit/include/rtems/score/schedulerimpl.h b/cpukit/include/rtems/score/schedulerimpl.h index 2ca3e6e8b7..36d464fb64 100644 --- a/cpukit/include/rtems/score/schedulerimpl.h +++ b/cpukit/include/rtems/score/schedulerimpl.h @@ -942,6 +942,12 @@ static inline Status_Control _Scheduler_Set( #endif +#if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS) + if ( the_thread->is_scheduler_change_inhibited ) { + return STATUS_RESOURCE_IN_USE; + } +#endif + if ( the_thread->Wait.queue != NULL ) { return STATUS_RESOURCE_IN_USE; } diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h index 43e8d51296..bf143990e4 100644 --- a/cpukit/include/rtems/score/thread.h +++ b/cpukit/include/rtems/score/thread.h @@ -112,6 +112,16 @@ extern "C" { #define RTEMS_SCORE_THREAD_REAL_PRIORITY_MAY_BE_INACTIVE #endif +#if defined(RTEMS_POSIX_API) && defined(RTEMS_SMP) +/** + * @brief This define enables support to inhibit scheduler changes. + * + * For example, the POSIX sporadic server adds a second priority to a thread. + * We cannot account for this priority in a scheduler change. + */ +#define RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS +#endif + /** * @brief Type of the numeric argument of a thread entry function with at * least one numeric argument. @@ -911,6 +921,16 @@ struct _Thread_Control { */ bool was_created_with_inherited_scheduler; +#if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS) + /** + * @brief This field is true, if scheduler changes are inhibited. + * + * Currently, the POSIX sporadic server is the only inhibitor. If more are + * added, then this needs to be changed to a counter or a bit field. + */ + bool is_scheduler_change_inhibited; +#endif + /** * @brief This member contains the CPU budget control used to manage the CPU * budget of the thread. diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index c0e00bb775..540eaf96f8 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -301,6 +301,9 @@ int pthread_create( the_attr->schedparam.sched_ss_max_repl; if ( schedpolicy == SCHED_SPORADIC ) { +#if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS) + the_thread->is_scheduler_change_inhibited = true; +#endif _POSIX_Threads_Sporadic_timer( &api->Sporadic.Timer ); } #endif diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c index 0eecba1f12..a25c9754c3 100644 --- a/cpukit/posix/src/pthreadsetschedparam.c +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -78,6 +78,10 @@ static int _POSIX_Set_sched_param( return EINVAL; } +#if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS) + the_thread->is_scheduler_change_inhibited = ( policy == SCHED_SPORADIC ); +#endif + #if defined(RTEMS_POSIX_API) if ( policy == SCHED_SPORADIC ) { low_prio = param->sched_ss_low_priority;