summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/threadqenqueue.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-17 16:28:50 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-24 14:35:04 +0100
commit2e9c3d5e2944a8782eac8a12d23af7559873ad0a (patch)
treed19a9f00f4ca76811e3e4d25af5b48f50a2d47c1 /cpukit/score/src/threadqenqueue.c
parentcpukit/libmisc/utf8proc/utf8proc.c: Avoid overflow (diff)
downloadrtems-2e9c3d5e2944a8782eac8a12d23af7559873ad0a.tar.bz2
score: Add thread priority change handler
Since the thread current priority change and thread queue requeue is performed in one critical section it is possible to simplify the thread queue requeue procedure. Add a thread queue agnostic thread priority change handler so that we are able to use alternative thread queue implementations. Update #2273.
Diffstat (limited to '')
-rw-r--r--cpukit/score/src/threadqenqueue.c67
1 files changed, 25 insertions, 42 deletions
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 39353fe6d4..572d8403ff 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -73,6 +73,24 @@ static void _Thread_blocking_operation_Finalize(
#endif
}
+static void _Thread_queue_Requeue_priority(
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ void *context
+)
+{
+ Thread_queue_Control *tq = context;
+
+ _Thread_queue_Enter_critical_section( tq );
+ _RBTree_Extract( &tq->Queues.Priority, &the_thread->RBNode );
+ _RBTree_Insert(
+ &tq->Queues.Priority,
+ &the_thread->RBNode,
+ _Thread_queue_Compare_priority,
+ false
+ );
+}
+
void _Thread_queue_Enqueue_with_handler(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread,
@@ -127,6 +145,11 @@ void _Thread_queue_Enqueue_with_handler(
&the_thread->Object.Node
);
} else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
+ _Thread_Priority_set_change_handler(
+ the_thread,
+ _Thread_queue_Requeue_priority,
+ the_thread_queue
+ );
_RBTree_Insert(
&the_thread_queue->Queues.Priority,
&the_thread->RBNode,
@@ -172,6 +195,7 @@ void _Thread_queue_Extract_with_return_code(
&the_thread->Wait.queue->Queues.Priority,
&the_thread->RBNode
);
+ _Thread_Priority_restore_default_change_handler( the_thread );
}
the_thread->Wait.return_code = return_code;
@@ -221,6 +245,7 @@ Thread_Control *_Thread_queue_Dequeue(
first = _RBTree_Get( &the_thread_queue->Queues.Priority, RBT_LEFT );
if ( first ) {
the_thread = THREAD_RBTREE_NODE_TO_THREAD( first );
+ _Thread_Priority_restore_default_change_handler( the_thread );
}
}
@@ -249,45 +274,3 @@ Thread_Control *_Thread_queue_Dequeue(
return the_thread;
}
-
-void _Thread_queue_Requeue(
- Thread_queue_Control *the_thread_queue,
- Thread_Control *the_thread
-)
-{
- /*
- * Just in case the thread really wasn't blocked on a thread queue
- * when we get here.
- */
- if ( !the_thread_queue )
- return;
-
- /*
- * If queueing by FIFO, there is nothing to do. This only applies to
- * priority blocking discipline.
- */
- if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
- Thread_queue_Control *tq = the_thread_queue;
- ISR_Level level;
-
- _ISR_Disable( level );
- if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
- _Thread_queue_Enter_critical_section( tq );
-
- /* extract the thread */
- _RBTree_Extract(
- &the_thread->Wait.queue->Queues.Priority,
- &the_thread->RBNode
- );
-
- /* enqueue the thread at the new priority */
- _RBTree_Insert(
- &the_thread_queue->Queues.Priority,
- &the_thread->RBNode,
- _Thread_queue_Compare_priority,
- false
- );
- }
- _ISR_Enable( level );
- }
-}