summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src')
-rw-r--r--cpukit/score/src/percpu.c3
-rw-r--r--cpukit/score/src/schedulerdefaulttick.c14
-rw-r--r--cpukit/score/src/schedulersetaffinity.c31
-rw-r--r--cpukit/score/src/smp.c79
-rw-r--r--cpukit/score/src/threadcreateidle.c6
-rw-r--r--cpukit/score/src/threadinitialize.c4
-rw-r--r--cpukit/score/src/threadstart.c8
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 );