[PATCH 07/16] posix: Make POSIX API aware of scheduler instances

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


---
 cpukit/posix/include/rtems/posix/priorityimpl.h | 82 ++++++++++---------------
 cpukit/posix/src/mutexgetprioceiling.c          |  1 +
 cpukit/posix/src/mutexinit.c                    |  5 +-
 cpukit/posix/src/mutexsetprioceiling.c          | 35 +++++++----
 cpukit/posix/src/psxpriorityisvalid.c           |  8 +--
 cpukit/posix/src/pthread.c                      |  4 +-
 cpukit/posix/src/pthreadcreate.c                | 11 ++--
 cpukit/posix/src/pthreadgetschedparam.c         | 11 +++-
 cpukit/posix/src/pthreadsetschedparam.c         | 11 ++--
 cpukit/posix/src/pthreadsetschedprio.c          |  7 ++-
 10 files changed, 94 insertions(+), 81 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/priorityimpl.h b/cpukit/posix/include/rtems/posix/priorityimpl.h
index e3f23e7..7e770f7 100644
--- a/cpukit/posix/include/rtems/posix/priorityimpl.h
+++ b/cpukit/posix/include/rtems/posix/priorityimpl.h
@@ -30,29 +30,10 @@ extern "C" {
  *
  * @ingroup POSIXAPI
  *
- * @brief Interface to the POSIX Priority Implementation
- * 
- */
-/**@{**/
-
-/**
- * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
- *
- * "Numerically higher values represent higher priorities."
- *
- * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
- *
- * There are only 254 posix priority levels since a task at priority level
- * 255 would never run because of the RTEMS idle task.  This is necessary
- * because GNAT maps the lowest Ada task priority to the lowest thread
- * priority.  The lowest priority Ada task should get to run, so there is
- * a fundamental conflict with having 255 priorities.
+ * @brief Interface to the POSIX Priority Implementation.
  *
- * But since RTEMS can be configured with fewer than 256 priorities,
- * we use the internal constant.
+ * @{
  */
-#define POSIX_SCHEDULER_MAXIMUM_PRIORITY (PRIORITY_MAXIMUM - 1)
-
 
 /**
  *  This is the numerically least important POSIX priority.
@@ -72,53 +53,58 @@ int _POSIX_Priority_Get_maximum( const Scheduler_Control *scheduler );
 /**
  * @brief Check if POSIX priority is valid.
  * 
- * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
- *
- * "Numerically higher values represent higher priorities."
- *
- * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
- *
- * @param[in] priority is the priority to test
- *
- * @retval TRUE The priority is valid.
- * @retval FALSE The priority is invalid.
+ * According to POSIX, numerically higher values represent higher priorities.
+ * Thus, SuperCore has priorities run in the opposite sense of the POSIX API.
+ *
+ * Let N be the maximum priority of this scheduler instance.   The SuperCore
+ * priority zero is system reserved (PRIORITY_PSEUDO_ISR).  There are only
+ * N - 1 POSIX API priority levels since a thread at SuperCore priority N would
+ * never run because of the idle threads.  This is necessary because GNAT maps
+ * the lowest Ada task priority to the lowest thread priority.  The lowest
+ * priority Ada task should get to run, so there is a fundamental conflict with
+ * having N priorities.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The POSIX API priority to test.
+ *
+ * @retval true The priority is valid.
+ * @retval false Otherwise.
  */
 bool _POSIX_Priority_Is_valid(
-  int priority
+  const Scheduler_Control *scheduler,
+  int                      priority
 );
 
 /**
- * @brief Convert POSIX priority to SuperCore priority.
- *
- * This method converts a POSIX API priority into onto the corresponding
- * SuperCore value.
+ * @brief Converts POSIX priority to SuperCore priority.
  *
- * @param[in] priority is the POSIX API priority.
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The POSIX API priority.
  *
- * @return This method returns the corresponding SuperCore priority.
+ * @return Returns the corresponding SuperCore priority.
  */
 RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core(
-  int priority
+  const Scheduler_Control *scheduler,
+  int                      priority
 )
 {
-  return (Priority_Control) (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1);
+  return scheduler->maximum_priority - (Priority_Control) priority;
 }
 
 /**
- * @brief Convert SuperCore priority To POSIX priority.
- *
- * This method converts a SuperCore priority into onto the corresponding
- * POSIX API value.
+ * @brief Converts SuperCore priority to POSIX priority.
  *
- * @param[in] priority is the POSIX API priority.
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The SuperCore priority.
  *
- * @return This method returns the corresponding POSIX priority.
+ * @return Returns the corresponding POSIX API priority.
  */
 RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core(
-  Priority_Control priority
+  const Scheduler_Control *scheduler,
+  Priority_Control         priority
 )
 {
-  return (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1);
+  return (int) ( scheduler->maximum_priority - priority );
 }
 
 /** @} */
diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c
index 2df4776..eda02cb 100644
--- a/cpukit/posix/src/mutexgetprioceiling.c
+++ b/cpukit/posix/src/mutexgetprioceiling.c
@@ -46,6 +46,7 @@ int pthread_mutex_getprioceiling(
   _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
 
   *prioceiling = _POSIX_Priority_From_core(
+    &_Scheduler_Table[ 0 ],
     the_mutex->Mutex.priority_ceiling
   );
 
diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c
index 0d4833e..04c36e1 100644
--- a/cpukit/posix/src/mutexinit.c
+++ b/cpukit/posix/src/mutexinit.c
@@ -20,6 +20,7 @@
 
 #include <rtems/posix/muteximpl.h>
 #include <rtems/posix/priorityimpl.h>
+#include <rtems/score/schedulerimpl.h>
 
 /**
  * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
@@ -115,11 +116,11 @@ int pthread_mutex_init(
       prio_ceiling = _POSIX_Priority_Get_maximum( scheduler );
     }
 
-    if ( !_POSIX_Priority_Is_valid( prio_ceiling ) ) {
+    if ( !_POSIX_Priority_Is_valid( scheduler, prio_ceiling ) ) {
       return EINVAL;
     }
 
-    priority = _POSIX_Priority_To_core( prio_ceiling );
+    priority = _POSIX_Priority_To_core( scheduler, prio_ceiling );
   }
 
   the_mutex = _POSIX_Mutex_Allocate();
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
index 96e8dbf..65b93c7 100644
--- a/cpukit/posix/src/mutexsetprioceiling.c
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -31,18 +31,14 @@ int pthread_mutex_setprioceiling(
   int               *old_ceiling
 )
 {
-  register POSIX_Mutex_Control *the_mutex;
-  Priority_Control              the_priority;
-  int                           error;
+  POSIX_Mutex_Control     *the_mutex;
+  const Scheduler_Control *scheduler;
+  int                      error;
+  int                      unlock_error;
 
   if ( !old_ceiling )
     return EINVAL;
 
-  if ( !_POSIX_Priority_Is_valid( prioceiling ) )
-    return EINVAL;
-
-  the_priority = _POSIX_Priority_To_core( prioceiling );
-
   /*
    *  Must acquire the mutex before we can change it's ceiling.
    *  POSIX says block until we acquire it.
@@ -56,13 +52,26 @@ int pthread_mutex_setprioceiling(
   the_mutex = _POSIX_Mutex_Get_no_protection( mutex );
   _Assert( the_mutex != NULL );
 
+  scheduler = &_Scheduler_Table[ 0 ];
+
   *old_ceiling = _POSIX_Priority_From_core(
+    scheduler,
     the_mutex->Mutex.priority_ceiling
   );
-  the_mutex->Mutex.priority_ceiling = the_priority;
 
-  error = pthread_mutex_unlock( mutex );
-  _Assert( error == 0 );
-  (void) error;
-  return 0;
+  if ( _POSIX_Priority_Is_valid( scheduler, prioceiling ) ) {
+    Priority_Control priority;
+
+    priority = _POSIX_Priority_To_core( scheduler, prioceiling );
+    the_mutex->Mutex.priority_ceiling = priority;
+
+    error = 0;
+  } else {
+    error = EINVAL;
+  }
+
+  unlock_error = pthread_mutex_unlock( mutex );
+  _Assert( unlock_error == 0 );
+  (void) unlock_error;
+  return error;
 }
diff --git a/cpukit/posix/src/psxpriorityisvalid.c b/cpukit/posix/src/psxpriorityisvalid.c
index c883416..ea7f6f4 100644
--- a/cpukit/posix/src/psxpriorityisvalid.c
+++ b/cpukit/posix/src/psxpriorityisvalid.c
@@ -30,11 +30,11 @@ int _POSIX_Priority_Get_maximum( const Scheduler_Control *scheduler )
 }
 
 bool _POSIX_Priority_Is_valid(
-  int priority
+  const Scheduler_Control *scheduler,
+  int                      priority
 )
 {
-  return ((priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY) &&
-          (priority <= POSIX_SCHEDULER_MAXIMUM_PRIORITY));
-
+  return priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY
+    && (Priority_Control) priority < scheduler->maximum_priority;
 }
 
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index ca7efa9..b29acae 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -37,8 +37,9 @@
 #include <rtems/posix/psignalimpl.h>
 #include <rtems/posix/config.h>
 #include <rtems/posix/keyimpl.h>
-#include <rtems/score/cpusetimpl.h>
 #include <rtems/score/assert.h>
+#include <rtems/score/cpusetimpl.h>
+#include <rtems/score/schedulerimpl.h>
 
 Thread_Information _POSIX_Threads_Information;
 
@@ -182,6 +183,7 @@ static bool _POSIX_Threads_Create_extension(
   api->thread = created;
   _POSIX_Threads_Initialize_attributes( &api->Attributes );
   api->Attributes.schedparam.sched_priority = _POSIX_Priority_From_core(
+    _Scheduler_Get_own( created ),
     created->current_priority
   );
 
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index f2fc1ca..a4b4684 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -70,6 +70,7 @@ int pthread_create(
   bool                                status;
   Thread_Control                     *the_thread;
   Thread_Control                     *executing;
+  const Scheduler_Control            *scheduler;
   POSIX_API_Control                  *api;
   int                                 schedpolicy = SCHED_RR;
   struct sched_param                  schedparam;
@@ -151,16 +152,18 @@ int pthread_create(
     high_prio = low_prio;
   }
 
-  if ( !_POSIX_Priority_Is_valid( low_prio ) ) {
+  scheduler = _Scheduler_Get_own( executing );
+
+  if ( !_POSIX_Priority_Is_valid( scheduler, low_prio ) ) {
     return EINVAL;
   }
 
-  if ( !_POSIX_Priority_Is_valid( high_prio ) ) {
+  if ( !_POSIX_Priority_Is_valid( scheduler, high_prio ) ) {
     return EINVAL;
   }
 
-  core_low_prio = _POSIX_Priority_To_core( low_prio );
-  core_high_prio = _POSIX_Priority_To_core( high_prio );
+  core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio );
+  core_high_prio = _POSIX_Priority_To_core( scheduler, high_prio );
 
 #if defined(RTEMS_SMP)
 #if __RTEMS_HAVE_SYS_CPUSET_H__
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index 6751c64..55e4048 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -27,6 +27,7 @@
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/priorityimpl.h>
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
 
 int pthread_getschedparam(
   pthread_t           thread,
@@ -34,9 +35,10 @@ int pthread_getschedparam(
   struct sched_param *param
 )
 {
-  Thread_Control    *the_thread;
-  ISR_lock_Context   lock_context;
-  POSIX_API_Control *api;
+  Thread_Control          *the_thread;
+  ISR_lock_Context         lock_context;
+  POSIX_API_Control       *api;
+  const Scheduler_Control *scheduler;
 
   if ( policy == NULL || param == NULL ) {
     return EINVAL;
@@ -54,7 +56,10 @@ int pthread_getschedparam(
 
   *policy = api->Attributes.schedpolicy;
   *param  = api->Attributes.schedparam;
+
+  scheduler = _Scheduler_Get_own( the_thread );
   param->sched_priority = _POSIX_Priority_From_core(
+    scheduler,
     the_thread->real_priority
   );
 
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index 15d016f..148391d 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -28,6 +28,7 @@
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/priorityimpl.h>
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
 
 typedef struct {
   int                                  policy;
@@ -45,6 +46,7 @@ static bool _POSIX_Set_sched_param_filter(
 {
   POSIX_Set_sched_param_context *context;
   const struct sched_param      *param;
+  const Scheduler_Control       *scheduler;
   POSIX_API_Control             *api;
   int                            low_prio;
   int                            high_prio;
@@ -54,6 +56,7 @@ static bool _POSIX_Set_sched_param_filter(
 
   context = arg;
   param = context->param;
+  scheduler = _Scheduler_Get_own( the_thread );
 
   if ( context->policy == SCHED_SPORADIC ) {
     low_prio = param->sched_ss_low_priority;
@@ -63,18 +66,18 @@ static bool _POSIX_Set_sched_param_filter(
     high_prio = low_prio;
   }
 
-  if ( !_POSIX_Priority_Is_valid( low_prio ) ) {
+  if ( !_POSIX_Priority_Is_valid( scheduler, low_prio ) ) {
     context->error = EINVAL;
     return false;
   }
 
-  if ( !_POSIX_Priority_Is_valid( high_prio ) ) {
+  if ( !_POSIX_Priority_Is_valid( scheduler, 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 );
+  core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio );
+  core_high_prio = _POSIX_Priority_To_core( scheduler, high_prio );
 
   *new_priority_p = core_high_prio;
 
diff --git a/cpukit/posix/src/pthreadsetschedprio.c b/cpukit/posix/src/pthreadsetschedprio.c
index 25dc59f..dace70a 100644
--- a/cpukit/posix/src/pthreadsetschedprio.c
+++ b/cpukit/posix/src/pthreadsetschedprio.c
@@ -16,6 +16,7 @@
 #include <rtems/posix/priorityimpl.h>
 #include <rtems/posix/threadsup.h>
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
 
 typedef struct {
   int prio;
@@ -30,19 +31,21 @@ static bool _POSIX_Set_sched_prio_filter(
 {
   POSIX_Set_sched_prio_context *context;
   int                           prio;
+  const Scheduler_Control      *scheduler;
   POSIX_API_Control            *api;
   Priority_Control              current_priority;
   Priority_Control              new_priority;
 
   context = arg;
   prio = context->prio;
+  scheduler = _Scheduler_Get_own( the_thread );
 
-  if ( !_POSIX_Priority_Is_valid( prio ) ) {
+  if ( !_POSIX_Priority_Is_valid( scheduler, prio ) ) {
     context->error = EINVAL;
     return false;
   }
 
-  new_priority = _POSIX_Priority_To_core( prio );
+  new_priority = _POSIX_Priority_To_core( scheduler, prio );
   *new_priority_p = new_priority;
 
   current_priority = the_thread->current_priority;
-- 
1.8.4.5




More information about the devel mailing list