[PATCH 04/10] score: Simplify _Scheduler_Get_by_id()

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Nov 8 08:59:38 UTC 2016


Avoid dead code in non-SMP configurations.  Return scheduler identifier
independent of the current processor count of the scheduler via
rtems_scheduler_ident(), since this value may change during run-time.
Check the processor count in _Scheduler_Set() under scheduler lock
protection.

Update #2797.
---
 cpukit/rtems/include/rtems/rtems/tasks.h         |   2 -
 cpukit/rtems/src/schedulergetprocessorset.c      |   3 +-
 cpukit/rtems/src/schedulerident.c                |   8 +-
 cpukit/rtems/src/semsetpriority.c                |   3 +-
 cpukit/rtems/src/taskgetpriority.c               |   3 +-
 cpukit/rtems/src/tasksetscheduler.c              |   3 +-
 cpukit/score/include/rtems/score/schedulerimpl.h | 110 ++++++++++++++---------
 testsuites/smptests/smpscheduler02/init.c        |  11 ++-
 8 files changed, 83 insertions(+), 60 deletions(-)

diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index 180e50e..3a94e34 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -555,8 +555,6 @@ void rtems_task_iterate(
  * @retval RTEMS_SUCCESSFUL Successful operation.
  * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL.
  * @retval RTEMS_INVALID_NAME Invalid scheduler name.
- * @retval RTEMS_UNSATISFIED A scheduler with this name exists, but the
- * processor set of this scheduler is empty.
  */
 rtems_status_code rtems_scheduler_ident(
   rtems_name  name,
diff --git a/cpukit/rtems/src/schedulergetprocessorset.c b/cpukit/rtems/src/schedulergetprocessorset.c
index 016c368..275c563 100644
--- a/cpukit/rtems/src/schedulergetprocessorset.c
+++ b/cpukit/rtems/src/schedulergetprocessorset.c
@@ -34,7 +34,8 @@ rtems_status_code rtems_scheduler_get_processor_set(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
+  scheduler = _Scheduler_Get_by_id( scheduler_id );
+  if ( scheduler == NULL ) {
     return RTEMS_INVALID_ID;
   }
 
diff --git a/cpukit/rtems/src/schedulerident.c b/cpukit/rtems/src/schedulerident.c
index ee18af0..5bde8de 100644
--- a/cpukit/rtems/src/schedulerident.c
+++ b/cpukit/rtems/src/schedulerident.c
@@ -36,12 +36,8 @@ rtems_status_code rtems_scheduler_ident(
       const Scheduler_Control *scheduler = &_Scheduler_Table[ i ];
 
       if ( scheduler->name == name ) {
-        if ( _Scheduler_Get_processor_count( scheduler ) > 0 ) {
-          *id = _Scheduler_Build_id( i );
-          sc = RTEMS_SUCCESSFUL;
-        } else {
-          sc = RTEMS_UNSATISFIED;
-        }
+        *id = _Scheduler_Build_id( i );
+        sc = RTEMS_SUCCESSFUL;
       }
     }
   } else {
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index 37dea5d..123f627 100644
--- a/cpukit/rtems/src/semsetpriority.c
+++ b/cpukit/rtems/src/semsetpriority.c
@@ -138,7 +138,8 @@ rtems_status_code rtems_semaphore_set_priority(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
+  scheduler = _Scheduler_Get_by_id( scheduler_id );
+  if ( scheduler == NULL ) {
     return RTEMS_INVALID_ID;
   }
 
diff --git a/cpukit/rtems/src/taskgetpriority.c b/cpukit/rtems/src/taskgetpriority.c
index b6800e2..8fb8ad3 100644
--- a/cpukit/rtems/src/taskgetpriority.c
+++ b/cpukit/rtems/src/taskgetpriority.c
@@ -36,7 +36,8 @@ rtems_status_code rtems_task_get_priority(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
+  scheduler = _Scheduler_Get_by_id( scheduler_id );
+  if ( scheduler == NULL ) {
     return RTEMS_INVALID_ID;
   }
 
diff --git a/cpukit/rtems/src/tasksetscheduler.c b/cpukit/rtems/src/tasksetscheduler.c
index 3a860a1..f3b7143 100644
--- a/cpukit/rtems/src/tasksetscheduler.c
+++ b/cpukit/rtems/src/tasksetscheduler.c
@@ -35,7 +35,8 @@ rtems_status_code rtems_task_set_scheduler(
   Priority_Control         core_priority;
   Status_Control           status;
 
-  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
+  scheduler = _Scheduler_Get_by_id( scheduler_id );
+  if ( scheduler == NULL ) {
     return RTEMS_INVALID_ID;
   }
 
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 0abc1a0..8d804bb 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -828,18 +828,19 @@ RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index_by_id( Objects_Id id )
   return id - minimum_id;
 }
 
-RTEMS_INLINE_ROUTINE bool _Scheduler_Get_by_id(
-  Objects_Id                id,
-  const Scheduler_Control **scheduler_p
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_id(
+  Objects_Id id
 )
 {
-  uint32_t index = _Scheduler_Get_index_by_id( id );
-  const Scheduler_Control *scheduler = &_Scheduler_Table[ index ];
+  uint32_t index;
 
-  *scheduler_p = scheduler;
+  index = _Scheduler_Get_index_by_id( id );
 
-  return index < _Scheduler_Count
-    && _Scheduler_Get_processor_count( scheduler ) > 0;
+  if ( index >= _Scheduler_Count ) {
+    return NULL;
+  }
+
+  return &_Scheduler_Table[ index ];
 }
 
 RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index(
@@ -1205,8 +1206,13 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
   Priority_Control         priority
 )
 {
-  Scheduler_Node *new_scheduler_node;
-  Scheduler_Node *old_scheduler_node;
+  Scheduler_Node          *new_scheduler_node;
+  Scheduler_Node          *old_scheduler_node;
+#if defined(RTEMS_SMP)
+  ISR_lock_Context         lock_context;
+  const Scheduler_Control *old_scheduler;
+
+#endif
 
   if ( the_thread->Wait.queue != NULL ) {
     return STATUS_RESOURCE_IN_USE;
@@ -1229,9 +1235,32 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
 
 #if defined(RTEMS_SMP)
   if ( !_Chain_Has_only_one_node( &the_thread->Scheduler.Wait_nodes ) ) {
+    _Priority_Plain_insert(
+      &old_scheduler_node->Wait.Priority,
+      &the_thread->Real_priority,
+      the_thread->Real_priority.priority
+    );
     return STATUS_RESOURCE_IN_USE;
   }
 
+  old_scheduler = _Thread_Scheduler_get_home( the_thread );
+
+  _Scheduler_Acquire_critical( new_scheduler, &lock_context );
+
+  if ( _Scheduler_Get_processor_count( new_scheduler ) == 0 ) {
+    _Scheduler_Release_critical( new_scheduler, &lock_context );
+    _Priority_Plain_insert(
+      &old_scheduler_node->Wait.Priority,
+      &the_thread->Real_priority,
+      the_thread->Real_priority.priority
+    );
+    return STATUS_UNSATISFIED;
+  }
+
+  the_thread->Scheduler.home = new_scheduler;
+
+  _Scheduler_Release_critical( new_scheduler, &lock_context );
+
   _Thread_Scheduler_process_requests( the_thread );
   new_scheduler_node = _Thread_Scheduler_get_node_by_index(
     the_thread,
@@ -1249,47 +1278,40 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
   );
 
 #if defined(RTEMS_SMP)
-  {
-    const Scheduler_Control *old_scheduler;
-
-    old_scheduler = _Thread_Scheduler_get_home( the_thread );
-
-    if ( old_scheduler != new_scheduler ) {
-      States_Control current_state;
-
-      current_state = the_thread->current_state;
+  if ( old_scheduler != new_scheduler ) {
+    States_Control current_state;
 
-      if ( _States_Is_ready( current_state ) ) {
-        _Scheduler_Block( the_thread );
-      }
+    current_state = the_thread->current_state;
 
-      _Assert( old_scheduler_node->sticky_level == 0 );
-      _Assert( new_scheduler_node->sticky_level == 0 );
+    if ( _States_Is_ready( current_state ) ) {
+      _Scheduler_Block( the_thread );
+    }
 
-      _Chain_Extract_unprotected( &old_scheduler_node->Thread.Wait_node );
-      _Assert( _Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
-      _Chain_Initialize_one(
-        &the_thread->Scheduler.Wait_nodes,
-        &new_scheduler_node->Thread.Wait_node
-      );
-      _Chain_Extract_unprotected(
-        &old_scheduler_node->Thread.Scheduler_node.Chain
-      );
-      _Assert( _Chain_Is_empty( &the_thread->Scheduler.Scheduler_nodes ) );
-      _Chain_Initialize_one(
-        &the_thread->Scheduler.Scheduler_nodes,
-        &new_scheduler_node->Thread.Scheduler_node.Chain
-      );
+    _Assert( old_scheduler_node->sticky_level == 0 );
+    _Assert( new_scheduler_node->sticky_level == 0 );
 
-      the_thread->Scheduler.home = new_scheduler;
-      _Scheduler_Node_set_priority( new_scheduler_node, priority, false );
+    _Chain_Extract_unprotected( &old_scheduler_node->Thread.Wait_node );
+    _Assert( _Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
+    _Chain_Initialize_one(
+      &the_thread->Scheduler.Wait_nodes,
+      &new_scheduler_node->Thread.Wait_node
+    );
+    _Chain_Extract_unprotected(
+      &old_scheduler_node->Thread.Scheduler_node.Chain
+    );
+    _Assert( _Chain_Is_empty( &the_thread->Scheduler.Scheduler_nodes ) );
+    _Chain_Initialize_one(
+      &the_thread->Scheduler.Scheduler_nodes,
+      &new_scheduler_node->Thread.Scheduler_node.Chain
+    );
 
-      if ( _States_Is_ready( current_state ) ) {
-        _Scheduler_Unblock( the_thread );
-      }
+    _Scheduler_Node_set_priority( new_scheduler_node, priority, false );
 
-      return STATUS_SUCCESSFUL;
+    if ( _States_Is_ready( current_state ) ) {
+      _Scheduler_Unblock( the_thread );
     }
+
+    return STATUS_SUCCESSFUL;
   }
 #endif
 
diff --git a/testsuites/smptests/smpscheduler02/init.c b/testsuites/smptests/smpscheduler02/init.c
index 7708576..1492d4c 100644
--- a/testsuites/smptests/smpscheduler02/init.c
+++ b/testsuites/smptests/smpscheduler02/init.c
@@ -108,7 +108,7 @@ static void test(void)
   }
 
   sc = rtems_scheduler_ident(SCHED_C, &scheduler_c_id);
-  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_semaphore_create(
     rtems_build_name('C', 'M', 'T', 'X'),
@@ -182,13 +182,16 @@ static void test(void)
   rtems_test_assert(sched_get_priority_min(SCHED_RR) == 1);
   rtems_test_assert(sched_get_priority_max(SCHED_RR) == 254);
 
+  sc = rtems_task_set_scheduler(task_id, scheduler_c_id, 1);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  sc = rtems_task_set_scheduler(task_id, scheduler_c_id + 1, 1);
+  rtems_test_assert(sc == RTEMS_INVALID_ID);
+
   if (cpu_count > 1) {
     sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    sc = rtems_task_set_scheduler(task_id, scheduler_b_id + 1, 1);
-    rtems_test_assert(sc == RTEMS_INVALID_ID);
-
     sc = rtems_task_get_scheduler(task_id, &scheduler_id);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     rtems_test_assert(scheduler_id == scheduler_b_id);
-- 
1.8.4.5




More information about the devel mailing list