summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/threadchangepriority.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-03-05 21:01:40 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-03-05 21:01:40 +0000
commit96d0b64c620a2107a5d6b076a17ab26fca6b2a39 (patch)
tree1abb8637b91640982eff0d1d3a4f64e624182cca /cpukit/score/src/threadchangepriority.c
parent2007-03-05 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-96d0b64c620a2107a5d6b076a17ab26fca6b2a39.tar.bz2
2007-03-05 Joel Sherrill <joel@OARcorp.com>
PR 1222/cpukit * score/Makefile.am, score/include/rtems/score/coremutex.h, score/include/rtems/score/threadq.h, score/inline/rtems/score/coremutex.inl, score/src/coremsgsubmit.c, score/src/coremutexsurrender.c, score/src/threadchangepriority.c, score/src/threadclearstate.c, score/src/threadhandler.c, score/src/threadinitialize.c, score/src/threadqdequeuefifo.c, score/src/threadqdequeuepriority.c, score/src/threadqenqueue.c, score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c, score/src/threadqextractfifo.c, score/src/threadqextractpriority.c, score/src/threadsetstate.c: Enhance so that when the prioirity of a thread that is blocked on a priority based thread queue is changed, that its placement in the queue is reevaluated based upon the new priority. This enhancement includes modifications to the SuperCore as well as new test cases. * score/src/threadqrequeue.c: New file.
Diffstat (limited to 'cpukit/score/src/threadchangepriority.c')
-rw-r--r--cpukit/score/src/threadchangepriority.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 89d0d2cd5f..9847f54f80 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -2,7 +2,7 @@
* Thread Handler
*
*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2006.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -55,8 +55,8 @@ void _Thread_Change_priority(
boolean prepend_it
)
{
- ISR_Level level;
- /* boolean do_prepend = FALSE; */
+ ISR_Level level;
+ States_Control state;
/*
* If this is a case where prepending the task to its priority is
@@ -66,13 +66,6 @@ void _Thread_Change_priority(
* change calls (e.g. rtems_task_set_priority) should always do an
* append not a prepend.
*/
-
- /*
- * Techically, the prepend should conditional on the thread lowering
- * its priority but that does allow cxd2004 of the acvc 2.0.1 to
- * pass with rtems 4.0.0. This should change when gnat redoes its
- * priority scheme.
- */
/*
if ( prepend_it &&
_Thread_Is_executing( the_thread ) &&
@@ -80,26 +73,46 @@ void _Thread_Change_priority(
prepend_it = TRUE;
*/
+ /*
+ * Set a transient state for the thread so it is pulled off the Ready chains.
+ * This will prevent it from being scheduled no matter what happens in an
+ * ISR.
+ */
_Thread_Set_transient( the_thread );
- if ( the_thread->current_priority != new_priority )
+ /*
+ * Do not bother recomputing all the priority related information if
+ * we are not REALLY changing priority.
+ */
+ if ( the_thread->current_priority != new_priority )
_Thread_Set_priority( the_thread, new_priority );
_ISR_Disable( level );
- the_thread->current_state =
- _States_Clear( STATES_TRANSIENT, the_thread->current_state );
-
- if ( ! _States_Is_ready( the_thread->current_state ) ) {
- /*
- * XXX If a task is to be reordered while blocked on a priority
- * XXX priority ordered thread queue, then this is where that
- * XXX should occur.
- */
+ /*
+ * If the thread has more than STATES_TRANSIENT set, then it is blocked,
+ * If it is blocked on a thread queue, then we need to requeue it.
+ */
+ state = the_thread->current_state;
+ if ( state != STATES_TRANSIENT ) {
+ if ( _States_Is_waiting_on_thread_queue( state ) ) {
+ _ISR_Enable( level );
+ _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
+ _ISR_Disable( level ); /* redisable so state is cleared with ISR off */
+ }
+ the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
_ISR_Enable( level );
return;
}
+ /*
+ * Interrupts are STILL disabled.
+ * We now know the thread will be in the READY state when we remove
+ * the TRANSIENT state. So we have to place it on the appropriate
+ * Ready Queue with interrupts off.
+ */
+ the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
+
_Priority_Add_to_bit_map( &the_thread->Priority_map );
if ( prepend_it )
_Chain_Prepend_unprotected( the_thread->ready, &the_thread->Object.Node );
@@ -108,6 +121,10 @@ void _Thread_Change_priority(
_ISR_Flash( level );
+ /*
+ * We altered the set of thread priorities. So let's figure out
+ * who is the heir and if we need to switch to them.
+ */
_Thread_Calculate_heir();
if ( !_Thread_Is_executing_also_the_heir() &&