From 1c1e31f788b85bf3bcadea675110eec35a612eb4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 4 Aug 2016 08:10:29 +0200 Subject: score: Optimize _Thread_queue_Path_release() Update #2556. --- cpukit/score/src/threadqenqueue.c | 36 +++++++++++++++++++++++++++++------- 1 file 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; -- cgit v1.2.3