diff options
-rw-r--r-- | cpukit/sapi/include/confdefs.h | 2 | ||||
-rw-r--r-- | cpukit/score/Makefile.am | 6 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulersimplesmp.h | 133 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/thread.h | 28 | ||||
-rw-r--r-- | cpukit/score/src/schedulersimplesmp.c | 182 | ||||
-rw-r--r-- | cpukit/score/src/schedulersimplesmpblock.c | 31 | ||||
-rw-r--r-- | cpukit/score/src/schedulersimplesmpschedule.c | 271 | ||||
-rw-r--r-- | cpukit/score/src/schedulersimplesmpunblock.c | 34 | ||||
-rw-r--r-- | cpukit/score/src/smp.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/threaddispatch.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 6 | ||||
-rw-r--r-- | cpukit/score/src/threadstartmultitasking.c | 5 |
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; /* |