summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-02 06:36:13 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-09 15:27:29 +0100
commit2612a0bf5b9f0105315d62cbacfa9d29a5caa4b5 (patch)
treef27e6300271c5a5d47f6ef41a6d5c4780b715fc7
parentscore: Fix _MRSP_Initialize() (diff)
downloadrtems-2612a0bf5b9f0105315d62cbacfa9d29a5caa4b5.tar.bz2
score: Simplify _Scheduler_Get_by_id()
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.
-rw-r--r--cpukit/rtems/include/rtems/rtems/tasks.h2
-rw-r--r--cpukit/rtems/src/schedulergetprocessorset.c3
-rw-r--r--cpukit/rtems/src/schedulerident.c8
-rw-r--r--cpukit/rtems/src/semsetpriority.c3
-rw-r--r--cpukit/rtems/src/taskgetpriority.c3
-rw-r--r--cpukit/rtems/src/tasksetscheduler.c3
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h110
-rw-r--r--testsuites/smptests/smpscheduler02/init.c11
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 180e50eed7..3a94e348ed 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 016c3681cf..275c563090 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 ee18af009e..5bde8de8bc 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 37dea5da80..123f6277af 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 b6800e2133..8fb8ad3b4f 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 3a860a197b..f3b7143d7b 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 0abc1a074c..8d804bb0e4 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 7708576ae9..1492d4c881 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);