summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-07 15:35:47 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-20 10:17:35 +0200
commit99b35052ae1437dd17477152a6e04fa2e7e89c26 (patch)
tree8fbf2647fcecce562353bf8da53c6126cb457b58
parentsmp: Generalize Simple SMP scheduler (diff)
downloadrtems-99b35052ae1437dd17477152a6e04fa2e7e89c26.tar.bz2
smp: Add Deterministic Priority SMP Scheduler
-rw-r--r--cpukit/sapi/include/confdefs.h24
-rw-r--r--cpukit/score/Makefile.am2
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityimpl.h17
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h94
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/schedulerprioritysmp.c212
-rw-r--r--cpukit/score/src/schedulerpriorityupdate.c10
-rw-r--r--doc/user/conf.t40
-rw-r--r--testsuites/smptests/smpmigration01/smpmigration01.scn24
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 ***