[PATCH 06/16] posix: Rework sporadic server scheduling policy

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 17 10:51:43 UTC 2016


Instead of lowering the priority in case the initial budget is consumed
raise the priority for each new period.  Restore the normal priority
once the initial budget is consumed.  This makes it later easier to
combine the high priority phase with temporary priority boosts (e.g. via
priority ceiling and inheritance).

Use the thread lock to protect the POSIX thread attributes instead of
the thread state lock.  This makes it easier to change the thread
priority and keep the POSIX attributes consistent.

Fixes a false positive use of uninitialized variable warning.
---
 cpukit/posix/include/rtems/posix/pthreadimpl.h |  17 +--
 cpukit/posix/include/rtems/posix/threadsup.h   |  26 +++-
 cpukit/posix/src/psxtransschedparam.c          |   8 --
 cpukit/posix/src/pthread.c                     | 105 +++++++---------
 cpukit/posix/src/pthreadcreate.c               |  48 +++++---
 cpukit/posix/src/pthreadgetschedparam.c        |   7 +-
 cpukit/posix/src/pthreadsetschedparam.c        | 163 +++++++++++++++----------
 cpukit/posix/src/pthreadsetschedprio.c         |  71 ++++++++---
 cpukit/score/include/rtems/score/thread.h      |   2 +-
 9 files changed, 254 insertions(+), 193 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index ba99392..988246e 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -62,7 +62,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Threads_Sporadic_timer_insert(
     _Timespec_To_ticks( &api->Attributes.schedparam.sched_ss_init_budget );
 
   _Watchdog_Per_CPU_insert_relative(
-    &api->Sporadic_timer,
+    &api->Sporadic.Timer,
     _Per_CPU_Get(),
     _Timespec_To_ticks( &api->Attributes.schedparam.sched_ss_repl_period )
   );
@@ -81,21 +81,6 @@ void _POSIX_Threads_Sporadic_budget_callout(
 );
 
 /**
- * This routine supports the sporadic scheduling algorithm.  It
- * is scheduled to be executed at the end of each replenishment
- * period.  In sporadic scheduling a thread will execute at a
- * high priority for a user specified amount of CPU time.  When
- * it exceeds that amount of CPU time, its priority is automatically
- * lowered. This TSR is executed when it is time to replenish
- * the thread's processor budget and raise its priority.
- *
- * @param[in] id is ignored
- * @param[in] argument is a pointer to the Thread_Control structure
- *            for the thread being replenished.
- */
-void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog );
-
-/**
  * @brief Translate sched_param into SuperCore terms.
  *
  * This method translates the POSIX API sched_param into the corresponding
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
index e18a429..21977be 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -18,10 +18,7 @@
 #ifndef _RTEMS_POSIX_THREADSUP_H
 #define _RTEMS_POSIX_THREADSUP_H
 
-#include <rtems/score/coresem.h>
-#include <rtems/score/isrlock.h>
 #include <rtems/score/thread.h>
-#include <rtems/score/threadq.h>
 #include <rtems/score/watchdog.h>
 
 #include <pthread.h>
@@ -50,10 +47,27 @@ typedef struct {
   pthread_attr_t          Attributes;
 
   /**
-   * This is the timer which controls when the thread executes at
-   * high and low priority when using the sporadic scheduler.
+   * @brief Control block for the sporadic server scheduling policy.
    */
-  Watchdog_Control        Sporadic_timer;
+  struct {
+    /**
+     * @brief This is the timer which controls when the thread executes at high
+     * and low priority when using the sporadic server scheduling policy.
+     */
+    Watchdog_Control Timer;
+
+    /**
+     * @brief The low priority when using the sporadic server scheduling
+     * policy.
+     */
+    Priority_Control low_priority;
+
+    /**
+     * @brief The high priority when using the sporadic server scheduling
+     * policy.
+     */
+    Priority_Control high_priority;
+  } Sporadic;
 
   /** This is the set of signals which are currently unblocked. */
   sigset_t                signals_unblocked;
diff --git a/cpukit/posix/src/psxtransschedparam.c b/cpukit/posix/src/psxtransschedparam.c
index 89fadde..fb501b0 100644
--- a/cpukit/posix/src/psxtransschedparam.c
+++ b/cpukit/posix/src/psxtransschedparam.c
@@ -21,9 +21,7 @@
 #include <pthread.h>
 #include <errno.h>
 
-#include <rtems/system.h>
 #include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/priorityimpl.h>
 
 int _POSIX_Thread_Translate_sched_param(
   int                                  policy,
@@ -32,9 +30,6 @@ int _POSIX_Thread_Translate_sched_param(
   Thread_CPU_budget_algorithm_callout *budget_callout
 )
 {
-  if ( !_POSIX_Priority_Is_valid( param->sched_priority ) )
-    return EINVAL;
-
   *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
   *budget_callout = NULL;
 
@@ -66,9 +61,6 @@ int _POSIX_Thread_Translate_sched_param(
 	 _Timespec_To_ticks( &param->sched_ss_init_budget ) )
       return EINVAL;
 
-    if ( !_POSIX_Priority_Is_valid( param->sched_ss_low_priority ) )
-      return EINVAL;
-
     *budget_algorithm  = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
     *budget_callout = _POSIX_Threads_Sporadic_budget_callout;
     return 0;
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index ead24cf..ca7efa9 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -81,83 +81,57 @@ pthread_attr_t _POSIX_Threads_Default_attributes = {
   #endif
 };
 
-static bool _POSIX_Threads_Sporadic_budget_TSR_filter(
+static bool _POSIX_Threads_Sporadic_timer_filter(
   Thread_Control   *the_thread,
-  Priority_Control *new_priority,
+  Priority_Control *new_priority_p,
   void             *arg
 )
 {
-  the_thread->real_priority = *new_priority;
+  POSIX_API_Control *api;
+  Priority_Control   current_priority;
+  Priority_Control   new_priority;
 
-  /*
-   * If holding a resource, then do not change it.
-   *
-   * If this would make them less important, then do not change it.
-   */
-  return !_Thread_Owns_resources( the_thread ) &&
-    _Thread_Priority_less_than( the_thread->current_priority, *new_priority );
-}
+  api = arg;
 
-/*
- *  _POSIX_Threads_Sporadic_budget_TSR
- */
-void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
-{
-  POSIX_API_Control  *api;
-  Thread_Control     *the_thread;
-  ISR_lock_Context    lock_context;
-  Priority_Control    new_priority;
+  new_priority = api->Sporadic.high_priority;
+  *new_priority_p = new_priority;
 
-  api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer );
-  the_thread = api->thread;
+  current_priority = the_thread->current_priority;
+  the_thread->real_priority = new_priority;
 
-  _Thread_State_acquire( the_thread, &lock_context );
-
-  _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+  _Watchdog_Per_CPU_remove_relative( &api->Sporadic.Timer );
   _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
 
-  new_priority = _POSIX_Priority_To_core(
-    api->Attributes.schedparam.sched_priority
-  );
+  return _Thread_Priority_less_than( current_priority, new_priority )
+    || !_Thread_Owns_resources( the_thread );
+}
+
+static void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog )
+{
+  POSIX_API_Control *api;
+  Thread_Control    *the_thread;
 
-  _Thread_State_release( the_thread, &lock_context );
+  api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic.Timer );
+  the_thread = api->thread;
 
   _Thread_Change_priority(
     the_thread,
-    new_priority,
-    NULL,
-    _POSIX_Threads_Sporadic_budget_TSR_filter,
+    0,
+    api,
+    _POSIX_Threads_Sporadic_timer_filter,
     true
   );
 }
 
 static bool _POSIX_Threads_Sporadic_budget_callout_filter(
   Thread_Control   *the_thread,
-  Priority_Control *new_priority,
+  Priority_Control *new_priority_p,
   void             *arg
 )
 {
-  the_thread->real_priority = *new_priority;
-
-  /*
-   * If holding a resource, then do not change it.
-   *
-   * Make sure we are actually lowering it. If they have lowered it
-   * to logically lower than sched_ss_low_priority, then we do not want to
-   * change it.
-   */
-  return !_Thread_Owns_resources( the_thread ) &&
-    _Thread_Priority_less_than( *new_priority, the_thread->current_priority );
-}
-
-/*
- *  _POSIX_Threads_Sporadic_budget_callout
- */
-void _POSIX_Threads_Sporadic_budget_callout(
-  Thread_Control *the_thread
-)
-{
   POSIX_API_Control *api;
+  Priority_Control   current_priority;
+  Priority_Control   new_priority;
 
   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
 
@@ -167,11 +141,21 @@ void _POSIX_Threads_Sporadic_budget_callout(
    */
   the_thread->cpu_time_budget = UINT32_MAX;
 
+  new_priority = api->Sporadic.low_priority;
+  *new_priority_p = new_priority;
+
+  current_priority = the_thread->current_priority;
+  the_thread->real_priority = new_priority;
+
+  return _Thread_Priority_less_than( current_priority, new_priority )
+    || !_Thread_Owns_resources( the_thread );
+}
+
+void _POSIX_Threads_Sporadic_budget_callout( Thread_Control *the_thread )
+{
   _Thread_Change_priority(
     the_thread,
-    _POSIX_Priority_To_core(
-      api->Attributes.schedparam.sched_ss_low_priority
-    ),
+    0,
     NULL,
     _POSIX_Threads_Sporadic_budget_callout_filter,
     true
@@ -217,11 +201,8 @@ static bool _POSIX_Threads_Create_extension(
     api->signals_unblocked = executing_api->signals_unblocked;
   }
 
-  _Watchdog_Preinitialize( &api->Sporadic_timer, _Per_CPU_Get_by_index( 0 ) );
-  _Watchdog_Initialize(
-    &api->Sporadic_timer,
-    _POSIX_Threads_Sporadic_budget_TSR
-  );
+  _Watchdog_Preinitialize( &api->Sporadic.Timer, _Per_CPU_Get_by_index( 0 ) );
+  _Watchdog_Initialize( &api->Sporadic.Timer, _POSIX_Threads_Sporadic_timer );
 
   return true;
 }
@@ -236,7 +217,7 @@ static void _POSIX_Threads_Terminate_extension( Thread_Control *executing )
   _Thread_State_acquire( executing, &lock_context );
 
   if ( api->Attributes.schedpolicy == SCHED_SPORADIC ) {
-    _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+    _Watchdog_Per_CPU_remove_relative( &api->Sporadic.Timer );
   }
 
   _Thread_State_release( executing, &lock_context );
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index c7c2338..f2fc1ca 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -60,7 +60,10 @@ int pthread_create(
     }
   };
   const pthread_attr_t               *the_attr;
-  Priority_Control                    core_priority;
+  int                                 low_prio;
+  int                                 high_prio;
+  Priority_Control                    core_low_prio;
+  Priority_Control                    core_high_prio;
   Thread_CPU_budget_algorithms        budget_algorithm;
   Thread_CPU_budget_algorithm_callout budget_callout;
   bool                                is_fp;
@@ -71,7 +74,7 @@ int pthread_create(
   int                                 schedpolicy = SCHED_RR;
   struct sched_param                  schedparam;
   Objects_Name                        name;
-  int                                 rc;
+  int                                 error;
   ISR_lock_Context                    lock_context;
 
   if ( !start_routine )
@@ -130,25 +133,34 @@ int pthread_create(
   if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS )
     return ENOTSUP;
 
-  /*
-   *  Interpret the scheduling parameters.
-   */
-  if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) )
-    return EINVAL;
-
-  core_priority = _POSIX_Priority_To_core( schedparam.sched_priority );
-
-  /*
-   *  Set the core scheduling policy information.
-   */
-  rc = _POSIX_Thread_Translate_sched_param(
+  error = _POSIX_Thread_Translate_sched_param(
     schedpolicy,
     &schedparam,
     &budget_algorithm,
     &budget_callout
   );
-  if ( rc )
-    return rc;
+  if ( error != 0 ) {
+    return error;
+  }
+
+  if ( schedpolicy == SCHED_SPORADIC ) {
+    low_prio = schedparam.sched_ss_low_priority;
+    high_prio = schedparam.sched_priority;
+  } else {
+    low_prio = schedparam.sched_priority;
+    high_prio = low_prio;
+  }
+
+  if ( !_POSIX_Priority_Is_valid( low_prio ) ) {
+    return EINVAL;
+  }
+
+  if ( !_POSIX_Priority_Is_valid( high_prio ) ) {
+    return EINVAL;
+  }
+
+  core_low_prio = _POSIX_Priority_To_core( low_prio );
+  core_high_prio = _POSIX_Priority_To_core( high_prio );
 
 #if defined(RTEMS_SMP)
 #if __RTEMS_HAVE_SYS_CPUSET_H__
@@ -186,7 +198,7 @@ int pthread_create(
     the_attr->stackaddr,
     _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize),
     is_fp,
-    core_priority,
+    core_high_prio,
     true,                 /* preemptible */
     budget_algorithm,
     budget_callout,
@@ -226,6 +238,8 @@ int pthread_create(
   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
 
   _POSIX_Threads_Copy_attributes( &api->Attributes, the_attr );
+  api->Sporadic.low_priority = core_low_prio;
+  api->Sporadic.high_priority = core_high_prio;
 
   if ( schedpolicy == SCHED_SPORADIC ) {
     _ISR_lock_ISR_disable( &lock_context );
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index ed149f2..6751c64 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -48,15 +48,16 @@ int pthread_getschedparam(
     return ESRCH;
   }
 
-  _Thread_State_acquire_critical( the_thread, &lock_context );
-
   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+  _Thread_Lock_acquire_default_critical( the_thread, &lock_context );
+
   *policy = api->Attributes.schedpolicy;
   *param  = api->Attributes.schedparam;
   param->sched_priority = _POSIX_Priority_From_core(
     the_thread->real_priority
   );
 
-  _Thread_State_release( the_thread, &lock_context );
+  _Thread_Lock_release_default( the_thread, &lock_context );
   return 0;
 }
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index a2e13a0..15d016f 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -28,8 +28,82 @@
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/priorityimpl.h>
 #include <rtems/score/threadimpl.h>
-#include <rtems/score/watchdogimpl.h>
-#include <rtems/config.h>
+
+typedef struct {
+  int                                  policy;
+  const struct sched_param            *param;
+  Thread_CPU_budget_algorithms         budget_algorithm;
+  Thread_CPU_budget_algorithm_callout  budget_callout;
+  int                                  error;
+} POSIX_Set_sched_param_context;
+
+static bool _POSIX_Set_sched_param_filter(
+  Thread_Control   *the_thread,
+  Priority_Control *new_priority_p,
+  void             *arg
+)
+{
+  POSIX_Set_sched_param_context *context;
+  const struct sched_param      *param;
+  POSIX_API_Control             *api;
+  int                            low_prio;
+  int                            high_prio;
+  Priority_Control               core_low_prio;
+  Priority_Control               core_high_prio;
+  Priority_Control               current_priority;
+
+  context = arg;
+  param = context->param;
+
+  if ( context->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;
+  }
+
+  if ( !_POSIX_Priority_Is_valid( low_prio ) ) {
+    context->error = EINVAL;
+    return false;
+  }
+
+  if ( !_POSIX_Priority_Is_valid( high_prio ) ) {
+    context->error = EINVAL;
+    return false;
+  }
+
+  core_low_prio = _POSIX_Priority_To_core( low_prio );
+  core_high_prio = _POSIX_Priority_To_core( high_prio );
+
+  *new_priority_p = core_high_prio;
+
+  current_priority = the_thread->current_priority;
+  the_thread->real_priority = core_high_prio;
+
+  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+  _Watchdog_Per_CPU_remove_relative( &api->Sporadic.Timer );
+
+  api->Attributes.schedpolicy = context->policy;
+  api->Attributes.schedparam  = *param;
+  api->Sporadic.low_priority  = core_low_prio;
+  api->Sporadic.high_priority = core_high_prio;
+
+  the_thread->budget_algorithm = context->budget_algorithm;
+  the_thread->budget_callout   = context->budget_callout;
+
+  if ( context->policy == SCHED_SPORADIC ) {
+    _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
+  } else {
+    the_thread->cpu_time_budget =
+      rtems_configuration_get_ticks_per_timeslice();
+  }
+
+  context->error = 0;
+  return _Thread_Priority_less_than( current_priority, core_high_prio )
+    || !_Thread_Owns_resources( the_thread );
+}
 
 int pthread_setschedparam(
   pthread_t           thread,
@@ -37,85 +111,46 @@ int pthread_setschedparam(
   struct sched_param *param
 )
 {
-  Thread_Control                      *the_thread;
-  Per_CPU_Control                     *cpu_self;
-  POSIX_API_Control                   *api;
-  Thread_CPU_budget_algorithms         budget_algorithm;
-  Thread_CPU_budget_algorithm_callout  budget_callout;
-  int                                  eno;
-  Priority_Control                     unused;
-  ISR_lock_Context                     lock_context;
-  Priority_Control                     new_priority;
-
-  /*
-   *  Check all the parameters
-   */
+  Thread_Control                *the_thread;
+  Per_CPU_Control               *cpu_self;
+  POSIX_Set_sched_param_context  context;
+  ISR_lock_Context               lock_context;
+  int                            error;
 
   if ( param == NULL ) {
     return EINVAL;
   }
 
-  eno = _POSIX_Thread_Translate_sched_param(
+  error = _POSIX_Thread_Translate_sched_param(
     policy,
     param,
-    &budget_algorithm,
-    &budget_callout
+    &context.budget_algorithm,
+    &context.budget_callout
   );
-  if ( eno != 0 ) {
-    return eno;
+  if ( error != 0 ) {
+    return error;
   }
 
+  context.policy = policy;
+  context.param = param;
+
   the_thread = _Thread_Get( thread, &lock_context );
 
   if ( the_thread == NULL ) {
     return ESRCH;
   }
 
-  /*
-   *  Actually change the scheduling policy and parameters
-   */
-
   cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
-  _Thread_State_acquire_critical( the_thread, &lock_context );
-
-  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
-  if ( api->Attributes.schedpolicy == SCHED_SPORADIC ) {
-    _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
-  }
-
-  api->Attributes.schedpolicy = policy;
-  api->Attributes.schedparam  = *param;
-
-  the_thread->budget_algorithm = budget_algorithm;
-  the_thread->budget_callout   = budget_callout;
-
-  switch ( policy ) {
-    case SCHED_OTHER:
-    case SCHED_FIFO:
-    case SCHED_RR:
-      the_thread->cpu_time_budget =
-        rtems_configuration_get_ticks_per_timeslice();
-      new_priority = _POSIX_Priority_To_core(
-        api->Attributes.schedparam.sched_priority
-      );
-      break;
-  }
-
-  _Thread_State_release( the_thread, &lock_context );
-
-  switch ( policy ) {
-    case SCHED_OTHER:
-    case SCHED_FIFO:
-    case SCHED_RR:
-      _Thread_Set_priority( the_thread, new_priority, &unused, false );
-      break;
-
-    case SCHED_SPORADIC:
-      _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer );
-      break;
-  }
+  _ISR_lock_ISR_enable( &lock_context );
+
+  _Thread_Change_priority(
+    the_thread,
+    0,
+    &context,
+    _POSIX_Set_sched_param_filter,
+    false
+  );
 
   _Thread_Dispatch_enable( cpu_self );
-  return 0;
+  return context.error;
 }
diff --git a/cpukit/posix/src/pthreadsetschedprio.c b/cpukit/posix/src/pthreadsetschedprio.c
index b7166bc..25dc59f 100644
--- a/cpukit/posix/src/pthreadsetschedprio.c
+++ b/cpukit/posix/src/pthreadsetschedprio.c
@@ -17,20 +17,58 @@
 #include <rtems/posix/threadsup.h>
 #include <rtems/score/threadimpl.h>
 
-int pthread_setschedprio( pthread_t thread, int prio )
+typedef struct {
+  int prio;
+  int error;
+} POSIX_Set_sched_prio_context;
+
+static bool _POSIX_Set_sched_prio_filter(
+  Thread_Control   *the_thread,
+  Priority_Control *new_priority_p,
+  void             *arg
+)
 {
-  Thread_Control    *the_thread;
-  Per_CPU_Control   *cpu_self;
-  POSIX_API_Control *api;
-  Priority_Control   unused;
-  ISR_lock_Context   lock_context;
-  Priority_Control   new_priority;
+  POSIX_Set_sched_prio_context *context;
+  int                           prio;
+  POSIX_API_Control            *api;
+  Priority_Control              current_priority;
+  Priority_Control              new_priority;
+
+  context = arg;
+  prio = context->prio;
 
   if ( !_POSIX_Priority_Is_valid( prio ) ) {
-    return EINVAL;
+    context->error = EINVAL;
+    return false;
   }
 
   new_priority = _POSIX_Priority_To_core( prio );
+  *new_priority_p = new_priority;
+
+  current_priority = the_thread->current_priority;
+  the_thread->real_priority = new_priority;
+
+  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+  api->Sporadic.high_priority = new_priority;
+
+  if ( api->Sporadic.low_priority < new_priority ) {
+    api->Sporadic.low_priority  = new_priority;
+  }
+
+  context->error = 0;
+  return _Thread_Priority_less_than( current_priority, new_priority )
+    || !_Thread_Owns_resources( the_thread );
+}
+
+int pthread_setschedprio( pthread_t thread, int prio )
+{
+  Thread_Control               *the_thread;
+  Per_CPU_Control              *cpu_self;
+  POSIX_Set_sched_prio_context  context;
+  ISR_lock_Context              lock_context;
+
+  context.prio = prio;
 
   the_thread = _Thread_Get( thread, &lock_context );
 
@@ -38,16 +76,17 @@ int pthread_setschedprio( pthread_t thread, int prio )
     return ESRCH;
   }
 
-  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
   cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+  _ISR_lock_ISR_enable( &lock_context );
 
-  _Thread_State_acquire_critical( the_thread, &lock_context );
-  api->Attributes.schedparam.sched_priority = prio;
-  _Thread_State_release( the_thread, &lock_context );
-
-  _Thread_Set_priority( the_thread, new_priority, &unused, true );
+  _Thread_Change_priority(
+    the_thread,
+    0,
+    &context,
+    _POSIX_Set_sched_prio_filter,
+    true
+  );
 
   _Thread_Dispatch_enable( cpu_self );
-  return 0;
+  return context.error;
 }
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 7c5f079..cde31b4 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -657,6 +657,7 @@ typedef struct  {
  * provide their own lock.
  *
  * The thread lock protects the following thread variables
+ *  - POSIX_API_Control::Attributes,
  *  - Thread_Control::current_priority,
  *  - Thread_Control::Wait::queue, and
  *  - Thread_Control::Wait::operations.
@@ -710,7 +711,6 @@ struct _Thread_Control {
    * The lock of this thread queue is used for various purposes.  It protects
    * the following fields
    *
-   * - POSIX_API_Control::Attributes,
    * - RTEMS_API_Control::Signal,
    * - Thread_Control::budget_algorithm,
    * - Thread_Control::budget_callout,
-- 
1.8.4.5




More information about the devel mailing list