summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/sapi/include/confdefs.h2
-rw-r--r--cpukit/score/Makefile.am6
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h133
-rw-r--r--cpukit/score/include/rtems/score/thread.h28
-rw-r--r--cpukit/score/src/schedulersimplesmp.c182
-rw-r--r--cpukit/score/src/schedulersimplesmpblock.c31
-rw-r--r--cpukit/score/src/schedulersimplesmpschedule.c271
-rw-r--r--cpukit/score/src/schedulersimplesmpunblock.c34
-rw-r--r--cpukit/score/src/smp.c3
-rw-r--r--cpukit/score/src/threaddispatch.c5
-rw-r--r--cpukit/score/src/threadinitialize.c6
-rw-r--r--cpukit/score/src/threadstartmultitasking.c5
12 files changed, 294 insertions, 412 deletions
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 2bd1444c18..bf9f5e8d6f 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -683,7 +683,7 @@ const rtems_libio_helper rtems_fs_init_helper =
* NOTE: This is the same as the Simple Scheduler
*/
#define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
- _Configure_From_workspace( sizeof(Chain_Control) ) \
+ _Configure_From_workspace( sizeof( Scheduler_simple_smp_Control ) ) \
)
#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
#endif
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index f072cf3cbc..3f6e686ad9 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -134,9 +134,9 @@ libscore_a_SOURCES += src/mpci.c src/objectmp.c src/threadmp.c
endif
if HAS_SMP
-libscore_a_SOURCES += src/isrsmp.c src/smp.c \
- src/schedulersimplesmpblock.c src/schedulersimplesmpschedule.c \
- src/schedulersimplesmpunblock.c
+libscore_a_SOURCES += src/isrsmp.c
+libscore_a_SOURCES += src/schedulersimplesmp.c
+libscore_a_SOURCES += src/smp.c
endif
## CORE_APIMUTEX_C_FILES
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index baac7b221d..1c7e125479 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -1,19 +1,16 @@
/**
- * @file rtems/score/schedulersimplesmp.h
+ * @file
*
- * @brief Manipulation of Threads on a Simple-Priority-Based Ready Queue
+ * @brief Simple SMP Scheduler API
*
- * This include file contains all the constants and structures associated
- * with the manipulation of threads on a simple-priority-based ready queue.
- * This implementation is SMP-aware and schedules across multiple cores.
- *
- * The implementation relies heavily on the Simple Scheduler and
- * only replaces a few routines from that scheduler.
+ * @ingroup ScoreSchedulerSMP
*/
/*
* Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2013 embedded brains GmbH.
+ *
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
@@ -22,20 +19,6 @@
#ifndef _RTEMS_SCORE_SCHEDULERSIMPLE_SMP_H
#define _RTEMS_SCORE_SCHEDULERSIMPLE_SMP_H
-/**
- * @defgroup ScoreSchedulerSMP Simple SMP Scheduler
- *
- * @ingroup ScoreScheduler
- *
- * The Simple SMP Scheduler attempts to faithfully implement the
- * behaviour of the Deterministic Priority Scheduler while spreading
- * the threads across multiple cores. It takes into account thread
- * priority, preemption, and how long a thread has been executing
- * on a core as factors. From an implementation perspective, it
- * relies heavily on the Simple Priority Scheduler.
- */
-/**@{*/
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -45,68 +28,76 @@ extern "C" {
#include <rtems/score/schedulerpriority.h>
/**
- * Entry points for Scheduler Simple SMP
+ * @defgroup ScoreSchedulerSMP Simple SMP Scheduler
+ *
+ * @ingroup ScoreScheduler
+ *
+ * The Simple SMP Scheduler allocates a processor for the processor count
+ * highest priority ready threads. The thread priority and position in the
+ * ready chain are the only information to determine the scheduling decision.
+ * Threads with an allocated processor are in the scheduled chain. After
+ * initialization the scheduled chain has exactly processor count nodes. Each
+ * processor has exactly one allocated thread after initialization. All
+ * enqueue and extract operations may exchange threads with the scheduled
+ * chain. One thread will be added and another will be removed. The scheduled
+ * and ready chain is ordered according to the thread priority order. The
+ * chain insert operations are O(count of ready threads), thus this scheduler
+ * is unsuitable for most real-time applications.
+ *
+ * The thread preempt mode will be ignored.
+ *
+ * @{
+ */
+
+typedef struct {
+ Chain_Control ready;
+ Chain_Control scheduled;
+} Scheduler_simple_smp_Control;
+
+/**
+ * @brief Entry points for the Simple SMP Scheduler.
*/
#define SCHEDULER_SIMPLE_SMP_ENTRY_POINTS \
{ \
- _Scheduler_simple_Initialize, /* initialize entry point */ \
- _Scheduler_simple_smp_Schedule, /* schedule entry point */ \
- _Scheduler_simple_Yield, /* yield entry point */ \
- _Scheduler_simple_smp_Block, /* block entry point */ \
- _Scheduler_simple_smp_Unblock, /* unblock entry point */ \
- _Scheduler_simple_Allocate, /* allocate entry point */ \
- _Scheduler_simple_Free, /* free entry point */ \
- _Scheduler_simple_Update, /* update entry point */ \
- _Scheduler_simple_Enqueue, /* enqueue entry point */ \
- _Scheduler_simple_Enqueue_first, /* enqueue_first entry point */ \
- _Scheduler_simple_Extract, /* extract entry point */ \
- _Scheduler_priority_Priority_compare, /* compares two priorities */ \
- _Scheduler_priority_Release_job, /* new period of task */ \
- _Scheduler_default_Tick /* tick entry point */ \
+ _Scheduler_simple_smp_Initialize, \
+ _Scheduler_simple_smp_Schedule, \
+ _Scheduler_simple_smp_Yield, \
+ _Scheduler_simple_smp_Extract, \
+ _Scheduler_simple_smp_Enqueue_priority_fifo, \
+ _Scheduler_simple_Allocate, \
+ _Scheduler_simple_Free, \
+ _Scheduler_simple_Update, \
+ _Scheduler_simple_smp_Enqueue_priority_fifo, \
+ _Scheduler_simple_smp_Enqueue_priority_lifo, \
+ _Scheduler_simple_smp_Extract, \
+ _Scheduler_priority_Priority_compare, \
+ _Scheduler_priority_Release_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_simple_smp_Start_idle \
}
-/**
- * @brief Allocates ready SMP threads to individual cores in an SMP system.
- *
- * This routine allocates ready threads to individual cores in an SMP
- * system. If the allocation results in a new heir which requires
- * a dispatch, then the dispatch needed flag for that core is set.
- */
+void _Scheduler_simple_smp_Initialize( void );
+
+void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread );
+
+void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread );
+
+void _Scheduler_simple_smp_Extract( Thread_Control *thread );
+
+void _Scheduler_simple_smp_Yield( Thread_Control *thread );
+
void _Scheduler_simple_smp_Schedule( void );
-/**
- * @brief Remove SMP @a the_thread from the ready queue.
- *
- * This routine removes @a the_thread from the scheduling decision,
- * that is, removes it from the ready queue. It performs
- * any necessary scheduling operations including the selection of
- * a new heir thread.
- *
- * @param[in] the_thread is the thread that is to be blocked
- */
-void _Scheduler_simple_smp_Block(
- Thread_Control *the_thread
+void _Scheduler_simple_smp_Start_idle(
+ Thread_Control *thread,
+ Per_CPU_Control *cpu
);
-/**
- * @brief Adds SMP @a the_thread to the ready queue and updates any
- * appropriate scheduling variables, for example the heir thread.
- *
- * This routine adds @a the_thread to the scheduling decision,
- * that is, adds it to the ready queue and updates any appropriate
- * scheduling variables, for example the heir thread.
- *
- * @param[in] the_thread is the thread that is to be unblocked
- */
-void _Scheduler_simple_smp_Unblock(
- Thread_Control *the_thread
-);
+/** @} */
#ifdef __cplusplus
}
#endif
-/**@}*/
-
#endif
/* end of include file */
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 60583a77c0..56b9b0cdf9 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -384,6 +384,30 @@ struct Thread_Control_struct {
#endif
/** This field is true if the thread is preemptible. */
bool is_preemptible;
+#if defined(RTEMS_SMP)
+ /**
+ * @brief This field is true if the thread is scheduled.
+ *
+ * A thread is scheduled if it is ready and the scheduler allocated a
+ * processor for it. A scheduled thread is assigned to exactly one
+ * processor. There are exactly processor count scheduled threads in the
+ * system.
+ */
+ bool is_scheduled;
+
+ /**
+ * @brief This field is true if the thread is executing.
+ *
+ * A thread is executing if it executes on a processor. An executing thread
+ * executes on exactly one processor. There are exactly processor count
+ * executing threads in the system. An executing thread may have a heir
+ * thread and thread dispatching is necessary. On SMP a thread dispatch on a
+ * remote processor needs help from an inter-processor interrupt, thus it
+ * will take some time to complete the state change. A lot of things can
+ * happen in the meantime.
+ */
+ bool is_executing;
+#endif
#if __RTEMS_ADA__
/** This field is the GNAT self context pointer. */
void *rtems_ada_self;
@@ -408,6 +432,10 @@ struct Thread_Control_struct {
/** This pointer holds per-thread data for the scheduler and ready queue. */
void *scheduler_info;
+#ifdef RTEMS_SMP
+ Per_CPU_Control *cpu;
+#endif
+
/** This field contains information about the starting state of
* this thread.
*/
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
new file mode 100644
index 0000000000..ec1b0e27f4
--- /dev/null
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -0,0 +1,182 @@
+/**
+ * @file
+ *
+ * @brief Simple SMP Scheduler Implementation
+ *
+ * @ingroup ScoreSchedulerSMP
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/schedulersimplesmp.h>
+
+static Scheduler_simple_smp_Control *_Scheduler_simple_smp_Instance( void )
+{
+ return _Scheduler.information;
+}
+
+void _Scheduler_simple_smp_Initialize( void )
+{
+ Scheduler_simple_smp_Control *self =
+ _Workspace_Allocate_or_fatal_error( sizeof( *self ) );
+
+ _Chain_Initialize_empty( &self->ready );
+ _Chain_Initialize_empty( &self->scheduled );
+
+ _Scheduler.information = self;
+}
+
+static void _Scheduler_simple_smp_Allocate_processor(
+ Thread_Control *scheduled,
+ Thread_Control *victim
+)
+{
+ Per_CPU_Control *cpu_of_scheduled = scheduled->cpu;
+ Per_CPU_Control *cpu_of_victim = victim->cpu;
+ Thread_Control *heir;
+
+ scheduled->is_scheduled = true;
+ victim->is_scheduled = false;
+
+ if ( scheduled->is_executing ) {
+ heir = cpu_of_scheduled->heir;
+ cpu_of_scheduled->heir = scheduled;
+ } else {
+ heir = scheduled;
+ }
+
+ if ( heir != victim ) {
+ heir->cpu = cpu_of_victim;
+ cpu_of_victim->heir = heir;
+ cpu_of_victim->dispatch_necessary = true;
+ }
+}
+
+static void _Scheduler_simple_smp_Move_from_scheduled_to_ready(
+ Chain_Control *ready_chain,
+ Thread_Control *scheduled_to_ready
+)
+{
+ _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
+ _Scheduler_simple_Insert_priority_lifo( ready_chain, scheduled_to_ready );
+}
+
+static void _Scheduler_simple_smp_Move_from_ready_to_scheduled(
+ Chain_Control *scheduled_chain,
+ Thread_Control *ready_to_scheduled
+)
+{
+ _Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
+ _Scheduler_simple_Insert_priority_fifo( scheduled_chain, ready_to_scheduled );
+}
+
+static void _Scheduler_simple_smp_Insert(
+ Chain_Control *chain,
+ Thread_Control *thread,
+ Chain_Node_order order
+)
+{
+ _Chain_Insert_ordered_unprotected( chain, &thread->Object.Node, order );
+}
+
+static void _Scheduler_simple_smp_Enqueue_ordered(
+ Thread_Control *thread,
+ Chain_Node_order order
+)
+{
+ Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();
+
+ /*
+ * The scheduled chain has exactly processor count nodes after
+ * initialization, thus the lowest priority scheduled thread exists.
+ */
+ Thread_Control *lowest_scheduled =
+ (Thread_Control *) _Chain_Last( &self->scheduled );
+
+ if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
+ _Scheduler_simple_smp_Allocate_processor( thread, lowest_scheduled );
+
+ _Scheduler_simple_smp_Insert( &self->scheduled, thread, order );
+
+ _Scheduler_simple_smp_Move_from_scheduled_to_ready(
+ &self->ready,
+ lowest_scheduled
+ );
+ } else {
+ _Scheduler_simple_smp_Insert( &self->ready, thread, order );
+ }
+}
+
+void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread )
+{
+ _Scheduler_simple_smp_Enqueue_ordered(
+ thread,
+ _Scheduler_simple_Insert_priority_lifo_order
+ );
+}
+
+void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread )
+{
+ _Scheduler_simple_smp_Enqueue_ordered(
+ thread,
+ _Scheduler_simple_Insert_priority_fifo_order
+ );
+}
+
+void _Scheduler_simple_smp_Extract( Thread_Control *thread )
+{
+ Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();
+
+ _Chain_Extract_unprotected( &thread->Object.Node );
+
+ if ( thread->is_scheduled ) {
+ Thread_Control *highest_ready =
+ (Thread_Control *) _Chain_First( &self->ready );
+
+ _Scheduler_simple_smp_Allocate_processor( highest_ready, thread );
+
+ _Scheduler_simple_smp_Move_from_ready_to_scheduled(
+ &self->scheduled,
+ highest_ready
+ );
+ }
+}
+
+void _Scheduler_simple_smp_Yield( Thread_Control *thread )
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+
+ _Scheduler_simple_smp_Extract( thread );
+ _Scheduler_simple_smp_Enqueue_priority_fifo( thread );
+
+ _ISR_Enable( level );
+}
+
+void _Scheduler_simple_smp_Schedule( void )
+{
+ /* Nothing to do */
+}
+
+void _Scheduler_simple_smp_Start_idle(
+ Thread_Control *thread,
+ Per_CPU_Control *cpu
+)
+{
+ Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();
+
+ thread->is_scheduled = true;
+ thread->cpu = cpu;
+ _Chain_Append_unprotected( &self->scheduled, &thread->Object.Node );
+}
diff --git a/cpukit/score/src/schedulersimplesmpblock.c b/cpukit/score/src/schedulersimplesmpblock.c
deleted file mode 100644
index 9d6d979684..0000000000
--- a/cpukit/score/src/schedulersimplesmpblock.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @file
- *
- * @brief Scheduler Simple Block
- * @ingroup ScoreScheduler
- */
-
-/*
- * COPYRIGHT (c) 2011.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/schedulersimplesmp.h>
-
-void _Scheduler_simple_smp_Block(
- Thread_Control *the_thread
-)
-{
- _Scheduler_simple_Extract( the_thread );
-
- _Scheduler_simple_smp_Schedule();
-}
diff --git a/cpukit/score/src/schedulersimplesmpschedule.c b/cpukit/score/src/schedulersimplesmpschedule.c
deleted file mode 100644
index 471f710ede..0000000000
--- a/cpukit/score/src/schedulersimplesmpschedule.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file
- *
- * Scheduler Simple SMP Handler / Schedule
- */
-
-/*
- * COPYRIGHT (c) 2011- 2012.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/smp.h>
-#include <rtems/score/schedulersimplesmp.h>
-
-#include <stdio.h>
-
-/*
- * The following is very useful on the scheduler simulator when debugging
- * this algorithm. You are not likely to be able to print like this when
- * running on a real system.
- *
- * NOTE: This is NOT using RTEMS_DEBUG because this is not consistency
- * checking and is VERY VERY noisy. It is just for debugging
- * the algorithm.
- */
-#if 0
-#define D(format,...) printk( format, __VA_ARGS__)
-#else
-#define D(format,...)
-#endif
-
-/* Declaration to avoid warnings */
-bool _Scheduler_simple_smp_Assign(
- Thread_Control *consider
-);
-
-/**
- * @brief Assign Heir Thread to CPU
- *
- * This method attempts to find a core for the thread under consideration
- * (@a consider) to become heir of. The placement takes into account
- * priority, preemptibility, and length of time on core.
- *
- * Combined with the loop in _Scheduler_simple_smp_Schedule, it attempts
- * to faithfully implement the behaviour of the Deterministic Priority
- * Scheduler while spreading the threads across multiple cores.
- *
- * @param[in] consider is the thread under consideration. This means
- * that the method is looking for the best core to place it
- * as heir.
- *
- * @return This method returns true if it was able to make @a consider
- * the heir on a core and false otherwise. When this returns
- * false, there is no point in attempting to place an heir of
- * of lower priority.
- */
-bool _Scheduler_simple_smp_Assign(
- Thread_Control *consider
-)
-{
- bool found; /* have we found a cpu to place it on? */
- uint32_t found_cpu; /* CPU to place this thread */
- bool blocked; /* CPU has blocked thread? */
- Thread_Control *pheir; /* heir on found cpu to potentially replace */
- Thread_Control *h;
- Thread_Control *e;
- uint32_t cpu;
-
- /*
- * Initialize various variables to indicate we have not found
- * a potential core for the thread under consideration.
- */
- found = false;
- blocked = false;
- found_cpu = 0;
- pheir = NULL;
-
- for ( cpu=0 ; cpu < _SMP_Processor_count ; cpu++ ) {
- D( "SCHED CPU=%d consider=0x%08x ASSIGN\n", cpu, consider->Object.id );
-
- /*
- * If the thread under consideration is already executing or
- * heir, then we don't have a better option for it.
- */
- e = _Per_CPU_Information[cpu].executing;
- if ( e == consider ) {
- D( "SCHED CPU=%d Executing=0x%08x considering=0x%08x ASSIGNED\n",
- cpu, e->Object.id, consider->Object.id );
- return true;
- }
-
- if ( !_States_Is_ready( e->current_state ) ) {
- pheir = e;
- found_cpu = cpu;
- found = true;
- blocked = true;
- D( "SCHED CPU=%d PHeir=0x%08x considering=0x%08x BLOCKED\n",
- cpu, e->Object.id, consider->Object.id );
- continue;
- }
-
- h = _Per_CPU_Information[cpu].heir;
- if ( h == consider ) {
- D( "SCHED CPU=%d Heir=0x%08x considering=0x%08x ASSIGNED\n",
- cpu, h->Object.id, consider->Object.id );
- return true;
- }
-
- if ( blocked )
- continue;
-
- /*
- * If we haven't found a potential CPU to locate the thread
- * under consideration on, we need to consider if this is a
- * more important threads first (e.g. priority <).
- *
- * But when a thread changes its priority and ends up at the end of
- * the priority group for the new heir, we also need to schedule
- * a new heir. This is the "=" part of the check.
- */
- if ( !found ) {
- if ( consider->current_priority <= h->current_priority ) {
- pheir = h;
- found_cpu = cpu;
- found = true;
- D( "SCHED CPU=%d PHeir=0x%08x considering=0x%08x MAYBE #1\n",
- cpu, h->Object.id, consider->Object.id );
- }
-
- continue;
- }
-
- /*
- * ASSERTION: (found == true)
- *
- * Past this point, we have found a potential heir and are considering
- * whether the thread is better placed on another core. It is desirable
- * to preempt the lowest priority thread using time on core and
- * preemptibility as additional factors.
- */
-
- /*
- * If we have found a potential CPU on which to make the
- * thread under consideration the heir, then we need to
- * check if the current CPU is a more appropriate place
- * for this thread to be placed.
- *
- * Check 1: heir of potential CPU is more important
- * then heir of current CPU. We want to
- * replace the least important thread possible.
- */
- if ( h->current_priority > pheir->current_priority ) {
- pheir = h;
- found_cpu = cpu;
- D( "SCHED CPU=%d PHeir=0x%08x considering=0x%08x MAYBE #2\n",
- cpu, h->Object.id, consider->Object.id );
- continue;
- }
-
- /*
- * If the current heir is more important than the potential
- * heir, then we should not consider it further in scheduling.
- */
- if ( h->current_priority < pheir->current_priority )
- continue;
-
- /*
- * ASSERTION: (h->current_priority == pheir->current_priority).
- *
- * Past this point, this means we are considering the length of time
- * the thread has spent on the time on the CPU core and if it is
- * preemptible.
- */
-
- /*
- * If heir of potential CPU and of the current CPU are of the SAME
- * priority, then which has been running longer?
- *
- * Which CPU has had its executing thread longer?
- */
- if ( _Timestamp_Less_than(
- &_Per_CPU_Information[cpu].time_of_last_context_switch,
- &_Per_CPU_Information[found_cpu].time_of_last_context_switch
- ) ) {
- pheir = h;
- found_cpu = cpu;
- D( "SCHED CPU=%d PHeir=0x%08x considering=0x%08x LONGER\n",
- cpu, h->Object.id, consider->Object.id );
- continue;
- }
-
- /*
- * If we are looking at a core with a non-preemptible thread
- * for potential placement, then favor a core with a preeemtible
- * thread of the same priority. This should help avoid priority
- * inversions and let threads run earlier.
- */
- if ( !pheir->is_preemptible && h->is_preemptible ) {
- D( "SCHED CPU=%d PHeir==0x%08x is NOT PREEMPTIBLE\n",
- cpu, pheir->Object.id );
- pheir = h;
- found_cpu = cpu;
- D( "SCHED CPU=%d PHeir=0x%08x considering=0x%08x PREEMPTIBLE\n",
- cpu, h->Object.id, consider->Object.id );
- continue;
-
- }
- }
-
- /*
- * If we found a cpu to make this thread heir of, then we
- * need to consider whether we need a dispatch on that CPU.
- */
- if ( found ) {
- e = _Per_CPU_Information[found_cpu].executing;
- D( "SCHED CPU=%d executing=0x%08x considering=0x%08x FOUND\n",
- found_cpu, e->Object.id, consider->Object.id );
- _Per_CPU_Information[found_cpu].heir = consider;
- if ( !_States_Is_ready( e->current_state ) ) {
- D( "SCHED CPU=%d executing not ready dispatch needed\n", found_cpu);
- _Per_CPU_Information[found_cpu].dispatch_necessary = true;
- } else if ( consider->current_priority < e->current_priority ) {
- if ( e->is_preemptible || consider->current_priority == 0 ) {
- D( "SCHED CPU=%d preempting\n", found_cpu);
- _Per_CPU_Information[found_cpu].dispatch_necessary = true;
- }
- }
- }
-
- /*
- * Return true to indicate we changed an heir. This indicates
- * scheduling needs to examine more threads.
- */
- return found;
-}
-
-/*
- * Reschedule threads -- select heirs for all cores
- */
-void _Scheduler_simple_smp_Schedule(void)
-{
- Chain_Control *c;
- Chain_Node *n;
- Thread_Control *t;
- uint32_t cpu;
-
- c = (Chain_Control *)_Scheduler.information;
- cpu = 0;
-
- /*
- * Iterate over the first N (where N is the number of CPU cores) threads
- * on the ready chain. Attempt to assign each as heir on a core. When
- * unable to assign a thread as a new heir, then stop.
- */
- for (n = _Chain_First(c); !_Chain_Is_tail(c, n); n = _Chain_Next(n)) {
- t = (Thread_Control *)n;
- if ( !_Scheduler_simple_smp_Assign( t ) )
- break;
- if ( ++cpu >= _SMP_Processor_count )
- break;
- }
-}
diff --git a/cpukit/score/src/schedulersimplesmpunblock.c b/cpukit/score/src/schedulersimplesmpunblock.c
deleted file mode 100644
index ef61d483e8..0000000000
--- a/cpukit/score/src/schedulersimplesmpunblock.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * @file
- *
- * @brief Scheduler Simple SMP Unblock Method
- * @ingroup ScoreScheduler
- */
-
-/*
- * COPYRIGHT (c) 2011.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/schedulersimplesmp.h>
-
-void _Scheduler_simple_smp_Unblock(
- Thread_Control *the_thread
-)
-{
- _Scheduler_simple_Ready_queue_enqueue(the_thread);
-
- /*
- * Evaluate all CPUs and pick heirs
- */
- _Scheduler_simple_smp_Schedule();
-}
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index 10acbe25de..3081062f87 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -51,7 +51,10 @@ void rtems_smp_secondary_cpu_initialize( void )
* THIS core.
*/
heir = per_cpu->heir;
+ heir->is_executing = true;
+ per_cpu->executing->is_executing = false;
per_cpu->executing = heir;
+ per_cpu->dispatch_necessary = false;
/*
* Threads begin execution in the _Thread_Handler() function. This function
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index 4856f8e67b..4cd449d55b 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -94,7 +94,10 @@ void _Thread_Dispatch( void )
_ISR_Disable( level );
while ( _Thread_Dispatch_necessary == true ) {
heir = _Thread_Heir;
- #ifndef RTEMS_SMP
+ #if defined(RTEMS_SMP)
+ executing->is_executing = false;
+ heir->is_executing = true;
+ #else
_Thread_Dispatch_set_disable_level( 1 );
#endif
_Thread_Dispatch_necessary = false;
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index fb22578c3d..4c40ae87b8 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -180,6 +180,12 @@ bool _Thread_Initialize(
the_thread->Start.isr_level = isr_level;
+#if defined(RTEMS_SMP)
+ the_thread->is_scheduled = false;
+ the_thread->is_executing = false;
+ the_thread->cpu = NULL;
+#endif
+
the_thread->current_state = STATES_DORMANT;
the_thread->Wait.queue = NULL;
the_thread->resource_count = 0;
diff --git a/cpukit/score/src/threadstartmultitasking.c b/cpukit/score/src/threadstartmultitasking.c
index 32a594bd3b..16d1328148 100644
--- a/cpukit/score/src/threadstartmultitasking.c
+++ b/cpukit/score/src/threadstartmultitasking.c
@@ -43,6 +43,11 @@ void _Thread_Start_multitasking( void )
_Thread_Dispatch_necessary = false;
+ #if defined(RTEMS_SMP)
+ _Thread_Executing->is_executing = false;
+ _Thread_Heir->is_executing = true;
+ #endif
+
_Thread_Executing = _Thread_Heir;
/*