From 31036f1dc8a963fb0bc3fc103f63028988314fea Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 18 Jul 2022 09:41:39 +0200 Subject: score: Use priority inheritance for thread join Threads may join the thread termination of another thread using the pthread_join() or rtems_task_delete() directives. The thread cancel operation used a special case priority boosting mechanism implemented by _Thread_Raise_real_priority(). The problem was that this approach * is not transitive, * does not account for priority adjustments of the calling task while waiting for the join, * does not support clustered scheduling, and * does not detect deadlocks. All these problems are fixed by using a priority inheritance thread queue for the join operation. Close #4679. --- cpukit/rtems/src/taskdelete.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'cpukit/rtems/src/taskdelete.c') diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c index 2e3de0922e..410842f393 100644 --- a/cpukit/rtems/src/taskdelete.c +++ b/cpukit/rtems/src/taskdelete.c @@ -40,6 +40,7 @@ #endif #include +#include #include rtems_status_code rtems_task_delete( @@ -47,12 +48,13 @@ rtems_status_code rtems_task_delete( ) { Thread_Control *the_thread; - Thread_Close_context context; + Thread_queue_Context queue_context; Per_CPU_Control *cpu_self; Thread_Control *executing; + Status_Control status; - _Thread_queue_Context_initialize( &context.Base ); - the_thread = _Thread_Get( id, &context.Base.Lock_context.Lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + the_thread = _Thread_Get( id, &queue_context.Lock_context.Lock_context ); if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) @@ -67,23 +69,22 @@ rtems_status_code rtems_task_delete( cpu_self = _Per_CPU_Get(); if ( _Per_CPU_Is_ISR_in_progress( cpu_self ) ) { - _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); + _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context ); return RTEMS_CALLED_FROM_ISR; } executing = _Per_CPU_Get_executing( cpu_self ); if ( the_thread == executing ) { - _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); + _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context ); /* * The Classic tasks are neither detached nor joinable. In case of * self deletion, they are detached, otherwise joinable by default. */ _Thread_Exit( NULL, THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED ); - } else { - _Thread_Close( the_thread, executing, &context ); } - return RTEMS_SUCCESSFUL; + status = _Thread_Close( the_thread, executing, &queue_context ); + return _Status_Get( status ); } -- cgit v1.2.3