summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/schedulerimpl.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-30 14:08:18 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-07-01 11:51:49 +0200
commitc0bd0064ac41f0602c0abfe494dbe140d7c5282f (patch)
treeaaa200033234cf2d3833305f13565171521b0d26 /cpukit/score/include/rtems/score/schedulerimpl.h
parentscore: Workaround for #2751 (diff)
downloadrtems-c0bd0064ac41f0602c0abfe494dbe140d7c5282f.tar.bz2
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.
Diffstat (limited to 'cpukit/score/include/rtems/score/schedulerimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h101
1 files changed, 56 insertions, 45 deletions
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 9885adf210..2007b30b9d 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