diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-30 06:59:55 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-30 16:16:23 +0200 |
commit | 0b713f8940d90b480f8cd36663c11aa0688587d8 (patch) | |
tree | c71a01748c3749e0243518b486c2bb32a1c67df1 /cpukit/score/src | |
parent | score: Rework CORE priority ceiling mutex (diff) | |
download | rtems-0b713f8940d90b480f8cd36663c11aa0688587d8.tar.bz2 |
score: Rework CORE inherit priority mutex
Provide dedicated seize and surrender methods for inherit priority
mutexes. This eliminates CORE_mutex_Attributes.
Diffstat (limited to '')
-rw-r--r-- | cpukit/score/src/apimutex.c | 6 | ||||
-rw-r--r-- | cpukit/score/src/apimutexisowner.c | 6 | ||||
-rw-r--r-- | cpukit/score/src/apimutexlock.c | 7 | ||||
-rw-r--r-- | cpukit/score/src/apimutexunlock.c | 8 | ||||
-rw-r--r-- | cpukit/score/src/coremutex.c | 53 | ||||
-rw-r--r-- | cpukit/score/src/coremutexseize.c | 17 | ||||
-rw-r--r-- | cpukit/score/src/coremutexsurrender.c | 127 | ||||
-rw-r--r-- | cpukit/score/src/debugisownerofallocator.c | 2 |
8 files changed, 48 insertions, 178 deletions
diff --git a/cpukit/score/src/apimutex.c b/cpukit/score/src/apimutex.c index e3c6e5a705..ed5cfd5831 100644 --- a/cpukit/score/src/apimutex.c +++ b/cpukit/score/src/apimutex.c @@ -47,16 +47,12 @@ void _API_Mutex_Allocate( { API_Mutex_Control *mutex; - CORE_mutex_Attributes attr = { - CORE_MUTEX_NESTING_ACQUIRES - }; - mutex = (API_Mutex_Control *) _Objects_Allocate_unprotected( &_API_Mutex_Information ); _Assert( mutex != NULL ); - _CORE_mutex_Initialize( &mutex->Mutex, NULL, &attr, false ); + _CORE_recursive_mutex_Initialize( &mutex->Mutex ); _Objects_Open_u32( &_API_Mutex_Information, &mutex->Object, 1 ); diff --git a/cpukit/score/src/apimutexisowner.c b/cpukit/score/src/apimutexisowner.c index a80c664cb3..65b80ed5b3 100644 --- a/cpukit/score/src/apimutexisowner.c +++ b/cpukit/score/src/apimutexisowner.c @@ -18,9 +18,13 @@ #endif #include <rtems/score/apimutex.h> +#include <rtems/score/coremuteximpl.h> #include <rtems/score/threadimpl.h> bool _API_Mutex_Is_owner( const API_Mutex_Control *the_mutex ) { - return the_mutex->Mutex.holder == _Thread_Get_executing(); + return _CORE_mutex_Is_owner( + &the_mutex->Mutex.Mutex, + _Thread_Get_executing() + ); } diff --git a/cpukit/score/src/apimutexlock.c b/cpukit/score/src/apimutexlock.c index 7a7f911f84..df53e75256 100644 --- a/cpukit/score/src/apimutexlock.c +++ b/cpukit/score/src/apimutexlock.c @@ -34,15 +34,16 @@ void _API_Mutex_Lock( API_Mutex_Control *the_mutex ) _Thread_queue_Context_initialize( &queue_context ); _ISR_lock_ISR_disable( &queue_context.Lock_context ); - _CORE_mutex_Seize( + _CORE_recursive_mutex_Seize( &the_mutex->Mutex, _Thread_Executing, true, - 0, + WATCHDOG_NO_TIMEOUT, + _CORE_recursive_mutex_Seize_nested, &queue_context ); - if ( the_mutex->Mutex.nest_count == 1 ) { + if ( the_mutex->Mutex.nest_level == 0 ) { the_mutex->previous_thread_life_state = previous_thread_life_state; } } diff --git a/cpukit/score/src/apimutexunlock.c b/cpukit/score/src/apimutexunlock.c index 486301fa82..67188db144 100644 --- a/cpukit/score/src/apimutexunlock.c +++ b/cpukit/score/src/apimutexunlock.c @@ -29,11 +29,15 @@ void _API_Mutex_Unlock( API_Mutex_Control *the_mutex ) bool restore_thread_life_protection; previous_thread_life_state = the_mutex->previous_thread_life_state; - restore_thread_life_protection = the_mutex->Mutex.nest_count == 1; + restore_thread_life_protection = the_mutex->Mutex.nest_level == 0; _Thread_queue_Context_initialize( &queue_context ); _ISR_lock_ISR_disable( &queue_context.Lock_context ); - _CORE_mutex_Surrender( &the_mutex->Mutex, &queue_context ); + _CORE_recursive_mutex_Surrender( + &the_mutex->Mutex, + _Thread_Executing, + &queue_context + ); if ( restore_thread_life_protection ) { _Thread_Set_life_protection( previous_thread_life_state ); diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c deleted file mode 100644 index 9c6b7a8b93..0000000000 --- a/cpukit/score/src/coremutex.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file - * - * @brief Initialize a Core Mutex - * @ingroup ScoreMutex - */ - -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/system.h> -#include <rtems/score/isr.h> -#include <rtems/score/coremuteximpl.h> -#include <rtems/score/thread.h> - -Status_Control _CORE_mutex_Initialize( - CORE_mutex_Control *the_mutex, - Thread_Control *executing, - const CORE_mutex_Attributes *the_mutex_attributes, - bool initially_locked -) -{ - -/* Add this to the RTEMS environment later ????????? - rtems_assert( initial_lock == CORE_MUTEX_LOCKED || - initial_lock == CORE_MUTEX_UNLOCKED ); - */ - - the_mutex->Attributes = *the_mutex_attributes; - - if ( initially_locked ) { - the_mutex->nest_count = 1; - the_mutex->holder = executing; - executing->resource_count++; - } else { - the_mutex->nest_count = 0; - the_mutex->holder = NULL; - } - - _Thread_queue_Initialize( &the_mutex->Wait_queue ); - - return STATUS_SUCCESSFUL; -} diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index ed5eb0aeec..ab743c4847 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -22,14 +22,19 @@ #include <rtems/score/statesimpl.h> #include <rtems/score/thread.h> -Status_Control _CORE_mutex_Seize_interrupt_blocking( +Status_Control _CORE_mutex_Seize_slow( CORE_mutex_Control *the_mutex, Thread_Control *executing, + Thread_Control *owner, + bool wait, Watchdog_Interval timeout, Thread_queue_Context *queue_context ) { - Thread_Control *holder; + if ( !wait ) { + _CORE_mutex_Release( the_mutex, queue_context ); + return STATUS_UNAVAILABLE; + } #if !defined(RTEMS_SMP) /* @@ -37,23 +42,19 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking( * priority inheritance mutexes. */ _Thread_Dispatch_disable(); -#endif - - holder = the_mutex->holder; -#if !defined(RTEMS_SMP) /* * To enable interrupts here works only since exactly one executing thread * exists and only threads are allowed to seize and surrender mutexes with * the priority inheritance protocol. On SMP configurations more than one * executing thread may exist, so here we must not release the lock, since - * otherwise the current holder may be no longer the holder of the mutex + * otherwise the current owner may be no longer the owner of the mutex * once we released the lock. */ _CORE_mutex_Release( the_mutex, queue_context ); #endif - _Thread_Inherit_priority( holder, executing ); + _Thread_Inherit_priority( owner, executing ); #if defined(RTEMS_SMP) _Thread_queue_Context_set_expected_level( queue_context, 1 ); diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c index 5075e204c9..6604be89da 100644 --- a/cpukit/score/src/coremutexsurrender.c +++ b/cpukit/score/src/coremutexsurrender.c @@ -18,141 +18,58 @@ #include "config.h" #endif -#include <rtems/system.h> -#include <rtems/score/isr.h> #include <rtems/score/coremuteximpl.h> -#include <rtems/score/thread.h> -Status_Control _CORE_mutex_Surrender( +Status_Control _CORE_mutex_Surrender_slow( CORE_mutex_Control *the_mutex, + Thread_Control *executing, + Thread_queue_Heads *heads, + bool keep_priority, Thread_queue_Context *queue_context ) { - Thread_Control *the_thread; - Thread_Control *holder; + if ( heads != NULL ) { + const Thread_queue_Operations *operations; + Thread_Control *new_owner; + bool unblock; - holder = the_mutex->holder; + operations = CORE_MUTEX_TQ_OPERATIONS; + new_owner = ( *operations->first )( heads ); - /* - * Priority Ceiling or Priority Inheritance mutexes must be released by the - * thread which acquired them. - */ - if ( !_Thread_Is_executing( holder ) ) { - _ISR_lock_ISR_enable( &queue_context->Lock_context ); - return STATUS_NOT_OWNER; - } - - _CORE_mutex_Acquire_critical( the_mutex, queue_context ); - - /* XXX already unlocked -- not right status */ - - if ( !the_mutex->nest_count ) { - _CORE_mutex_Release( the_mutex, queue_context ); - return STATUS_SUCCESSFUL; - } - - the_mutex->nest_count--; + _CORE_mutex_Set_owner( the_mutex, new_owner ); - if ( the_mutex->nest_count != 0 ) { - /* - * All error checking is on the locking side, so if the lock was - * allowed to acquired multiple times, then we should just deal with - * that. The RTEMS_DEBUG is just a validation. - */ - #if defined(RTEMS_DEBUG) - switch ( the_mutex->Attributes.lock_nesting_behavior ) { - case CORE_MUTEX_NESTING_ACQUIRES: - _CORE_mutex_Release( the_mutex, queue_context ); - return STATUS_SUCCESSFUL; - #if defined(RTEMS_POSIX_API) - case CORE_MUTEX_NESTING_IS_ERROR: - /* should never occur */ - _CORE_mutex_Release( the_mutex, queue_context ); - return STATUS_NESTING_NOT_ALLOWED; - #endif - } - #else - _CORE_mutex_Release( the_mutex, queue_context ); - /* must be CORE_MUTEX_NESTING_ACQUIRES or we wouldn't be here */ - return STATUS_SUCCESSFUL; - #endif - } - - /* - * Formally release the mutex before possibly transferring it to a - * blocked thread. - */ - holder->resource_count--; - the_mutex->holder = NULL; - - /* - * Now we check if another thread was waiting for this mutex. If so, - * transfer the mutex to that thread. - */ - if ( - ( the_thread = _Thread_queue_First_locked( - &the_mutex->Wait_queue, - CORE_MUTEX_TQ_OPERATIONS - ) - ) - ) { - bool unblock; - - the_mutex->holder = the_thread; - the_mutex->nest_count = 1; - - /* - * We must extract the thread now since this will restore its default - * thread lock. This is necessary to avoid a deadlock in the - * _Thread_Change_priority() below due to a recursive thread queue lock - * acquire. - */ unblock = _Thread_queue_Extract_locked( &the_mutex->Wait_queue.Queue, - CORE_MUTEX_TQ_OPERATIONS, - the_thread, + operations, + new_owner, queue_context ); #if defined(RTEMS_MULTIPROCESSING) - if ( _Objects_Is_local_id( the_thread->Object.id ) ) + if ( _Objects_Is_local_id( new_owner->Object.id ) ) #endif { - the_thread->resource_count++; - _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread ); + ++new_owner->resource_count; + _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, new_owner ); } _Thread_queue_Unblock_critical( unblock, &the_mutex->Wait_queue.Queue, - the_thread, + new_owner, &queue_context->Lock_context ); } else { _CORE_mutex_Release( the_mutex, queue_context ); } - /* - * Whether or not someone is waiting for the mutex, an - * inherited priority must be lowered if this is the last - * mutex (i.e. resource) this task has. - */ - if ( !_Thread_Owns_resources( holder ) ) { - /* - * Ensure that the holder resource count is visible to all other processors - * and that we read the latest priority restore hint. - */ - _Atomic_Fence( ATOMIC_ORDER_ACQ_REL ); - - if ( holder->priority_restore_hint ) { - Per_CPU_Control *cpu_self; + if ( !keep_priority ) { + Per_CPU_Control *cpu_self; - cpu_self = _Thread_Dispatch_disable(); - _Thread_Restore_priority( holder ); - _Thread_Dispatch_enable( cpu_self ); - } + cpu_self = _Thread_Dispatch_disable(); + _Thread_Restore_priority( executing ); + _Thread_Dispatch_enable( cpu_self ); } - _CORE_mutex_Restore_priority( holder ); return STATUS_SUCCESSFUL; } diff --git a/cpukit/score/src/debugisownerofallocator.c b/cpukit/score/src/debugisownerofallocator.c index 57da2ca001..6b396df4fc 100644 --- a/cpukit/score/src/debugisownerofallocator.c +++ b/cpukit/score/src/debugisownerofallocator.c @@ -27,7 +27,7 @@ bool owner; if ( mutex != NULL ) { - owner = mutex->Mutex.holder == _Thread_Get_executing(); + owner = _API_Mutex_Is_owner( mutex ); } else { owner = false; } |