summaryrefslogtreecommitdiffstats
path: root/cpukit/score
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 /cpukit/score
parentsmp: Generalize Simple SMP scheduler (diff)
downloadrtems-99b35052ae1437dd17477152a6e04fa2e7e89c26.tar.bz2
smp: Add Deterministic Priority SMP Scheduler
Diffstat (limited to 'cpukit/score')
-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
6 files changed, 330 insertions, 9 deletions
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 );
}