diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-08-07 15:35:47 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-08-20 10:17:35 +0200 |
commit | 99b35052ae1437dd17477152a6e04fa2e7e89c26 (patch) | |
tree | 8fbf2647fcecce562353bf8da53c6126cb457b58 | |
parent | smp: Generalize Simple SMP scheduler (diff) | |
download | rtems-99b35052ae1437dd17477152a6e04fa2e7e89c26.tar.bz2 |
smp: Add Deterministic Priority SMP Scheduler
-rw-r--r-- | cpukit/sapi/include/confdefs.h | 24 | ||||
-rw-r--r-- | cpukit/score/Makefile.am | 2 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerpriorityimpl.h | 17 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerprioritysmp.h | 94 | ||||
-rw-r--r-- | cpukit/score/preinstall.am | 4 | ||||
-rw-r--r-- | cpukit/score/src/schedulerprioritysmp.c | 212 | ||||
-rw-r--r-- | cpukit/score/src/schedulerpriorityupdate.c | 10 | ||||
-rw-r--r-- | doc/user/conf.t | 40 | ||||
-rw-r--r-- | testsuites/smptests/smpmigration01/smpmigration01.scn | 24 |
9 files changed, 402 insertions, 25 deletions
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 31d28acec1..dc4fb5e415 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -606,6 +606,7 @@ const rtems_libio_helper rtems_fs_init_helper = * scheduling policy to use. The supported configurations are: * CONFIGURE_SCHEDULER_USER - user provided scheduler * CONFIGURE_SCHEDULER_PRIORITY - Deterministic Priority Scheduler + * CONFIGURE_SCHEDULER_PRIORITY_SMP - Deterministic Priority SMP Scheduler * CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler * CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler * CONFIGURE_SCHEDULER_EDF - EDF Scheduler @@ -629,12 +630,13 @@ const rtems_libio_helper rtems_fs_init_helper = /* If no scheduler is specified, the priority scheduler is default. */ #if !defined(CONFIGURE_SCHEDULER_USER) && \ !defined(CONFIGURE_SCHEDULER_PRIORITY) && \ + !defined(CONFIGURE_SCHEDULER_PRIORITY_SMP) && \ !defined(CONFIGURE_SCHEDULER_SIMPLE) && \ !defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \ !defined(CONFIGURE_SCHEDULER_EDF) && \ !defined(CONFIGURE_SCHEDULER_CBS) #if defined(RTEMS_SMP) && defined(CONFIGURE_SMP_APPLICATION) - #define CONFIGURE_SCHEDULER_SIMPLE_SMP + #define CONFIGURE_SCHEDULER_PRIORITY_SMP #else #define CONFIGURE_SCHEDULER_PRIORITY #endif @@ -659,6 +661,26 @@ const rtems_libio_helper rtems_fs_init_helper = #endif /* + * If the Deterministic Priority SMP Scheduler is selected, then configure for + * it. + */ +#if defined(CONFIGURE_SCHEDULER_PRIORITY_SMP) + #include <rtems/score/schedulerprioritysmp.h> + #define CONFIGURE_SCHEDULER_ENTRY_POINTS SCHEDULER_PRIORITY_SMP_ENTRY_POINTS + + /** + * This defines the memory used by the priority scheduler. + */ + #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ + _Configure_From_workspace( \ + sizeof(Scheduler_SMP_Control) + \ + ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \ + ) + #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \ + _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) ) +#endif + +/* * If the Simple Priority Scheduler is selected, then configure for it. */ #if defined(CONFIGURE_SCHEDULER_SIMPLE) diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index c5af9c7380..c9d2d477d3 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -53,6 +53,7 @@ include_rtems_score_HEADERS += include/rtems/score/scheduleredf.h include_rtems_score_HEADERS += include/rtems/score/scheduleredfimpl.h include_rtems_score_HEADERS += include/rtems/score/schedulerpriority.h include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityimpl.h +include_rtems_score_HEADERS += include/rtems/score/schedulerprioritysmp.h include_rtems_score_HEADERS += include/rtems/score/schedulersimple.h include_rtems_score_HEADERS += include/rtems/score/schedulersimpleimpl.h include_rtems_score_HEADERS += include/rtems/score/schedulersmp.h @@ -119,6 +120,7 @@ libscore_a_SOURCES += src/mpci.c src/objectmp.c src/threadmp.c endif if HAS_SMP +libscore_a_SOURCES += src/schedulerprioritysmp.c libscore_a_SOURCES += src/schedulersimplesmp.c libscore_a_SOURCES += src/schedulersmpstartidle.c libscore_a_SOURCES += src/smp.c diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h index 9f45f21fcd..1c851505d4 100644 --- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h +++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h @@ -186,6 +186,23 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body( _Scheduler_Update_heir( heir, force_dispatch ); } +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body( + Thread_Control *thread, + Chain_Control *ready_queues +) +{ + Scheduler_priority_Per_thread *sched_info_of_thread = + _Scheduler_priority_Get_scheduler_info( thread ); + + sched_info_of_thread->ready_chain = + &ready_queues[ thread->current_priority ]; + + _Priority_bit_map_Initialize_information( + &sched_info_of_thread->Priority_map, + thread->current_priority + ); +} + /** * @brief Priority comparison. * diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h new file mode 100644 index 0000000000..f19f1de3fa --- /dev/null +++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h @@ -0,0 +1,94 @@ +/** + * @file + * + * @ingroup ScoreSchedulerPrioritySMP + * + * @brief Deterministic Priority SMP Scheduler API + */ + +/* + * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H +#define _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H + +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/schedulersmp.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup ScoreSchedulerPrioritySMP Deterministic Priority SMP Scheduler + * + * @ingroup ScoreScheduler + * + * This is an implementation of the global fixed priority scheduler (G-FP). It + * uses one ready chain per priority to ensure constant time insert operations. + * The scheduled chain uses linear insert operations and has at most processor + * count entries. Since the processor and priority count are constants all + * scheduler operations complete in a bounded execution time. + * + * The thread preempt mode will be ignored. + * + * @{ + */ + +/** + * @brief Entry points for the Simple SMP Scheduler. + */ +#define SCHEDULER_PRIORITY_SMP_ENTRY_POINTS \ + { \ + _Scheduler_priority_SMP_Initialize, \ + _Scheduler_priority_SMP_Schedule, \ + _Scheduler_priority_SMP_Yield, \ + _Scheduler_priority_SMP_Block, \ + _Scheduler_priority_SMP_Enqueue_fifo, \ + _Scheduler_priority_Allocate, \ + _Scheduler_priority_Free, \ + _Scheduler_priority_SMP_Update, \ + _Scheduler_priority_SMP_Enqueue_fifo, \ + _Scheduler_priority_SMP_Enqueue_lifo, \ + _Scheduler_priority_SMP_Extract, \ + _Scheduler_priority_Priority_compare, \ + _Scheduler_default_Release_job, \ + _Scheduler_default_Tick, \ + _Scheduler_SMP_Start_idle \ + } + +void _Scheduler_priority_SMP_Initialize( void ); + +void _Scheduler_priority_SMP_Schedule( Thread_Control *thread ); + +void _Scheduler_priority_SMP_Block( Thread_Control *thread ); + +void _Scheduler_priority_SMP_Update( Thread_Control *thread ); + +void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread ); + +void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread ); + +void _Scheduler_priority_SMP_Extract( Thread_Control *thread ); + +void _Scheduler_priority_SMP_Yield( Thread_Control *thread ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H */ diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index 4e645f4b48..79a18b5dd1 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -195,6 +195,10 @@ $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityimpl.h: include/rtems/score/sche $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityimpl.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityimpl.h +$(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmp.h: include/rtems/score/schedulerprioritysmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmp.h + $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h: include/rtems/score/schedulersimple.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c new file mode 100644 index 0000000000..fed94b11e2 --- /dev/null +++ b/cpukit/score/src/schedulerprioritysmp.c @@ -0,0 +1,212 @@ +/** + * @file + * + * @brief Deterministic Priority SMP Scheduler Implementation + * + * @ingroup ScoreSchedulerSMP + */ + +/* + * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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/schedulerprioritysmp.h> +#include <rtems/score/schedulerpriorityimpl.h> +#include <rtems/score/schedulersmpimpl.h> +#include <rtems/score/wkspace.h> + +void _Scheduler_priority_SMP_Initialize( void ) +{ + Scheduler_SMP_Control *self = _Workspace_Allocate_or_fatal_error( + sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control ) + ); + + _Chain_Initialize_empty( &self->scheduled ); + _Scheduler_priority_Ready_queue_initialize( &self->ready[ 0 ] ); + + _Scheduler.information = self; +} + +void _Scheduler_priority_SMP_Update( Thread_Control *thread ) +{ + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + + _Scheduler_priority_Update_body( thread, &self->ready[ 0 ] ); +} + +static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready( + Scheduler_SMP_Control *self +) +{ + Thread_Control *highest_ready = NULL; + + if ( !_Priority_bit_map_Is_empty() ) { + highest_ready = _Scheduler_priority_Ready_queue_first( &self->ready[ 0 ] ); + } + + return highest_ready; +} + +static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready( + Scheduler_SMP_Control *self, + Thread_Control *scheduled_to_ready +) +{ + _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node ); + _Scheduler_priority_Ready_queue_enqueue_first( scheduled_to_ready ); +} + +static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled( + Scheduler_SMP_Control *self, + Thread_Control *ready_to_scheduled +) +{ + _Scheduler_priority_Ready_queue_extract( ready_to_scheduled ); + _Scheduler_simple_Insert_priority_fifo( + &self->scheduled, + ready_to_scheduled + ); +} + +static void _Scheduler_priority_SMP_Insert_ready_lifo( + Scheduler_SMP_Control *self, + Thread_Control *thread +) +{ + _Scheduler_priority_Ready_queue_enqueue( thread ); +} + +static void _Scheduler_priority_SMP_Insert_ready_fifo( + Scheduler_SMP_Control *self, + Thread_Control *thread +) +{ + _Scheduler_priority_Ready_queue_enqueue_first( thread ); +} + +static void _Scheduler_priority_SMP_Do_extract( + Scheduler_SMP_Control *self, + Thread_Control *thread +) +{ + bool is_scheduled = thread->is_scheduled; + + ( void ) self; + + thread->is_in_the_air = is_scheduled; + thread->is_scheduled = false; + + if ( is_scheduled ) { + _Chain_Extract_unprotected( &thread->Object.Node ); + } else { + _Scheduler_priority_Ready_queue_extract( thread ); + } +} + +void _Scheduler_priority_SMP_Block( Thread_Control *thread ) +{ + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + + _Scheduler_SMP_Block( + self, + thread, + _Scheduler_priority_SMP_Do_extract, + _Scheduler_priority_SMP_Get_highest_ready, + _Scheduler_priority_SMP_Move_from_ready_to_scheduled + ); +} + +static void _Scheduler_priority_SMP_Enqueue_ordered( + Scheduler_SMP_Control *self, + Thread_Control *thread, + Chain_Node_order order, + Scheduler_SMP_Insert insert_ready, + Scheduler_SMP_Insert insert_scheduled +) +{ + _Scheduler_SMP_Enqueue_ordered( + self, + thread, + order, + _Scheduler_priority_SMP_Get_highest_ready, + insert_ready, + insert_scheduled, + _Scheduler_priority_SMP_Move_from_ready_to_scheduled, + _Scheduler_priority_SMP_Move_from_scheduled_to_ready + ); +} + +void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread ) +{ + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + + _Scheduler_priority_SMP_Enqueue_ordered( + self, + thread, + _Scheduler_simple_Insert_priority_lifo_order, + _Scheduler_priority_SMP_Insert_ready_lifo, + _Scheduler_SMP_Insert_scheduled_lifo + ); +} + +void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread ) +{ + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + + _Scheduler_priority_SMP_Enqueue_ordered( + self, + thread, + _Scheduler_simple_Insert_priority_fifo_order, + _Scheduler_priority_SMP_Insert_ready_fifo, + _Scheduler_SMP_Insert_scheduled_fifo + ); +} + +void _Scheduler_priority_SMP_Extract( Thread_Control *thread ) +{ + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + + _Scheduler_SMP_Extract( + self, + thread, + _Scheduler_priority_SMP_Do_extract + ); +} + +void _Scheduler_priority_SMP_Yield( Thread_Control *thread ) +{ + ISR_Level level; + + _ISR_Disable( level ); + + _Scheduler_priority_SMP_Extract( thread ); + _Scheduler_priority_SMP_Enqueue_fifo( thread ); + + _ISR_Enable( level ); +} + +void _Scheduler_priority_SMP_Schedule( Thread_Control *thread ) +{ + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + + _Scheduler_SMP_Schedule( + self, + thread, + _Scheduler_priority_SMP_Get_highest_ready, + _Scheduler_priority_SMP_Move_from_ready_to_scheduled + ); +} diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c index de3f02615c..062b36913c 100644 --- a/cpukit/score/src/schedulerpriorityupdate.c +++ b/cpukit/score/src/schedulerpriorityupdate.c @@ -25,15 +25,7 @@ void _Scheduler_priority_Update( Thread_Control *the_thread ) { - Scheduler_priority_Per_thread *sched_info_of_thread = - _Scheduler_priority_Get_scheduler_info( the_thread ); Chain_Control *ready_queues = _Scheduler_priority_Get_ready_queues(); - sched_info_of_thread->ready_chain = - &ready_queues[ the_thread->current_priority ]; - - _Priority_bit_map_Initialize_information( - &sched_info_of_thread->Priority_map, - the_thread->current_priority - ); + _Scheduler_priority_Update_body( the_thread, ready_queues ); } diff --git a/doc/user/conf.t b/doc/user/conf.t index 66f31ad384..94d523f659 100644 --- a/doc/user/conf.t +++ b/doc/user/conf.t @@ -3536,6 +3536,43 @@ This scheduler may be explicitly selected by defining None. @c +@c === CONFIGURE_SCHEDULER_PRIORITY_SMP === +@c +@subsection Use Deterministic Priority SMP Scheduler + +@findex CONFIGURE_SCHEDULER_PRIORITY_SMP + +@table @b +@item CONSTANT: +@code{CONFIGURE_SCHEDULER_PRIORITY_SMP} + +@item DATA TYPE: +Boolean feature macro. + +@item RANGE: +Defined or undefined. + +@item DEFAULT VALUE: +This is not defined by default. + +@end table + +@subheading DESCRIPTION: +The Deterministic Priority SMP Scheduler is derived from the Deterministic +Priority Scheduler but is capable of scheduling threads across multiple +processors. + +In a configuration with SMP enabled at configure time, it may be +explicitly selected by defining @code{CONFIGURE_SCHEDULER_PRIORITY_SMP}. + +@subheading NOTES: +This scheduler is only available when RTEMS is configured with SMP +support enabled. + +This scheduler is currently the default in SMP configurations and is +only selected when @code{CONFIGURE_SMP_APPLICATION} is defined. + +@c @c === CONFIGURE_SCHEDULER_SIMPLE_SMP === @c @subsection Use Simple SMP Priority Scheduler @@ -3578,9 +3615,6 @@ explicitly selected by defining @code{CONFIGURE_SCHEDULER_SIMPLE_SMP}. This scheduler is only available when RTEMS is configured with SMP support enabled. -This scheduler is currently the default in SMP configurations and is -only selected when @code{CONFIGURE_SMP_APPLICATION} is defined. - @c @c === Configuring a User Scheduler === @c diff --git a/testsuites/smptests/smpmigration01/smpmigration01.scn b/testsuites/smptests/smpmigration01/smpmigration01.scn index c5a21069bd..b2b56ffcb8 100644 --- a/testsuites/smptests/smpmigration01/smpmigration01.scn +++ b/testsuites/smptests/smpmigration01/smpmigration01.scn @@ -1,17 +1,17 @@ *** TEST SMPMIGRATION 1 *** runner 0 - cpu 0 tokens 530399 - cpu 0 cycles 10077490 - cpu 1 tokens 530399 - cpu 1 cycles 10071429 + cpu 0 tokens 453284 + cpu 0 cycles 14955317 + cpu 1 tokens 453283 + cpu 1 cycles 14978390 runner 1 - cpu 0 tokens 530399 - cpu 0 cycles 5978212 - cpu 1 tokens 530399 - cpu 1 cycles 7951897 + cpu 0 tokens 453283 + cpu 0 cycles 21302793 + cpu 1 tokens 453283 + cpu 1 cycles 21318817 runner 2 - cpu 0 tokens 530399 - cpu 0 cycles 10070929 - cpu 1 tokens 530398 - cpu 1 cycles 10106437 + cpu 0 tokens 453283 + cpu 0 cycles 19973312 + cpu 1 tokens 453283 + cpu 1 cycles 21315227 *** END OF TEST SMPMIGRATION 1 *** |