[rtems commit] score: Split SMP scheduler enqueue function

Sebastian Huber sebh at rtems.org
Thu May 15 11:10:48 UTC 2014


Module:    rtems
Branch:    master
Commit:    c0bff5e936c4b967fe490e1e11eda00c638a8f6a
Changeset: http://git.rtems.org/rtems/commit/?id=c0bff5e936c4b967fe490e1e11eda00c638a8f6a

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu May 15 10:31:22 2014 +0200

score: Split SMP scheduler enqueue function

Extract code from _Scheduler_SMP_Enqueue_ordered() and move it to the
new function _Scheduler_SMP_Enqueue_scheduled_ordered() to avoid
untestable execution paths.

Add and use function _Scheduler_SMP_Unblock().

---

 .../score/include/rtems/score/schedulersmpimpl.h   |  164 +++++++++++++-------
 cpukit/score/src/schedulerprioritysmp.c            |   71 +++++++--
 cpukit/score/src/schedulersimplesmp.c              |   71 +++++++--
 testsuites/smptests/Makefile.am                    |    1 +
 testsuites/smptests/configure.ac                   |    1 +
 testsuites/smptests/smpscheduler03/Makefile.am     |   19 +++
 testsuites/smptests/smpscheduler03/init.c          |  144 +++++++++++++++++
 .../smptests/smpscheduler03/smpscheduler03.doc     |   11 ++
 .../smptests/smpscheduler03/smpscheduler03.scn     |    2 +
 9 files changed, 398 insertions(+), 86 deletions(-)

diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index 3650e4c..9bc1a37 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -41,7 +41,8 @@ extern "C" {
  * - @ref SCHEDULER_SMP_NODE_READY.
  *
  * State transitions are triggered via basic operations
- * - _Scheduler_SMP_Enqueue_ordered(), and
+ * - _Scheduler_SMP_Enqueue_ordered(),
+ * - _Scheduler_SMP_Enqueue_scheduled_ordered(), and
  * - _Scheduler_SMP_Block().
  *
  * @dot
@@ -295,8 +296,7 @@ typedef void ( *Scheduler_SMP_Update )(
 
 typedef void ( *Scheduler_SMP_Enqueue )(
   Scheduler_Context *context,
-  Thread_Control *thread_to_enqueue,
-  bool has_processor_allocated
+  Thread_Control *thread_to_enqueue
 );
 
 static inline Scheduler_SMP_Context *_Scheduler_SMP_Get_self(
@@ -432,80 +432,102 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
 /**
  * @brief Enqueues a thread according to the specified order function.
  *
+ * The thread must not be in the scheduled state.
+ *
  * @param[in] context The scheduler instance context.
  * @param[in] thread The thread to enqueue.
- * @param[in] has_processor_allocated The thread has a processor allocated.
  * @param[in] order The order function.
- * @param[in] get_highest_ready Function to get the highest ready node.
  * @param[in] insert_ready Function to insert a node into the set of ready
  * nodes.
  * @param[in] insert_scheduled Function to insert a node into the set of
  * scheduled nodes.
- * @param[in] move_from_ready_to_scheduled Function to move a node from the set
- * of ready nodes to the set of scheduled nodes.
  * @param[in] move_from_scheduled_to_ready Function to move a node from the set
  * of scheduled nodes to the set of ready nodes.
  */
 static inline void _Scheduler_SMP_Enqueue_ordered(
   Scheduler_Context *context,
   Thread_Control *thread,
-  bool has_processor_allocated,
   Chain_Node_order order,
-  Scheduler_SMP_Get_highest_ready get_highest_ready,
   Scheduler_SMP_Insert insert_ready,
   Scheduler_SMP_Insert insert_scheduled,
-  Scheduler_SMP_Move move_from_ready_to_scheduled,
   Scheduler_SMP_Move move_from_scheduled_to_ready
 )
 {
   Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
+  Thread_Control *lowest_scheduled =
+    _Scheduler_SMP_Get_lowest_scheduled( self );
+
+  _Assert( lowest_scheduled != NULL);
+
+  /*
+   * NOTE: Do not exchange parameters to do the negation of the order check.
+   */
+  if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
+    Scheduler_SMP_Node *lowest_scheduled_node =
+      _Scheduler_SMP_Node_get( lowest_scheduled );
+
+    _Scheduler_SMP_Node_change_state(
+      lowest_scheduled_node,
+      SCHEDULER_SMP_NODE_READY
+    );
+    _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );
+    ( *insert_scheduled )( &self->Base, thread );
+    ( *move_from_scheduled_to_ready )( &self->Base, lowest_scheduled );
+  } else {
+    ( *insert_ready )( &self->Base, thread );
+  }
+}
+
+/**
+ * @brief Enqueues a scheduled thread according to the specified order
+ * function.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] thread The thread to enqueue.
+ * @param[in] order The order function.
+ * @param[in] get_highest_ready Function to get the highest ready node.
+ * @param[in] insert_ready Function to insert a node into the set of ready
+ * nodes.
+ * @param[in] insert_scheduled Function to insert a node into the set of
+ * scheduled nodes.
+ * @param[in] move_from_ready_to_scheduled Function to move a node from the set
+ * of ready nodes to the set of scheduled nodes.
+ */
+static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
+  Scheduler_Context *context,
+  Thread_Control *thread,
+  Chain_Node_order order,
+  Scheduler_SMP_Get_highest_ready get_highest_ready,
+  Scheduler_SMP_Insert insert_ready,
+  Scheduler_SMP_Insert insert_scheduled,
+  Scheduler_SMP_Move move_from_ready_to_scheduled
+)
+{
+  Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
   Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+  Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
 
-  if ( has_processor_allocated) {
-    Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
-
-    _Assert( highest_ready != NULL);
-
-    /*
-     * The thread has been extracted from the scheduled chain.  We have to
-     * place it now on the scheduled or ready chain.
-     *
-     * NOTE: Do not exchange parameters to do the negation of the order check.
-     */
-    if ( !( *order )( &thread->Object.Node, &highest_ready->Object.Node ) ) {
-      _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
-      _Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
-      ( *insert_ready )( &self->Base, thread );
-      ( *move_from_ready_to_scheduled )( &self->Base, highest_ready );
-    } else {
-      _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_SCHEDULED );
-      ( *insert_scheduled )( &self->Base, thread );
-    }
+  _Assert( highest_ready != NULL);
+
+  /*
+   * The thread has been extracted from the scheduled chain.  We have to place
+   * it now on the scheduled or ready set.
+   *
+   * NOTE: Do not exchange parameters to do the negation of the order check.
+   */
+  if ( !( *order )( &thread->Object.Node, &highest_ready->Object.Node ) ) {
+    _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
+    _Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
+    ( *insert_ready )( &self->Base, thread );
+    ( *move_from_ready_to_scheduled )( &self->Base, highest_ready );
   } else {
-    Thread_Control *lowest_scheduled =
-      _Scheduler_SMP_Get_lowest_scheduled( self );
-
-    _Assert( lowest_scheduled != NULL);
-
-    if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
-      Scheduler_SMP_Node *lowest_scheduled_node =
-        _Scheduler_SMP_Node_get( lowest_scheduled );
-
-      _Scheduler_SMP_Node_change_state(
-        lowest_scheduled_node,
-        SCHEDULER_SMP_NODE_READY
-      );
-      _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );
-      ( *insert_scheduled )( &self->Base, thread );
-      ( *move_from_scheduled_to_ready )( &self->Base, lowest_scheduled );
-    } else {
-      _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
-      ( *insert_ready )( &self->Base, thread );
-    }
+    ( *insert_scheduled )( &self->Base, thread );
   }
 }
 
-static inline void _Scheduler_SMP_Extract_from_scheduled( Thread_Control *thread )
+static inline void _Scheduler_SMP_Extract_from_scheduled(
+  Thread_Control *thread
+)
 {
   _Chain_Extract_unprotected( &thread->Object.Node );
 }
@@ -563,6 +585,19 @@ static inline void _Scheduler_SMP_Block(
   }
 }
 
+static inline void _Scheduler_SMP_Unblock(
+  Scheduler_Context *context,
+  Thread_Control *thread,
+  Scheduler_SMP_Enqueue enqueue_fifo
+)
+{
+  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+
+  _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
+
+  ( *enqueue_fifo )( context, thread );
+}
+
 static inline void _Scheduler_SMP_Change_priority(
   Scheduler_Context *context,
   Thread_Control *thread,
@@ -571,24 +606,33 @@ static inline void _Scheduler_SMP_Change_priority(
   Scheduler_SMP_Extract extract_from_ready,
   Scheduler_SMP_Update update,
   Scheduler_SMP_Enqueue enqueue_fifo,
-  Scheduler_SMP_Enqueue enqueue_lifo
+  Scheduler_SMP_Enqueue enqueue_lifo,
+  Scheduler_SMP_Enqueue enqueue_scheduled_fifo,
+  Scheduler_SMP_Enqueue enqueue_scheduled_lifo
 )
 {
   Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
-  bool has_processor_allocated = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
 
-  if ( has_processor_allocated ) {
+  if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
     _Scheduler_SMP_Extract_from_scheduled( thread );
+
+    ( *update )( context, &node->Base, new_priority );
+
+    if ( prepend_it ) {
+      ( *enqueue_scheduled_lifo )( context, thread );
+    } else {
+      ( *enqueue_scheduled_fifo )( context, thread );
+    }
   } else {
     ( *extract_from_ready )( context, thread );
-  }
 
-  ( *update )( context, &node->Base, new_priority );
+    ( *update )( context, &node->Base, new_priority );
 
-  if ( prepend_it ) {
-    ( *enqueue_lifo )( context, thread, has_processor_allocated );
-  } else {
-    ( *enqueue_fifo )( context, thread, has_processor_allocated );
+    if ( prepend_it ) {
+      ( *enqueue_lifo )( context, thread );
+    } else {
+      ( *enqueue_fifo )( context, thread );
+    }
   }
 }
 
diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
index 956b7cf..56bb0ac 100644
--- a/cpukit/score/src/schedulerprioritysmp.c
+++ b/cpukit/score/src/schedulerprioritysmp.c
@@ -228,7 +228,6 @@ void _Scheduler_priority_SMP_Block(
 static void _Scheduler_priority_SMP_Enqueue_ordered(
   Scheduler_Context *context,
   Thread_Control *thread,
-  bool has_processor_allocated,
   Chain_Node_order order,
   Scheduler_SMP_Insert insert_ready,
   Scheduler_SMP_Insert insert_scheduled
@@ -237,26 +236,21 @@ static void _Scheduler_priority_SMP_Enqueue_ordered(
   _Scheduler_SMP_Enqueue_ordered(
     context,
     thread,
-    has_processor_allocated,
     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
   );
 }
 
 static void _Scheduler_priority_SMP_Enqueue_lifo(
   Scheduler_Context *context,
-  Thread_Control *thread,
-  bool has_processor_allocated
+  Thread_Control *thread
 )
 {
   _Scheduler_priority_SMP_Enqueue_ordered(
     context,
     thread,
-    has_processor_allocated,
     _Scheduler_simple_Insert_priority_lifo_order,
     _Scheduler_priority_SMP_Insert_ready_lifo,
     _Scheduler_SMP_Insert_scheduled_lifo
@@ -265,14 +259,59 @@ static void _Scheduler_priority_SMP_Enqueue_lifo(
 
 static void _Scheduler_priority_SMP_Enqueue_fifo(
   Scheduler_Context *context,
-  Thread_Control *thread,
-  bool has_processor_allocated
+  Thread_Control *thread
 )
 {
   _Scheduler_priority_SMP_Enqueue_ordered(
     context,
     thread,
-    has_processor_allocated,
+    _Scheduler_simple_Insert_priority_fifo_order,
+    _Scheduler_priority_SMP_Insert_ready_fifo,
+    _Scheduler_SMP_Insert_scheduled_fifo
+  );
+}
+
+static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
+  Scheduler_Context *context,
+  Thread_Control *thread,
+  Chain_Node_order order,
+  Scheduler_SMP_Insert insert_ready,
+  Scheduler_SMP_Insert insert_scheduled
+)
+{
+  _Scheduler_SMP_Enqueue_scheduled_ordered(
+    context,
+    thread,
+    order,
+    _Scheduler_priority_SMP_Get_highest_ready,
+    insert_ready,
+    insert_scheduled,
+    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
+  );
+}
+
+static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo(
+  Scheduler_Context *context,
+  Thread_Control *thread
+)
+{
+  _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
+    context,
+    thread,
+    _Scheduler_simple_Insert_priority_lifo_order,
+    _Scheduler_priority_SMP_Insert_ready_lifo,
+    _Scheduler_SMP_Insert_scheduled_lifo
+  );
+}
+
+static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo(
+  Scheduler_Context *context,
+  Thread_Control *thread
+)
+{
+  _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
+    context,
+    thread,
     _Scheduler_simple_Insert_priority_fifo_order,
     _Scheduler_priority_SMP_Insert_ready_fifo,
     _Scheduler_SMP_Insert_scheduled_fifo
@@ -286,7 +325,11 @@ void _Scheduler_priority_SMP_Unblock(
 {
   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
 
-  _Scheduler_priority_SMP_Enqueue_fifo( context, thread, false );
+  _Scheduler_SMP_Unblock(
+    context,
+    thread,
+    _Scheduler_priority_SMP_Enqueue_fifo
+  );
 }
 
 void _Scheduler_priority_SMP_Change_priority(
@@ -306,7 +349,9 @@ void _Scheduler_priority_SMP_Change_priority(
     _Scheduler_priority_SMP_Extract_from_ready,
     _Scheduler_priority_SMP_Do_update,
     _Scheduler_priority_SMP_Enqueue_fifo,
-    _Scheduler_priority_SMP_Enqueue_lifo
+    _Scheduler_priority_SMP_Enqueue_lifo,
+    _Scheduler_priority_SMP_Enqueue_scheduled_fifo,
+    _Scheduler_priority_SMP_Enqueue_scheduled_lifo
   );
 }
 
@@ -321,7 +366,7 @@ void _Scheduler_priority_SMP_Yield(
   _ISR_Disable( level );
 
   _Scheduler_SMP_Extract_from_scheduled( thread );
-  _Scheduler_priority_SMP_Enqueue_fifo( context, thread, true );
+  _Scheduler_priority_SMP_Enqueue_scheduled_fifo( context, thread );
 
   _ISR_Enable( level );
 }
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
index a743cf9..d5d3908 100644
--- a/cpukit/score/src/schedulersimplesmp.c
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -164,7 +164,6 @@ void _Scheduler_simple_SMP_Block(
 static void _Scheduler_simple_SMP_Enqueue_ordered(
   Scheduler_Context *context,
   Thread_Control *thread,
-  bool has_processor_allocated,
   Chain_Node_order order,
   Scheduler_SMP_Insert insert_ready,
   Scheduler_SMP_Insert insert_scheduled
@@ -173,26 +172,21 @@ static void _Scheduler_simple_SMP_Enqueue_ordered(
   _Scheduler_SMP_Enqueue_ordered(
     context,
     thread,
-    has_processor_allocated,
     order,
-    _Scheduler_simple_SMP_Get_highest_ready,
     insert_ready,
     insert_scheduled,
-    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
     _Scheduler_simple_SMP_Move_from_scheduled_to_ready
   );
 }
 
 static void _Scheduler_simple_SMP_Enqueue_lifo(
   Scheduler_Context *context,
-  Thread_Control *thread,
-  bool has_processor_allocated
+  Thread_Control *thread
 )
 {
   _Scheduler_simple_SMP_Enqueue_ordered(
     context,
     thread,
-    has_processor_allocated,
     _Scheduler_simple_Insert_priority_lifo_order,
     _Scheduler_simple_SMP_Insert_ready_lifo,
     _Scheduler_SMP_Insert_scheduled_lifo
@@ -201,14 +195,59 @@ static void _Scheduler_simple_SMP_Enqueue_lifo(
 
 static void _Scheduler_simple_SMP_Enqueue_fifo(
   Scheduler_Context *context,
-  Thread_Control *thread,
-  bool has_processor_allocated
+  Thread_Control *thread
 )
 {
   _Scheduler_simple_SMP_Enqueue_ordered(
     context,
     thread,
-    has_processor_allocated,
+    _Scheduler_simple_Insert_priority_fifo_order,
+    _Scheduler_simple_SMP_Insert_ready_fifo,
+    _Scheduler_SMP_Insert_scheduled_fifo
+  );
+}
+
+static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
+  Scheduler_Context *context,
+  Thread_Control *thread,
+  Chain_Node_order order,
+  Scheduler_SMP_Insert insert_ready,
+  Scheduler_SMP_Insert insert_scheduled
+)
+{
+  _Scheduler_SMP_Enqueue_scheduled_ordered(
+    context,
+    thread,
+    order,
+    _Scheduler_simple_SMP_Get_highest_ready,
+    insert_ready,
+    insert_scheduled,
+    _Scheduler_simple_SMP_Move_from_ready_to_scheduled
+  );
+}
+
+static void _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
+  Scheduler_Context *context,
+  Thread_Control *thread
+)
+{
+  _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
+    context,
+    thread,
+    _Scheduler_simple_Insert_priority_lifo_order,
+    _Scheduler_simple_SMP_Insert_ready_lifo,
+    _Scheduler_SMP_Insert_scheduled_lifo
+  );
+}
+
+static void _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
+  Scheduler_Context *context,
+  Thread_Control *thread
+)
+{
+  _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
+    context,
+    thread,
     _Scheduler_simple_Insert_priority_fifo_order,
     _Scheduler_simple_SMP_Insert_ready_fifo,
     _Scheduler_SMP_Insert_scheduled_fifo
@@ -222,7 +261,11 @@ void _Scheduler_simple_SMP_Unblock(
 {
   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
 
-  _Scheduler_simple_SMP_Enqueue_fifo( context, thread, false );
+  _Scheduler_SMP_Unblock(
+    context,
+    thread,
+    _Scheduler_simple_SMP_Enqueue_fifo
+  );
 }
 
 void _Scheduler_simple_SMP_Change_priority(
@@ -242,7 +285,9 @@ void _Scheduler_simple_SMP_Change_priority(
     _Scheduler_simple_SMP_Extract_from_ready,
     _Scheduler_simple_SMP_Do_update,
     _Scheduler_simple_SMP_Enqueue_fifo,
-    _Scheduler_simple_SMP_Enqueue_lifo
+    _Scheduler_simple_SMP_Enqueue_lifo,
+    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
+    _Scheduler_simple_SMP_Enqueue_scheduled_lifo
   );
 }
 
@@ -257,7 +302,7 @@ void _Scheduler_simple_SMP_Yield(
   _ISR_Disable( level );
 
   _Scheduler_SMP_Extract_from_scheduled( thread );
-  _Scheduler_simple_SMP_Enqueue_fifo( context, thread, true );
+  _Scheduler_simple_SMP_Enqueue_scheduled_fifo( context, thread );
 
   _ISR_Enable( level );
 }
diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 36fb156..ed6fefd 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -25,6 +25,7 @@ SUBDIRS += smpmigration01
 SUBDIRS += smpmigration02
 SUBDIRS += smpscheduler01
 SUBDIRS += smpscheduler02
+SUBDIRS += smpscheduler03
 SUBDIRS += smpsignal01
 SUBDIRS += smpswitchextension01
 SUBDIRS += smpthreadlife01
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 0b9b4c6..f9e7662 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -83,6 +83,7 @@ smppsxaffinity02/Makefile
 smppsxsignal01/Makefile
 smpscheduler01/Makefile
 smpscheduler02/Makefile
+smpscheduler03/Makefile
 smpsignal01/Makefile
 smpswitchextension01/Makefile
 smpthreadlife01/Makefile
diff --git a/testsuites/smptests/smpscheduler03/Makefile.am b/testsuites/smptests/smpscheduler03/Makefile.am
new file mode 100644
index 0000000..5df9c57
--- /dev/null
+++ b/testsuites/smptests/smpscheduler03/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpscheduler03
+smpscheduler03_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpscheduler03.scn smpscheduler03.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(smpscheduler03_OBJECTS)
+LINK_LIBS = $(smpscheduler03_LDLIBS)
+
+smpscheduler03$(EXEEXT): $(smpscheduler03_OBJECTS) $(smpscheduler03_DEPENDENCIES)
+	@rm -f smpscheduler03$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpscheduler03/init.c b/testsuites/smptests/smpscheduler03/init.c
new file mode 100644
index 0000000..a93ab7f
--- /dev/null
+++ b/testsuites/smptests/smpscheduler03/init.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2014 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.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulersmpimpl.h>
+
+#include "tmacros.h"
+
+const char rtems_test_name[] = "SMPSCHEDULER 3";
+
+static void task(rtems_task_argument arg)
+{
+  rtems_test_assert(0);
+}
+
+static void test_case(
+  Thread_Control *executing,
+  Scheduler_SMP_Node *node,
+  Scheduler_SMP_Node_state start_state,
+  Priority_Control prio,
+  bool prepend_it,
+  Scheduler_SMP_Node_state new_state
+)
+{
+  switch (start_state) {
+    case SCHEDULER_SMP_NODE_SCHEDULED:
+      _Thread_Change_priority(executing, 1, true);
+      break;
+    case SCHEDULER_SMP_NODE_READY:
+      _Thread_Change_priority(executing, 4, true);
+      break;
+    default:
+      rtems_test_assert(0);
+      break;
+  }
+  rtems_test_assert(node->state == start_state);
+
+  _Thread_Change_priority(executing, prio, prepend_it);
+  rtems_test_assert(node->state == new_state);
+}
+
+static const Scheduler_SMP_Node_state states[2] = {
+  SCHEDULER_SMP_NODE_SCHEDULED,
+  SCHEDULER_SMP_NODE_READY
+};
+
+static const Priority_Control priorities[2] = { 2, 5 };
+
+static const bool prepend_it[2] = { true, false };
+
+static void test(void)
+{
+  rtems_status_code sc;
+  rtems_id task_id;
+  Thread_Control *executing;
+  Scheduler_SMP_Node *node;
+  size_t i;
+  size_t j;
+  size_t k;
+
+  sc = rtems_task_create(
+    rtems_build_name('T', 'A', 'S', 'K'),
+    3,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &task_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(task_id, task, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  _Thread_Disable_dispatch();
+
+  executing = _Thread_Executing;
+  node = _Scheduler_SMP_Node_get( executing );
+
+  for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
+    for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
+      for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
+        test_case(
+          executing,
+          node,
+          states[i],
+          priorities[j],
+          prepend_it[k],
+          states[j]
+        );
+      }
+    }
+  }
+
+  _Thread_Change_priority(executing, 1, true);
+  rtems_test_assert(node->state == SCHEDULER_SMP_NODE_SCHEDULED);
+
+  _Thread_Enable_dispatch();
+
+  sc = rtems_task_delete(task_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  TEST_BEGIN();
+
+  test();
+
+  TEST_END();
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 1
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpscheduler03/smpscheduler03.doc b/testsuites/smptests/smpscheduler03/smpscheduler03.doc
new file mode 100644
index 0000000..aece819
--- /dev/null
+++ b/testsuites/smptests/smpscheduler03/smpscheduler03.doc
@@ -0,0 +1,11 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpscheduler03
+
+directives:
+
+  - _Scheduler_SMP_Change_priority()
+
+concepts:
+
+  - Ensure that priority changes work.
diff --git a/testsuites/smptests/smpscheduler03/smpscheduler03.scn b/testsuites/smptests/smpscheduler03/smpscheduler03.scn
new file mode 100644
index 0000000..63cbf6a
--- /dev/null
+++ b/testsuites/smptests/smpscheduler03/smpscheduler03.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SMPSCHEDULER 3 ***
+*** END OF TEST SMPSCHEDULER 3 ***




More information about the vc mailing list