diff options
Diffstat (limited to 'cpukit/score')
-rw-r--r-- | cpukit/score/include/rtems/score/percpu.h | 19 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/scheduler.h | 64 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerimpl.h | 176 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/smpimpl.h | 9 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/thread.h | 14 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 1 | ||||
-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 |
13 files changed, 342 insertions, 86 deletions
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h index 9a6b1698fb..e491ffa002 100644 --- a/cpukit/score/include/rtems/score/percpu.h +++ b/cpukit/score/include/rtems/score/percpu.h @@ -316,6 +316,12 @@ typedef struct { * @see _Per_CPU_State_change(). */ Per_CPU_State state; + + /** + * @brief Indicates if the processor has been successfully started via + * _CPU_SMP_Start_processor(). + */ + bool started; #endif Per_CPU_Stats Stats; @@ -462,6 +468,19 @@ static inline uint32_t _Per_CPU_Get_index( const Per_CPU_Control *per_cpu ) return ( uint32_t ) ( per_cpu_envelope - &_Per_CPU_Information[ 0 ] ); } +static inline bool _Per_CPU_Is_processor_started( + const Per_CPU_Control *per_cpu +) +{ +#if defined( RTEMS_SMP ) + return per_cpu->started; +#else + (void) per_cpu; + + return true; +#endif +} + #if defined( RTEMS_SMP ) static inline void _Per_CPU_Send_interrupt( const Per_CPU_Control *per_cpu ) diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h index 3fd47c78a2..9002ef85d9 100644 --- a/cpukit/score/include/rtems/score/scheduler.h +++ b/cpukit/score/include/rtems/score/scheduler.h @@ -102,7 +102,7 @@ typedef struct { ); /** perform scheduler update actions required at each clock tick */ - void ( *tick )( const Scheduler_Control * ); + void ( *tick )( const Scheduler_Control *, Thread_Control * ); /** * @brief Starts the idle thread for a particular processor. @@ -149,7 +149,12 @@ typedef struct { * this structure at the begin of its context structure. */ typedef struct { - /* No fields yet */ +#if defined(RTEMS_SMP) + /** + * @brief Count of processors owned by this scheduler instance. + */ + uint32_t processor_count; +#endif } Scheduler_Context; /** @@ -198,6 +203,55 @@ extern const Scheduler_Control _Scheduler_Table[]; #define _Scheduler_Count ( (size_t) 1 ) #endif +#if defined(RTEMS_SMP) + /** + * @brief The scheduler assignment default attributes. + */ + #define SCHEDULER_ASSIGN_DEFAULT UINT32_C(0x0) + + /** + * @brief The presence of this processor is optional. + */ + #define SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL SCHEDULER_ASSIGN_DEFAULT + + /** + * @brief The presence of this processor is mandatory. + */ + #define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY UINT32_C(0x1) + + /** + * @brief Scheduler assignment. + */ + typedef struct { + /** + * @brief The scheduler for this processor. + */ + const Scheduler_Control *scheduler; + + /** + * @brief The scheduler assignment attributes. + * + * Use @ref SCHEDULER_ASSIGN_DEFAULT to select default attributes. + * + * The presence of a processor can be + * - @ref SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL, or + * - @ref SCHEDULER_ASSIGN_PROCESSOR_MANDATORY. + */ + uint32_t attributes; + } Scheduler_Assignment; + + /** + * @brief The scheduler assignments. + * + * The length of this array must be equal to the maximum processors. + * + * Application provided via <rtems/confdefs.h>. + * + * @see _Scheduler_Table and rtems_configuration_get_maximum_processors(). + */ + extern const Scheduler_Assignment _Scheduler_Assignments[]; +#endif + /** * @brief Returns an arbitrary non-NULL value. * @@ -253,8 +307,12 @@ void _Scheduler_default_Release_job( * This routine is invoked as part of processing each clock tick. * * @param[in] scheduler The scheduler. + * @param[in] execution An executing thread. */ -void _Scheduler_default_Tick( const Scheduler_Control *scheduler ); +void _Scheduler_default_Tick( + const Scheduler_Control *scheduler, + Thread_Control *executing +); /** * @brief Starts an idle thread. diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 8b80db78c1..35054dfd3b 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -21,6 +21,7 @@ #include <rtems/score/scheduler.h> #include <rtems/score/cpusetimpl.h> +#include <rtems/score/smpimpl.h> #include <rtems/score/threadimpl.h> #ifdef __cplusplus @@ -41,6 +42,28 @@ extern "C" { */ void _Scheduler_Handler_initialization( void ); +RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_CPU_index( + uint32_t cpu_index +) +{ +#if defined(RTEMS_SMP) + return _Scheduler_Assignments[ cpu_index ].scheduler; +#else + (void) cpu_index; + + return &_Scheduler_Table[ 0 ]; +#endif +} + +RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_CPU( + const Per_CPU_Control *cpu +) +{ + uint32_t cpu_index = _Per_CPU_Get_index( cpu ); + + return _Scheduler_Get_by_CPU_index( cpu_index ); +} + /** * The preferred method to add a new scheduler is to define the jump table * entries and add a case to the _Scheduler_Initialize routine. @@ -234,11 +257,19 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_job( * scheduler which support standard RTEMS features, this includes * time-slicing management. */ -RTEMS_INLINE_ROUTINE void _Scheduler_Tick( - const Scheduler_Control *scheduler -) +RTEMS_INLINE_ROUTINE void _Scheduler_Tick( void ) { - ( *scheduler->Operations.tick )( scheduler ); + uint32_t cpu_count = _SMP_Get_processor_count(); + uint32_t cpu_index; + + for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { + const Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index ); + const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu ); + + if ( scheduler != NULL ) { + ( *scheduler->Operations.tick )( scheduler, cpu->executing ); + } + } } /** @@ -258,6 +289,47 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Start_idle( ( *scheduler->Operations.start_idle )( scheduler, the_thread, cpu ); } +#if defined(RTEMS_SMP) +RTEMS_INLINE_ROUTINE const Scheduler_Assignment *_Scheduler_Get_assignment( + uint32_t cpu_index +) +{ + return &_Scheduler_Assignments[ cpu_index ]; +} + +RTEMS_INLINE_ROUTINE bool _Scheduler_Is_mandatory_processor( + const Scheduler_Assignment *assignment +) +{ + return (assignment->attributes & SCHEDULER_ASSIGN_PROCESSOR_MANDATORY) != 0; +} + +RTEMS_INLINE_ROUTINE bool _Scheduler_Should_start_processor( + const Scheduler_Assignment *assignment +) +{ + return assignment->scheduler != NULL; +} +#endif /* defined(RTEMS_SMP) */ + +RTEMS_INLINE_ROUTINE bool _Scheduler_Has_processor_ownership( + const Scheduler_Control *scheduler, + uint32_t cpu_index +) +{ +#if defined(RTEMS_SMP) + const Scheduler_Assignment *assignment = + _Scheduler_Get_assignment( cpu_index ); + + return assignment->scheduler == scheduler; +#else + (void) scheduler; + (void) cpu_index; + + return true; +#endif +} + #if defined(__RTEMS_HAVE_SYS_CPUSET_H__) RTEMS_INLINE_ROUTINE void _Scheduler_Get_processor_set( @@ -269,12 +341,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Get_processor_set( uint32_t cpu_count = _SMP_Get_processor_count(); uint32_t cpu_index; - (void) scheduler; - CPU_ZERO_S( cpusetsize, cpuset ); for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { +#if defined(RTEMS_SMP) + if ( _Scheduler_Has_processor_ownership( scheduler, cpu_index ) ) { + CPU_SET_S( (int) cpu_index, cpusetsize, cpuset ); + } +#else + (void) scheduler; + CPU_SET_S( (int) cpu_index, cpusetsize, cpuset ); +#endif } } @@ -299,6 +377,44 @@ bool _Scheduler_Get_affinity( cpu_set_t *cpuset ); +RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get( + Thread_Control *the_thread +) +{ +#if defined(RTEMS_SMP) + return the_thread->scheduler; +#else + (void) the_thread; + + return &_Scheduler_Table[ 0 ]; +#endif +} + +RTEMS_INLINE_ROUTINE bool _Scheduler_Set( + const Scheduler_Control *scheduler, + Thread_Control *the_thread +) +{ + bool ok; + + if ( _States_Is_dormant( the_thread->current_state ) ) { +#if defined(RTEMS_SMP) + _Scheduler_Free( _Scheduler_Get( the_thread ), the_thread ); + the_thread->scheduler = scheduler; + _Scheduler_Allocate( scheduler, the_thread ); + _Scheduler_Update( scheduler, the_thread ); +#else + (void) scheduler; +#endif + + ok = true; + } else { + ok = false; + } + + return ok; +} + RTEMS_INLINE_ROUTINE bool _Scheduler_default_Set_affinity_body( const Scheduler_Control *scheduler, Thread_Control *the_thread, @@ -311,22 +427,35 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_default_Set_affinity_body( uint32_t cpu_index; bool ok = true; - (void) scheduler; - (void) the_thread; - for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) { +#if defined(RTEMS_SMP) + const Scheduler_Control *scheduler_of_cpu = + _Scheduler_Get_by_CPU_index( cpu_index ); + + ok = ok + && ( ( CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset ) + && scheduler == scheduler_of_cpu ) + || ( !CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset ) + && scheduler != scheduler_of_cpu ) ); +#else + (void) scheduler; + ok = ok && CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset ); +#endif } for ( ; cpu_index < cpu_max ; ++cpu_index ) { ok = ok && !CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset ); } + if ( ok ) { + ok = _Scheduler_Set( scheduler, the_thread ); + } + return ok; } bool _Scheduler_Set_affinity( - const Scheduler_Control *scheduler, Thread_Control *the_thread, size_t cpusetsize, const cpu_set_t *cpuset @@ -442,33 +571,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority_if_higher( } } -RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get( - Thread_Control *the_thread -) -{ - (void) the_thread; - - return &_Scheduler_Table[ 0 ]; -} - -RTEMS_INLINE_ROUTINE bool _Scheduler_Set( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - bool ok; - - (void) scheduler; - - if ( _States_Is_dormant( the_thread->current_state ) ) { - ok = true; - } else { - ok = false; - } - - return ok; -} - RTEMS_INLINE_ROUTINE Objects_Id _Scheduler_Build_id( uint32_t scheduler_index ) { return _Objects_Build_id( diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h index 3e808600d3..225da0fde4 100644 --- a/cpukit/score/include/rtems/score/smpimpl.h +++ b/cpukit/score/include/rtems/score/smpimpl.h @@ -49,9 +49,18 @@ extern "C" { typedef enum { SMP_FATAL_SHUTDOWN, SMP_FATAL_SHUTDOWN_EARLY, + SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER, + SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT, + SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR, + SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS, SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED } SMP_Fatal_code; +static inline void _SMP_Fatal( SMP_Fatal_code code ) +{ + _Terminate( RTEMS_FATAL_SOURCE_SMP, false, code ); +} + /** * @brief Initialize SMP Handler * diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 77e105bf28..5215d6a8ce 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -33,13 +33,12 @@ #include <rtems/score/threadq.h> #include <rtems/score/watchdog.h> -#ifdef RTEMS_SMP -#if __RTEMS_HAVE_SYS_CPUSET_H__ -#include <sys/cpuset.h> -#include <rtems/score/cpuset.h> -#endif +#if defined(RTEMS_SMP) + #include <rtems/score/cpuset.h> #endif +struct Scheduler_Control; + #ifdef __cplusplus extern "C" { #endif @@ -517,6 +516,11 @@ struct Thread_Control_struct { * _Thread_Kill_zombies(). */ volatile bool is_executing; + + /** + * @brief The scheduler of this thread. + */ + const struct Scheduler_Control *scheduler; #endif #if __RTEMS_ADA__ diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 41b90e3018..4efc85d8f1 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -141,6 +141,7 @@ void _Thread_Stack_Free( bool _Thread_Initialize( Objects_Information *information, Thread_Control *the_thread, + const struct Scheduler_Control *scheduler, void *stack_area, size_t stack_size, bool is_fp, 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 ); |