[PATCH 12/12] smp: Add Priority SMP Scheduler
Sebastian Huber
sebastian.huber at embedded-brains.de
Tue Aug 13 13:42:57 UTC 2013
---
cpukit/sapi/include/confdefs.h | 23 ++-
cpukit/score/Makefile.am | 2 +
.../include/rtems/score/schedulerpriorityimpl.h | 17 ++
.../include/rtems/score/schedulerprioritysmp.h | 88 ++++++++
cpukit/score/preinstall.am | 4 +
cpukit/score/src/schedulerprioritysmp.c | 217 ++++++++++++++++++++
cpukit/score/src/schedulerpriorityupdate.c | 10 +-
.../smptests/smpmigration01/smpmigration01.scn | 24 +-
8 files changed, 363 insertions(+), 22 deletions(-)
create mode 100644 cpukit/score/include/rtems/score/schedulerprioritysmp.h
create mode 100644 cpukit/score/src/schedulerprioritysmp.c
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 0a98645..45275a8 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 - 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,25 @@ const rtems_libio_helper rtems_fs_init_helper =
#endif
/*
+ * If the 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 c5af9c7..c9d2d47 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 9f45f21..1c85150 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 0000000..012ad1f
--- /dev/null
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -0,0 +1,88 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerPrioritySMP
+ *
+ * @brief Priority SMP Scheduler API
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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 Priority SMP Scheduler
+ *
+ * @ingroup ScoreScheduler
+ *
+ * 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 4e645f4..79a18b5 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 0000000..ae0a1ca
--- /dev/null
+++ b/cpukit/score/src/schedulerprioritysmp.c
@@ -0,0 +1,217 @@
+/**
+ * @file
+ *
+ * @brief Priority SMP Scheduler Implementation
+ *
+ * @ingroup ScoreSchedulerSMP
+ */
+
+/*
+ * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at 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>
+
+static Scheduler_SMP_Control *_Scheduler_priority_SMP_Instance( void )
+{
+ return _Scheduler.information;
+}
+
+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_priority_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 de3f026..062b369 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/testsuites/smptests/smpmigration01/smpmigration01.scn b/testsuites/smptests/smpmigration01/smpmigration01.scn
index c5a2106..b2b56ff 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 ***
--
1.7.7
More information about the devel
mailing list