diff options
Diffstat (limited to 'cpukit/score/src')
-rw-r--r-- | cpukit/score/src/percpu.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/schedulerdefaulttick.c | 14 | ||||
-rw-r--r-- | cpukit/score/src/schedulersetaffinity.c | 31 | ||||
-rw-r--r-- | cpukit/score/src/smp.c | 79 | ||||
-rw-r--r-- | cpukit/score/src/threadcreateidle.c | 6 | ||||
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 4 | ||||
-rw-r--r-- | cpukit/score/src/threadstart.c | 8 |
7 files changed, 104 insertions, 41 deletions
diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c index cb9a470990..c396ace6c9 100644 --- a/cpukit/score/src/percpu.c +++ b/cpukit/score/src/percpu.c @@ -22,7 +22,6 @@ #include <rtems/score/assert.h> #include <rtems/score/smpimpl.h> #include <rtems/config.h> -#include <rtems/fatal.h> #if defined(RTEMS_SMP) @@ -154,7 +153,7 @@ void _Per_CPU_State_change( next_state == PER_CPU_STATE_SHUTDOWN && new_state != PER_CPU_STATE_SHUTDOWN ) { - rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN ); + _SMP_Fatal( SMP_FATAL_SHUTDOWN ); } } diff --git a/cpukit/score/src/schedulerdefaulttick.c b/cpukit/score/src/schedulerdefaulttick.c index 6e7ed376e3..98cd05e1c0 100644 --- a/cpukit/score/src/schedulerdefaulttick.c +++ b/cpukit/score/src/schedulerdefaulttick.c @@ -24,7 +24,7 @@ #include <rtems/score/smp.h> #include <rtems/config.h> -static void _Scheduler_default_Tick_for_executing( +void _Scheduler_default_Tick( const Scheduler_Control *scheduler, Thread_Control *executing ) @@ -83,15 +83,3 @@ static void _Scheduler_default_Tick_for_executing( #endif } } - -void _Scheduler_default_Tick( const Scheduler_Control *scheduler ) -{ - uint32_t processor_count = _SMP_Get_processor_count(); - uint32_t processor; - - for ( processor = 0 ; processor < processor_count ; ++processor ) { - const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( processor ); - - _Scheduler_default_Tick_for_executing( scheduler, per_cpu->executing ); - } -} diff --git a/cpukit/score/src/schedulersetaffinity.c b/cpukit/score/src/schedulersetaffinity.c index 2416a195c5..a20888b617 100644 --- a/cpukit/score/src/schedulersetaffinity.c +++ b/cpukit/score/src/schedulersetaffinity.c @@ -21,7 +21,6 @@ #if defined(__RTEMS_HAVE_SYS_CPUSET_H__) bool _Scheduler_Set_affinity( - const Scheduler_Control *scheduler, Thread_Control *the_thread, size_t cpusetsize, const cpu_set_t *cpuset @@ -31,15 +30,31 @@ bool _Scheduler_Set_affinity( if ( _CPU_set_Is_large_enough( cpusetsize ) ) { #if defined(RTEMS_SMP) - ok = ( *scheduler->Operations.set_affinity )( - scheduler, - the_thread, - cpusetsize, - cpuset - ); + uint32_t cpu_count = _SMP_Get_processor_count(); + uint32_t cpu_index; + + ok = false; + + for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { + if ( CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset ) ) { + const Scheduler_Control *scheduler_of_cpu = + _Scheduler_Get_by_CPU_index( cpu_index ); + + if ( scheduler_of_cpu != NULL ) { + ok = ( *scheduler_of_cpu->Operations.set_affinity )( + scheduler_of_cpu, + the_thread, + cpusetsize, + cpuset + ); + } + + break; + } + } #else ok = _Scheduler_default_Set_affinity_body( - scheduler, + _Scheduler_Get( the_thread ), the_thread, cpusetsize, cpuset diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c index 08677d83c7..6df72070ec 100644 --- a/cpukit/score/src/smp.c +++ b/cpukit/score/src/smp.c @@ -20,14 +20,68 @@ #include <rtems/score/smpimpl.h> #include <rtems/score/assert.h> +#include <rtems/score/schedulerimpl.h> #include <rtems/score/threaddispatch.h> #include <rtems/score/threadimpl.h> #include <rtems/config.h> +static void _SMP_Check_scheduler_configuration( void ) +{ + size_t n = _Scheduler_Count; + size_t i; + + for ( i = 0 ; i < n ; ++i ) { + const Scheduler_Control *scheduler = &_Scheduler_Table[ i ]; + + if ( scheduler->context->processor_count == 0 ) { + _SMP_Fatal( SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS ); + } + } +} + +static void _SMP_Start_processors( uint32_t cpu_count ) +{ + uint32_t cpu_self = _SMP_Get_current_processor(); + uint32_t cpu_index; + + + for ( cpu_index = 0 ; cpu_index < cpu_count; ++cpu_index ) { + const Scheduler_Assignment *assignment = + _Scheduler_Get_assignment( cpu_index ); + Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu_index ); + bool started; + + if ( cpu_index != cpu_self ) { + if ( _Scheduler_Should_start_processor( assignment ) ) { + started = _CPU_SMP_Start_processor( cpu_index ); + + if ( !started && _Scheduler_Is_mandatory_processor( assignment ) ) { + _SMP_Fatal( SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED ); + } + } else { + started = false; + } + } else { + started = true; + + if ( !_Scheduler_Should_start_processor( assignment ) ) { + _SMP_Fatal( SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER ); + } + } + + per_cpu->started = started; + + if ( started ) { + ++assignment->scheduler->context->processor_count; + } + } + + _SMP_Check_scheduler_configuration(); +} + void _SMP_Handler_initialize( void ) { uint32_t cpu_max = rtems_configuration_get_maximum_processors(); - uint32_t cpu_self; uint32_t cpu_count; uint32_t cpu_index; @@ -45,22 +99,17 @@ void _SMP_Handler_initialize( void ) cpu_count = cpu_count < cpu_max ? cpu_count : cpu_max; _SMP_Processor_count = cpu_count; - cpu_self = _SMP_Get_current_processor(); + for ( cpu_index = cpu_count ; cpu_index < cpu_max; ++cpu_index ) { + const Scheduler_Assignment *assignment = + _Scheduler_Get_assignment( cpu_index ); - for ( cpu_index = 0 ; cpu_index < cpu_count; ++cpu_index ) { - if ( cpu_index != cpu_self ) { - bool ok = _CPU_SMP_Start_processor( cpu_index ); - - if ( !ok ) { - _Terminate( - RTEMS_FATAL_SOURCE_SMP, - false, - SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED - ); - } + if ( _Scheduler_Is_mandatory_processor( assignment ) ) { + _SMP_Fatal( SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT ); } } + _SMP_Start_processors( cpu_count ); + _CPU_SMP_Finalize_initialization( cpu_count ); } @@ -83,6 +132,10 @@ void _SMP_Start_multitasking_on_secondary_processor( void ) { Per_CPU_Control *self_cpu = _Per_CPU_Get(); + if ( !_Per_CPU_Is_processor_started( self_cpu ) ) { + _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR ); + } + _Per_CPU_State_change( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING ); _Thread_Start_multitasking(); diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c index e044b92905..2a242658a5 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -19,6 +19,7 @@ #endif #include <rtems/score/threadimpl.h> +#include <rtems/score/schedulerimpl.h> #include <rtems/score/stackimpl.h> #include <rtems/config.h> @@ -39,6 +40,7 @@ static void _Thread_Create_idle_for_cpu( Per_CPU_Control *per_cpu ) _Thread_Initialize( &_Thread_Internal_information, idle, + _Scheduler_Get_by_CPU( per_cpu ), NULL, /* allocate the stack */ _Stack_Ensure_minimum( rtems_configuration_get_idle_task_stack_size() ), CPU_IDLE_TASK_IS_FP, @@ -75,6 +77,8 @@ void _Thread_Create_idle( void ) for ( processor = 0 ; processor < processor_count ; ++processor ) { Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( processor ); - _Thread_Create_idle_for_cpu( per_cpu ); + if ( _Per_CPU_Is_processor_started( per_cpu ) ) { + _Thread_Create_idle_for_cpu( per_cpu ); + } } } diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 153c1d0b13..f8e0e7d440 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -31,6 +31,7 @@ bool _Thread_Initialize( Objects_Information *information, Thread_Control *the_thread, + const Scheduler_Control *scheduler, void *stack_area, size_t stack_size, bool is_fp, @@ -50,7 +51,6 @@ bool _Thread_Initialize( bool extension_status; size_t i; bool scheduler_allocated = false; - const Scheduler_Control *scheduler; /* * Do not use _TLS_Size here since this will lead GCC to assume that this @@ -188,6 +188,7 @@ bool _Thread_Initialize( the_thread->is_scheduled = false; the_thread->is_in_the_air = false; the_thread->is_executing = false; + the_thread->scheduler = scheduler; #endif /* Initialize the CPU for the non-SMP schedulers */ @@ -199,7 +200,6 @@ bool _Thread_Initialize( the_thread->real_priority = priority; the_thread->Start.initial_priority = priority; - scheduler = _Scheduler_Get( _Thread_Get_executing() ); scheduler_allocated = _Scheduler_Allocate( scheduler, the_thread ); if ( !scheduler_allocated ) { goto failed; diff --git a/cpukit/score/src/threadstart.c b/cpukit/score/src/threadstart.c index b65a2c3380..dda9495a35 100644 --- a/cpukit/score/src/threadstart.c +++ b/cpukit/score/src/threadstart.c @@ -46,8 +46,12 @@ bool _Thread_Start( if ( cpu == NULL ) { _Thread_Ready( the_thread ); } else { - the_thread->current_state = STATES_READY; - _Scheduler_Start_idle( _Scheduler_Get( the_thread ), the_thread, cpu ); + const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu ); + + if ( scheduler != NULL ) { + the_thread->current_state = STATES_READY; + _Scheduler_Start_idle( scheduler, the_thread, cpu ); + } } _User_extensions_Thread_start( the_thread ); |