summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-08-04 08:10:29 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-08-04 08:10:29 +0200
commit1c1e31f788b85bf3bcadea675110eec35a612eb4 (patch)
treeb51f2d1ac7344d39bba73d1e4c37b9554d60515b
parentscore: Indroduce cancel job scheduler operation (diff)
downloadrtems-1c1e31f788b85bf3bcadea675110eec35a612eb4.tar.bz2
score: Optimize _Thread_queue_Path_release()
Update #2556.
-rw-r--r--cpukit/score/src/threadqenqueue.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 9ac57d05b4..8f11fa247f 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -162,6 +162,9 @@ static void _Thread_queue_Link_remove( Thread_queue_Link *link )
}
#endif
+#define THREAD_QUEUE_LINK_OF_PATH_NODE( node ) \
+ RTEMS_CONTAINER_OF( node, Thread_queue_Link, Path_node );
+
static void _Thread_queue_Path_release( Thread_queue_Path *path )
{
#if defined(RTEMS_SMP)
@@ -171,21 +174,40 @@ static void _Thread_queue_Path_release( Thread_queue_Path *path )
head = _Chain_Head( &path->Links );
node = _Chain_Last( &path->Links );
- while ( head != node ) {
+ if ( head != node ) {
Thread_queue_Link *link;
- link = RTEMS_CONTAINER_OF( node, Thread_queue_Link, Path_node );
-
- if ( link->Queue_context.Wait.queue != NULL ) {
- _Thread_queue_Link_remove( link );
- }
+ /* The terminal link has an owner which does not wait on a thread queue */
+ link = THREAD_QUEUE_LINK_OF_PATH_NODE( node );
+ _Assert( link->Queue_context.Wait.queue == NULL );
- _Thread_Wait_release_critical( link->owner, &link->Queue_context );
+ _Thread_Wait_release_default_critical(
+ link->owner,
+ &link->Queue_context.Lock_context
+ );
node = _Chain_Previous( node );
#if defined(RTEMS_DEBUG)
_Chain_Set_off_chain( &link->Path_node );
#endif
+
+ while ( head != node ) {
+ /* The other links have an owner which waits on a thread queue */
+ link = THREAD_QUEUE_LINK_OF_PATH_NODE( node );
+ _Assert( link->Queue_context.Wait.queue != NULL );
+
+ _Thread_queue_Link_remove( link );
+ _Thread_Wait_release_queue_critical(
+ link->Queue_context.Wait.queue,
+ &link->Queue_context
+ );
+ _Thread_Wait_remove_request( link->owner, &link->Queue_context );
+
+ node = _Chain_Previous( node );
+#if defined(RTEMS_DEBUG)
+ _Chain_Set_off_chain( &link->Path_node );
+#endif
+ }
}
#else
(void) path;