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.
This commit is contained in:
Sebastian Huber
2016-11-09 15:27:29 +01:00
parent 16b14cfdf8
commit 2612a0bf5b
8 changed files with 87 additions and 64 deletions
-2
View File
@@ -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,
+2 -1
View File
@@ -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;
}
+2 -6
View File
@@ -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 {
+2 -1
View File
@@ -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;
}
+2 -1
View File
@@ -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;
}
+2 -1
View File
@@ -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;
}
@@ -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;
if ( old_scheduler != new_scheduler ) {
States_Control current_state;
old_scheduler = _Thread_Scheduler_get_home( the_thread );
current_state = the_thread->current_state;
if ( old_scheduler != new_scheduler ) {
States_Control current_state;
current_state = the_thread->current_state;
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Block( the_thread );
}
_Assert( old_scheduler_node->sticky_level == 0 );
_Assert( new_scheduler_node->sticky_level == 0 );
_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
);
the_thread->Scheduler.home = new_scheduler;
_Scheduler_Node_set_priority( new_scheduler_node, priority, false );
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Unblock( the_thread );
}
return STATUS_SUCCESSFUL;
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Block( the_thread );
}
_Assert( old_scheduler_node->sticky_level == 0 );
_Assert( new_scheduler_node->sticky_level == 0 );
_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
);
_Scheduler_Node_set_priority( new_scheduler_node, priority, false );
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Unblock( the_thread );
}
return STATUS_SUCCESSFUL;
}
#endif
+7 -4
View File
@@ -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);