[rtems commit] rtems: Fix rtems_task_set_scheduler() API

Sebastian Huber sebh at rtems.org
Fri Jul 1 09:58:49 UTC 2016


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jun 30 14:08:18 2016 +0200

rtems: Fix rtems_task_set_scheduler() API

Task priorities are only valid within a scheduler instance. The
rtems_task_set_scheduler() directive moves a task from one scheduler
instance to another using the current priority of the thread. However,
the current task priority of the source scheduler instance is undefined
in the target scheduler instance. Add a third parameter to specify the
priority.

Close #2749.

---

 cpukit/rtems/include/rtems/rtems/tasks.h         |  23 +++-
 cpukit/rtems/src/tasksetscheduler.c              |  21 ++-
 cpukit/score/include/rtems/score/schedulerimpl.h | 101 +++++++-------
 cpukit/score/include/rtems/score/status.h        |   2 +
 testsuites/smptests/smpclock01/init.c            |   4 +-
 testsuites/smptests/smpmigration02/init.c        |  35 +++--
 testsuites/smptests/smpmrsp01/init.c             |  37 ++---
 testsuites/smptests/smpmutex01/init.c            |   2 +-
 testsuites/smptests/smppsxmutex01/init.c         |   6 +-
 testsuites/smptests/smpscheduler02/init.c        |   6 +-
 testsuites/smptests/smpscheduler03/init.c        |   4 +-
 testsuites/smptests/smpwakeafter01/init.c        |   4 +-
 testsuites/sptests/spscheduler01/init.c          | 163 +++++++++++++++++++++--
 13 files changed, 306 insertions(+), 102 deletions(-)

diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index 6273228..e690e60 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -448,23 +448,32 @@ rtems_status_code rtems_task_get_scheduler(
 );
 
 /**
- * @brief Sets the scheduler of a task.
+ * @brief Sets the scheduler instance of a task.
  *
- * The scheduler of a task is initialized to the scheduler of the task that
- * created it.
+ * Initially, the scheduler instance of a task is set to the scheduler instance
+ * of the task that created it.  This directive allows to move a task from its
+ * current scheduler instance to another specified by the scheduler identifier.
  *
  * @param[in] task_id Identifier of the task.  Use @ref RTEMS_SELF to select
- * the executing task.
- * @param[in] scheduler_id Identifier of the scheduler.
+ *   the executing task.
+ * @param[in] scheduler_id Identifier of the scheduler instance.
+ * @param[in] priority The task priority with respect to the new scheduler
+ *   instance.  The real and initial priority of the task is set to this value.
+ *   The initial priority is used by rtems_task_restart() for example.
  *
  * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Directive is illegal on remote tasks.
  * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier.
+ * @retval RTEMS_INVALID_PRIORITY Invalid priority.
+ * @retval RTEMS_RESOURCE_IN_USE The task owns resources which deny a scheduler
+ *   change.
  *
  * @see rtems_scheduler_ident().
  */
 rtems_status_code rtems_task_set_scheduler(
-  rtems_id task_id,
-  rtems_id scheduler_id
+  rtems_id            task_id,
+  rtems_id            scheduler_id,
+  rtems_task_priority priority
 );
 
 /**
diff --git a/cpukit/rtems/src/tasksetscheduler.c b/cpukit/rtems/src/tasksetscheduler.c
index 36fb46d..175f235 100644
--- a/cpukit/rtems/src/tasksetscheduler.c
+++ b/cpukit/rtems/src/tasksetscheduler.c
@@ -16,12 +16,14 @@
   #include "config.h"
 #endif
 
-#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/tasksimpl.h>
+#include <rtems/rtems/statusimpl.h>
 #include <rtems/score/schedulerimpl.h>
 
 rtems_status_code rtems_task_set_scheduler(
-  rtems_id task_id,
-  rtems_id scheduler_id
+  rtems_id            task_id,
+  rtems_id            scheduler_id,
+  rtems_task_priority priority
 )
 {
   const Scheduler_Control *scheduler;
@@ -30,12 +32,19 @@ rtems_status_code rtems_task_set_scheduler(
   ISR_lock_Context         state_lock_context;
   Per_CPU_Control         *cpu_self;
   void                    *lock;
-  bool                     ok;
+  bool                     valid;
+  Priority_Control         core_priority;
+  Status_Control           status;
 
   if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
     return RTEMS_INVALID_ID;
   }
 
+  core_priority = _RTEMS_Priority_To_core( scheduler, priority, &valid );
+  if ( !valid ) {
+    return RTEMS_INVALID_PRIORITY;
+  }
+
   the_thread = _Thread_Get( task_id, &lock_context );
 
   if ( the_thread == NULL ) {
@@ -54,10 +63,10 @@ rtems_status_code rtems_task_set_scheduler(
   lock = _Thread_Lock_acquire( the_thread, &lock_context );
   _Thread_State_acquire_critical( the_thread, &state_lock_context );
 
-  ok = _Scheduler_Set( scheduler, the_thread );
+  status = _Scheduler_Set( scheduler, the_thread, core_priority );
 
   _Thread_State_release_critical( the_thread, &state_lock_context );
   _Thread_Lock_release( lock, &lock_context );
   _Thread_Dispatch_enable( cpu_self );
-  return ok ? RTEMS_SUCCESSFUL : RTEMS_INCORRECT_STATE;
+  return _Status_Get( status );
 }
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 9885adf..2007b30 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -23,6 +23,7 @@
 #include <rtems/score/scheduler.h>
 #include <rtems/score/cpusetimpl.h>
 #include <rtems/score/smpimpl.h>
+#include <rtems/score/status.h>
 #include <rtems/score/threadimpl.h>
 
 #ifdef __cplusplus
@@ -580,51 +581,6 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Has_processor_ownership(
 #endif
 }
 
-RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
-  const Scheduler_Control *scheduler,
-  Thread_Control          *the_thread
-)
-{
-#if defined(RTEMS_SMP)
-  const Scheduler_Control *current_scheduler;
-  States_Control           current_state;
-
-  current_scheduler = _Scheduler_Get( the_thread );
-
-  if ( current_scheduler == scheduler ) {
-    return true;
-  }
-
-  if ( _Thread_Owns_resources( the_thread ) ) {
-    return false;
-  }
-
-  current_state = the_thread->current_state;
-
-  if ( _States_Is_ready( current_state ) ) {
-    _Scheduler_Block( the_thread );
-  }
-
-  _Scheduler_Node_destroy( current_scheduler, the_thread );
-  the_thread->Scheduler.own_control = scheduler;
-  the_thread->Scheduler.control = scheduler;
-  _Scheduler_Node_initialize(
-    scheduler,
-    the_thread,
-    the_thread->current_priority
-  );
-
-  if ( _States_Is_ready( current_state ) ) {
-    _Scheduler_Unblock( the_thread );
-  }
-
-  return true;
-#else
-  (void) scheduler;
-  return true;
-#endif
-}
-
 #if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
 
 RTEMS_INLINE_ROUTINE void _Scheduler_Get_processor_set(
@@ -1472,6 +1428,61 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir(
   }
 }
 
+RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
+  const Scheduler_Control *new_scheduler,
+  Thread_Control          *the_thread,
+  Priority_Control         priority
+)
+{
+  Scheduler_Node *own_node;
+
+  if (
+    _Thread_Owns_resources( the_thread )
+      || the_thread->Wait.queue != NULL
+  ) {
+    return STATUS_RESOURCE_IN_USE;
+  }
+
+  the_thread->current_priority = priority;
+  the_thread->real_priority = priority;
+  the_thread->Start.initial_priority = priority;
+
+  own_node = _Scheduler_Thread_get_own_node( the_thread );
+
+#if defined(RTEMS_SMP)
+  {
+    const Scheduler_Control *old_scheduler;
+
+    old_scheduler = _Scheduler_Get( the_thread );
+
+    if ( old_scheduler != new_scheduler ) {
+      States_Control current_state;
+
+      current_state = the_thread->current_state;
+
+      if ( _States_Is_ready( current_state ) ) {
+        _Scheduler_Block( the_thread );
+      }
+
+      _Scheduler_Node_destroy( old_scheduler, the_thread );
+      the_thread->Scheduler.own_control = new_scheduler;
+      the_thread->Scheduler.control = new_scheduler;
+      _Scheduler_Node_initialize( new_scheduler, the_thread, priority );
+
+      if ( _States_Is_ready( current_state ) ) {
+        _Scheduler_Unblock( the_thread );
+      }
+
+      return STATUS_SUCCESSFUL;
+    }
+  }
+#endif
+
+  _Scheduler_Node_set_priority( own_node, priority, false );
+  _Scheduler_Update_priority( the_thread );
+  return STATUS_SUCCESSFUL;
+}
+
 /** @} */
 
 #ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/status.h b/cpukit/score/include/rtems/score/status.h
index d30f731..a4b2de9 100644
--- a/cpukit/score/include/rtems/score/status.h
+++ b/cpukit/score/include/rtems/score/status.h
@@ -83,6 +83,8 @@ typedef enum {
     STATUS_BUILD( STATUS_CLASSIC_INCORRECT_STATE, EDEADLK ),
   STATUS_FLUSHED =
     STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EAGAIN ),
+  STATUS_INCORRECT_STATE =
+    STATUS_BUILD( STATUS_CLASSIC_INCORRECT_STATE, EINVAL ),
   STATUS_INTERRUPTED =
     STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EINTR ),
   STATUS_INVALID_NUMBER =
diff --git a/testsuites/smptests/smpclock01/init.c b/testsuites/smptests/smpclock01/init.c
index 36016ef..ec98e2e 100644
--- a/testsuites/smptests/smpclock01/init.c
+++ b/testsuites/smptests/smpclock01/init.c
@@ -133,7 +133,7 @@ static void test(void)
 
   sc = rtems_task_create(
     SCHEDULER_B,
-    1,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -141,7 +141,7 @@ static void test(void)
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(task_id, scheduler_b_id);
+  sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_start(task_id, timer_task, (rtems_task_argument) ctx);
diff --git a/testsuites/smptests/smpmigration02/init.c b/testsuites/smptests/smpmigration02/init.c
index 3af8283..193d599 100644
--- a/testsuites/smptests/smpmigration02/init.c
+++ b/testsuites/smptests/smpmigration02/init.c
@@ -46,20 +46,32 @@ typedef struct {
 
 static test_context test_instance;
 
+static rtems_task_priority migration_task_prio(uint32_t task_index)
+{
+  return task_index > 0 ? PRIO_LOW : PRIO_HIGH;
+}
+
 static void migration_task(rtems_task_argument arg)
 {
   test_context *ctx = &test_instance;
-  rtems_status_code sc;
+  uint32_t task_index = arg;
+  rtems_task_priority prio = migration_task_prio(task_index);
   uint32_t cpu_count = rtems_get_processor_count();
   uint32_t cpu_index = rtems_get_current_processor();
 
   while (true) {
+    rtems_status_code sc;
+
     cpu_index = (cpu_index + 1) % cpu_count;
 
-    sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index]);
+    sc = rtems_task_set_scheduler(
+      RTEMS_SELF,
+      ctx->scheduler_ids[cpu_index],
+      prio
+    );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    ++ctx->counters[arg].value;
+    ++ctx->counters[task_index].value;
 
     rtems_test_assert(cpu_index == rtems_get_current_processor());
   }
@@ -77,7 +89,7 @@ static void test_migrations(test_context *ctx)
 
     sc = rtems_task_create(
       rtems_build_name('T', 'A', 'S', 'K'),
-      task_index > 0 ? PRIO_LOW : PRIO_HIGH,
+      255,
       RTEMS_MINIMUM_STACK_SIZE,
       RTEMS_DEFAULT_MODES,
       RTEMS_DEFAULT_ATTRIBUTES,
@@ -85,7 +97,11 @@ static void test_migrations(test_context *ctx)
     );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    sc = rtems_task_set_scheduler(task_id, ctx->scheduler_ids[task_index % cpu_count]);
+    sc = rtems_task_set_scheduler(
+      task_id,
+      ctx->scheduler_ids[task_index % cpu_count],
+      migration_task_prio(task_index)
+    );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
     sc = rtems_task_start(task_id, migration_task, task_index);
@@ -163,7 +179,8 @@ static void test_double_migration(test_context *ctx)
 
     sc = rtems_task_set_scheduler(
       task_id,
-      ctx->scheduler_ids[cpu_other_index]
+      ctx->scheduler_ids[cpu_other_index],
+      2
     );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
@@ -189,7 +206,8 @@ static void test_double_migration(test_context *ctx)
 
     sc = rtems_task_set_scheduler(
       RTEMS_SELF,
-      ctx->scheduler_ids[cpu_other_index]
+      ctx->scheduler_ids[cpu_other_index],
+      1
     );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
@@ -207,7 +225,8 @@ static void test_double_migration(test_context *ctx)
 
     sc = rtems_task_set_scheduler(
       RTEMS_SELF,
-      ctx->scheduler_ids[cpu_self_index]
+      ctx->scheduler_ids[cpu_self_index],
+      1
     );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
diff --git a/testsuites/smptests/smpmrsp01/init.c b/testsuites/smptests/smpmrsp01/init.c
index 30fb577..efc997a 100644
--- a/testsuites/smptests/smpmrsp01/init.c
+++ b/testsuites/smptests/smpmrsp01/init.c
@@ -418,7 +418,7 @@ static void test_mrsp_obtain_and_release(test_context *ctx)
 
   sc = rtems_task_create(
     rtems_build_name('W', 'O', 'R', 'K'),
-    4,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -426,7 +426,7 @@ static void test_mrsp_obtain_and_release(test_context *ctx)
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
+  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 4);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_start(ctx->worker_ids[0], obtain_and_release_worker, 0);
@@ -575,7 +575,7 @@ static void test_mrsp_obtain_after_migration(test_context *ctx)
 
   sc = rtems_task_create(
     rtems_build_name('W', 'O', 'R', 'K'),
-    3,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -583,7 +583,7 @@ static void test_mrsp_obtain_after_migration(test_context *ctx)
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
+  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 3);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   /* Create a MrsP semaphore objects */
@@ -1152,7 +1152,7 @@ static void start_low_task(test_context *ctx, size_t i)
 
   sc = rtems_task_create(
     rtems_build_name('L', 'O', 'W', '0' + i),
-    5,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -1160,7 +1160,7 @@ static void start_low_task(test_context *ctx, size_t i)
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(ctx->low_task_id[i], ctx->scheduler_ids[i]);
+  sc = rtems_task_set_scheduler(ctx->low_task_id[i], ctx->scheduler_ids[i], 5);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_start(
@@ -1202,7 +1202,7 @@ static void test_mrsp_various_block_and_unblock(test_context *ctx)
 
   sc = rtems_task_create(
     rtems_build_name('H', 'I', 'G', '1'),
-    2,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -1210,12 +1210,12 @@ static void test_mrsp_various_block_and_unblock(test_context *ctx)
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(ctx->high_task_id[1], ctx->scheduler_ids[1]);
+  sc = rtems_task_set_scheduler(ctx->high_task_id[1], ctx->scheduler_ids[1], 2);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_create(
     rtems_build_name('W', 'O', 'R', 'K'),
-    4,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -1223,7 +1223,7 @@ static void test_mrsp_various_block_and_unblock(test_context *ctx)
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
+  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 4);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_start(ctx->worker_ids[0], ready_unlock_worker, 0);
@@ -1365,7 +1365,7 @@ static void test_mrsp_obtain_and_release_with_help(test_context *ctx)
 
   sc = rtems_task_create(
     rtems_build_name('H', 'E', 'L', 'P'),
-    3,
+    255,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
@@ -1375,7 +1375,8 @@ static void test_mrsp_obtain_and_release_with_help(test_context *ctx)
 
   sc = rtems_task_set_scheduler(
     help_task_id,
-    ctx->scheduler_ids[1]
+    ctx->scheduler_ids[1],
+    3
   );
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
@@ -1549,7 +1550,7 @@ static void migration_task(rtems_task_argument arg)
   while (true) {
     uint32_t cpu_index = (v >> 5) % cpu_count;
 
-    sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index]);
+    sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index], 2);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
     ++ctx->migration_counters[rtems_get_current_processor()];
@@ -1600,7 +1601,7 @@ static void test_mrsp_load(test_context *ctx)
 
     sc = rtems_task_create(
       'A' + a,
-      3 + MRSP_COUNT + a,
+      255,
       RTEMS_MINIMUM_STACK_SIZE,
       RTEMS_DEFAULT_MODES,
       RTEMS_DEFAULT_ATTRIBUTES,
@@ -1610,7 +1611,8 @@ static void test_mrsp_load(test_context *ctx)
 
     sc = rtems_task_set_scheduler(
       ctx->worker_ids[a],
-      ctx->scheduler_ids[index]
+      ctx->scheduler_ids[index],
+      3 + MRSP_COUNT + a
     );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
@@ -1623,7 +1625,7 @@ static void test_mrsp_load(test_context *ctx)
 
     sc = rtems_task_create(
       'A' + b,
-      3 + MRSP_COUNT + b,
+      255,
       RTEMS_MINIMUM_STACK_SIZE,
       RTEMS_DEFAULT_MODES,
       RTEMS_DEFAULT_ATTRIBUTES,
@@ -1633,7 +1635,8 @@ static void test_mrsp_load(test_context *ctx)
 
     sc = rtems_task_set_scheduler(
       ctx->worker_ids[b],
-      ctx->scheduler_ids[index]
+      ctx->scheduler_ids[index],
+      3 + MRSP_COUNT + b
     );
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
diff --git a/testsuites/smptests/smpmutex01/init.c b/testsuites/smptests/smpmutex01/init.c
index b138172..5adc2e2 100644
--- a/testsuites/smptests/smpmutex01/init.c
+++ b/testsuites/smptests/smpmutex01/init.c
@@ -81,7 +81,7 @@ static void start_task(
   sc = rtems_scheduler_ident(scheduler, &scheduler_id);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(ctx->tasks[id], scheduler_id);
+  sc = rtems_task_set_scheduler(ctx->tasks[id], scheduler_id, prio);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_start(ctx->tasks[id], entry, id);
diff --git a/testsuites/smptests/smppsxmutex01/init.c b/testsuites/smptests/smppsxmutex01/init.c
index 761b5b9..1cd7be5 100644
--- a/testsuites/smptests/smppsxmutex01/init.c
+++ b/testsuites/smptests/smppsxmutex01/init.c
@@ -44,6 +44,7 @@ static void *thread_b(void *arg)
   test_context *ctx;
   rtems_id scheduler_b_id;
   rtems_status_code sc;
+  rtems_task_priority prio;
   int prio_ceiling;
   int eno;
 
@@ -54,7 +55,10 @@ static void *thread_b(void *arg)
   sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(pthread_self(), scheduler_b_id);
+  sc = rtems_task_set_priority(pthread_self(), RTEMS_CURRENT_PRIORITY, &prio);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_set_scheduler(pthread_self(), scheduler_b_id, prio);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   rtems_test_assert(rtems_get_current_processor() == 1);
diff --git a/testsuites/smptests/smpscheduler02/init.c b/testsuites/smptests/smpscheduler02/init.c
index 52b3f61..660346e 100644
--- a/testsuites/smptests/smpscheduler02/init.c
+++ b/testsuites/smptests/smpscheduler02/init.c
@@ -165,10 +165,10 @@ static void test(void)
   rtems_test_assert(sched_get_priority_max(SCHED_RR) == 254);
 
   if (cpu_count > 1) {
-    sc = rtems_task_set_scheduler(task_id, scheduler_b_id);
+    sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    sc = rtems_task_set_scheduler(task_id, scheduler_b_id + 1);
+    sc = rtems_task_set_scheduler(task_id, scheduler_b_id + 1, 1);
     rtems_test_assert(sc == RTEMS_INVALID_ID);
 
     sc = rtems_task_get_scheduler(task_id, &scheduler_id);
@@ -200,7 +200,7 @@ static void test(void)
     sc = rtems_task_start(task_id, task, 0);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    sc = rtems_task_set_scheduler(task_id, scheduler_b_id);
+    sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
     sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
diff --git a/testsuites/smptests/smpscheduler03/init.c b/testsuites/smptests/smpscheduler03/init.c
index f610b62..b7a76a9 100644
--- a/testsuites/smptests/smpscheduler03/init.c
+++ b/testsuites/smptests/smpscheduler03/init.c
@@ -603,7 +603,7 @@ static void Init(rtems_task_argument arg)
 
     sc = rtems_task_create(
       rtems_build_name('T', 'A', 'S', 'K'),
-      1,
+      255,
       RTEMS_MINIMUM_STACK_SIZE,
       RTEMS_DEFAULT_MODES,
       RTEMS_DEFAULT_ATTRIBUTES,
@@ -614,7 +614,7 @@ static void Init(rtems_task_argument arg)
     sc = rtems_scheduler_ident(SCHED_NAME(cpu_index), &scheduler_id);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    sc = rtems_task_set_scheduler(ctx->task_id[cpu_index], scheduler_id);
+    sc = rtems_task_set_scheduler(ctx->task_id[cpu_index], scheduler_id, 1);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
     sc = rtems_task_start(ctx->task_id[cpu_index], test_task, cpu_index);
diff --git a/testsuites/smptests/smpwakeafter01/init.c b/testsuites/smptests/smpwakeafter01/init.c
index e5e0305..b82bd3f 100644
--- a/testsuites/smptests/smpwakeafter01/init.c
+++ b/testsuites/smptests/smpwakeafter01/init.c
@@ -93,7 +93,7 @@ static void test(void)
     for (j = 0; j < INTERVAL_COUNT; ++j) {
       sc = rtems_task_create(
         rtems_build_name('T', 'A', 'S', 'K'),
-        2,
+        255,
         RTEMS_MINIMUM_STACK_SIZE,
         RTEMS_DEFAULT_MODES,
         RTEMS_DEFAULT_ATTRIBUTES,
@@ -101,7 +101,7 @@ static void test(void)
       );
       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-      sc = rtems_task_set_scheduler(task_ids[i][j], scheduler_id);
+      sc = rtems_task_set_scheduler(task_ids[i][j], scheduler_id, 2);
       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
       sc = rtems_task_start(task_ids[i][j], task, make_arg(i, j));
diff --git a/testsuites/sptests/spscheduler01/init.c b/testsuites/sptests/spscheduler01/init.c
index 31a0ec8..bb0c16d 100644
--- a/testsuites/sptests/spscheduler01/init.c
+++ b/testsuites/sptests/spscheduler01/init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -31,6 +31,10 @@ const char rtems_test_name[] = "SPSCHEDULER 1";
 
 static const rtems_id invalid_id = 1;
 
+static rtems_id master_id;
+
+static rtems_id sema_id;
+
 static void test_task_get_set_affinity(void)
 {
 #if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
@@ -119,13 +123,66 @@ static void test_task_get_set_affinity(void)
 #endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */
 }
 
-static void task(rtems_task_argument arg)
+static rtems_task_priority set_prio(rtems_id id, rtems_task_priority prio)
+{
+  rtems_status_code sc;
+  rtems_task_priority old_prio;
+
+  old_prio = 0xffffffff;
+  sc = rtems_task_set_priority(id, prio, &old_prio);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  return old_prio;
+}
+
+static void forbidden_task(rtems_task_argument arg)
 {
   (void) arg;
 
   rtems_test_assert(0);
 }
 
+static void restart_task(rtems_task_argument arg)
+{
+  rtems_status_code sc;
+
+  if (arg == 0) {
+    rtems_test_assert(set_prio(RTEMS_SELF, 3) == 2);
+
+    rtems_task_restart(RTEMS_SELF, 1);
+  } else if (arg == 1) {
+    rtems_id scheduler_id;
+
+    rtems_test_assert(set_prio(RTEMS_SELF, 3) == 2);
+
+    sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+    sc = rtems_task_set_scheduler(RTEMS_SELF, scheduler_id, 4);
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+    rtems_test_assert(set_prio(RTEMS_SELF, 3) == 4);
+
+    rtems_task_restart(RTEMS_SELF, 2);
+  } else {
+    rtems_test_assert(set_prio(RTEMS_SELF, 3) == 4);
+
+    rtems_task_resume(master_id);
+  }
+
+  rtems_test_assert(0);
+}
+
+static void sema_task(rtems_task_argument arg)
+{
+  rtems_status_code sc;
+
+  sc = rtems_semaphore_obtain(sema_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(0);
+}
+
 static void test_task_get_set_scheduler(void)
 {
   rtems_status_code sc;
@@ -134,6 +191,7 @@ static void test_task_get_set_scheduler(void)
   rtems_id scheduler_id;
   rtems_id scheduler_by_name;
   rtems_id task_id;
+  rtems_id mtx_id;
 
   sc = rtems_scheduler_ident(name, &scheduler_by_name);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -156,13 +214,46 @@ static void test_task_get_set_scheduler(void)
 
   rtems_test_assert(scheduler_id == scheduler_by_name);
 
-  sc = rtems_task_set_scheduler(invalid_id, scheduler_id);
+  sc = rtems_task_set_scheduler(invalid_id, scheduler_id, 1);
   rtems_test_assert(sc == RTEMS_INVALID_ID);
 
-  sc = rtems_task_set_scheduler(self_id, invalid_id);
+  sc = rtems_task_set_scheduler(self_id, invalid_id, 1);
   rtems_test_assert(sc == RTEMS_INVALID_ID);
 
-  sc = rtems_task_set_scheduler(self_id, scheduler_id);
+  sc = rtems_task_set_scheduler(self_id, scheduler_id, UINT32_C(0x80000000));
+  rtems_test_assert(sc == RTEMS_INVALID_PRIORITY);
+
+  sc = rtems_task_set_scheduler(self_id, scheduler_id, 1);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_semaphore_create(
+    rtems_build_name(' ', 'M', 'T', 'X'),
+    0,
+    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
+    0,
+    &mtx_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_set_scheduler(self_id, scheduler_id, 1);
+  rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
+
+  sc = rtems_semaphore_release(mtx_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(set_prio(self_id, RTEMS_CURRENT_PRIORITY) == 1);
+
+  sc = rtems_task_set_scheduler(self_id, scheduler_id, 2);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(set_prio(self_id, RTEMS_CURRENT_PRIORITY) == 2);
+
+  sc = rtems_task_set_scheduler(self_id, scheduler_id, 1);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(set_prio(self_id, RTEMS_CURRENT_PRIORITY) == 1);
+
+  sc = rtems_semaphore_delete(mtx_id);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_create(
@@ -181,13 +272,66 @@ static void test_task_get_set_scheduler(void)
 
   rtems_test_assert(scheduler_id == scheduler_by_name);
 
-  sc = rtems_task_set_scheduler(task_id, scheduler_id);
+  sc = rtems_task_set_scheduler(task_id, scheduler_id, 2);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(task_id, forbidden_task, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_set_scheduler(task_id, scheduler_id, 2);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_delete(task_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_create(
+    rtems_build_name('T', 'A', 'S', 'K'),
+    2,
+    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);
+  sc = rtems_task_start(task_id, restart_task, 0);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  sc = rtems_task_set_scheduler(task_id, scheduler_id);
+  sc = rtems_task_suspend(self_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_delete(task_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_semaphore_create(
+    rtems_build_name('S', 'E', 'M', 'A'),
+    0,
+    RTEMS_COUNTING_SEMAPHORE,
+    0,
+    &sema_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_create(
+    rtems_build_name('T', 'A', 'S', 'K'),
+    1,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &task_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(task_id, sema_task, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_set_scheduler(task_id, scheduler_id, 1);
+  rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
+
+  sc = rtems_semaphore_delete(sema_id);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   sc = rtems_task_delete(task_id);
@@ -275,6 +419,8 @@ static void Init(rtems_task_argument arg)
 
   rtems_resource_snapshot_take(&snapshot);
 
+  master_id = rtems_task_self();
+
   test_task_get_set_affinity();
   test_task_get_set_scheduler();
   test_scheduler_ident();
@@ -290,6 +436,7 @@ static void Init(rtems_task_argument arg)
 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
 
 #define CONFIGURE_MAXIMUM_TASKS 2
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
 
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 



More information about the vc mailing list