summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/schedulerprioritysmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src/schedulerprioritysmp.c')
-rw-r--r--cpukit/score/src/schedulerprioritysmp.c212
1 files changed, 212 insertions, 0 deletions
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
+ );
+}