From 5a598ac99b0de720a04afc5e2ac6764117589b90 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 27 May 2016 08:02:03 +0200 Subject: score: Add CORE mutex variants Add CORE_recursive_mutex_Control and CORE_ceiling_mutex_Control to avoid the run-time evaluation of attributes to figure out how a particular mutex methods should behave. Start with the no protocol variants. This eliminates the CORE_MUTEX_DISCIPLINES_FIFO and CORE_MUTEX_DISCIPLINES_PRIORITY disciplines. --- cpukit/score/src/apimutex.c | 1 - cpukit/score/src/coremutex.c | 57 +++++++++++++++-------------------- cpukit/score/src/coremutexseize.c | 27 ++++++++++++++++- cpukit/score/src/coremutexsurrender.c | 28 +++++------------ 4 files changed, 59 insertions(+), 54 deletions(-) (limited to 'cpukit/score/src') diff --git a/cpukit/score/src/apimutex.c b/cpukit/score/src/apimutex.c index a098edbd61..8af374aaef 100644 --- a/cpukit/score/src/apimutex.c +++ b/cpukit/score/src/apimutex.c @@ -49,7 +49,6 @@ void _API_Mutex_Allocate( CORE_mutex_Attributes attr = { CORE_MUTEX_NESTING_ACQUIRES, - true, CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT, 0 }; diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c index ec073ff999..6f73c1bd16 100644 --- a/cpukit/score/src/coremutex.c +++ b/cpukit/score/src/coremutex.c @@ -39,42 +39,41 @@ Status_Control _CORE_mutex_Initialize( the_mutex->Attributes = *the_mutex_attributes; if ( initially_locked ) { - bool is_priority_ceiling = - _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ); + bool is_priority_ceiling; + Priority_Control ceiling; + Per_CPU_Control *cpu_self; the_mutex->nest_count = 1; the_mutex->holder = executing; - if ( is_priority_ceiling || - _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) { - Priority_Control ceiling = the_mutex->Attributes.priority_ceiling; - Per_CPU_Control *cpu_self; - - /* The mutex initialization is only protected by the allocator lock */ - cpu_self = _Thread_Dispatch_disable(); + /* The mutex initialization is only protected by the allocator lock */ + cpu_self = _Thread_Dispatch_disable(); + is_priority_ceiling = + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ); + ceiling = the_mutex->Attributes.priority_ceiling; + + /* + * The test to check for a ceiling violation is a bit arbitrary. In case + * this thread is the owner of a priority inheritance mutex, then it may + * get a higher priority later or anytime on SMP configurations. + */ + if ( is_priority_ceiling && executing->current_priority < ceiling ) { /* - * The test to check for a ceiling violation is a bit arbitrary. In case - * this thread is the owner of a priority inheritance mutex, then it may - * get a higher priority later or anytime on SMP configurations. + * There is no need to undo the previous work since this error aborts + * the object creation. */ - if ( is_priority_ceiling && executing->current_priority < ceiling ) { - /* - * There is no need to undo the previous work since this error aborts - * the object creation. - */ - _Thread_Dispatch_enable( cpu_self ); - return STATUS_MUTEX_CEILING_VIOLATED; - } - - executing->resource_count++; + _Thread_Dispatch_enable( cpu_self ); + return STATUS_MUTEX_CEILING_VIOLATED; + } - if ( is_priority_ceiling ) { - _Thread_Raise_priority( executing, ceiling ); - } + executing->resource_count++; - _Thread_Dispatch_enable( cpu_self ); + if ( is_priority_ceiling ) { + _Thread_Raise_priority( executing, ceiling ); } + + _Thread_Dispatch_enable( cpu_self ); } else { the_mutex->nest_count = 0; the_mutex->holder = NULL; @@ -82,11 +81,5 @@ Status_Control _CORE_mutex_Initialize( _Thread_queue_Initialize( &the_mutex->Wait_queue ); - if ( _CORE_mutex_Is_fifo( the_mutex_attributes ) ) { - the_mutex->operations = &_Thread_queue_Operations_FIFO; - } else { - the_mutex->operations = &_Thread_queue_Operations_priority; - } - return STATUS_SUCCESSFUL; } diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index 7b8b603d9b..596378fda6 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -68,7 +68,7 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking( _Thread_queue_Enqueue_critical( &the_mutex->Wait_queue.Queue, - the_mutex->operations, + CORE_MUTEX_TQ_OPERATIONS, executing, STATES_WAITING_FOR_MUTEX, timeout, @@ -82,3 +82,28 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking( return _Thread_Wait_get_status( executing ); } +Status_Control _CORE_mutex_Seize_no_protocol_slow( + CORE_mutex_Control *the_mutex, + const Thread_queue_Operations *operations, + Thread_Control *executing, + bool wait, + Watchdog_Interval timeout, + Thread_queue_Context *queue_context +) +{ + if ( wait ) { + _Thread_queue_Context_set_expected_level( queue_context, 1 ); + _Thread_queue_Enqueue_critical( + &the_mutex->Wait_queue.Queue, + operations, + executing, + STATES_WAITING_FOR_MUTEX, + timeout, + queue_context + ); + return _Thread_Wait_get_status( executing ); + } else { + _CORE_mutex_Release( the_mutex, queue_context ); + return STATUS_UNAVAILABLE; + } +} diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c index 6047409085..2d976e0c22 100644 --- a/cpukit/score/src/coremutexsurrender.c +++ b/cpukit/score/src/coremutexsurrender.c @@ -34,18 +34,12 @@ Status_Control _CORE_mutex_Surrender( holder = the_mutex->holder; /* - * The following code allows a thread (or ISR) other than the thread - * which acquired the mutex to release that mutex. This is only - * allowed when the mutex in quetion is FIFO or simple Priority - * discipline. But Priority Ceiling or Priority Inheritance mutexes - * must be released by the thread which acquired them. + * Priority Ceiling or Priority Inheritance mutexes must be released by the + * thread which acquired them. */ - - if ( the_mutex->Attributes.only_owner_release ) { - if ( !_Thread_Is_executing( holder ) ) { - _ISR_lock_ISR_enable( &queue_context->Lock_context ); - return STATUS_NOT_OWNER; - } + 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 ); @@ -88,10 +82,7 @@ Status_Control _CORE_mutex_Surrender( * Formally release the mutex before possibly transferring it to a * blocked thread. */ - if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || - _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { - holder->resource_count--; - } + holder->resource_count--; the_mutex->holder = NULL; /* @@ -101,7 +92,7 @@ Status_Control _CORE_mutex_Surrender( if ( ( the_thread = _Thread_queue_First_locked( &the_mutex->Wait_queue, - the_mutex->operations + CORE_MUTEX_TQ_OPERATIONS ) ) ) { @@ -118,7 +109,7 @@ Status_Control _CORE_mutex_Surrender( */ unblock = _Thread_queue_Extract_locked( &the_mutex->Wait_queue.Queue, - the_mutex->operations, + CORE_MUTEX_TQ_OPERATIONS, the_thread, queue_context ); @@ -128,9 +119,6 @@ Status_Control _CORE_mutex_Surrender( #endif { switch ( the_mutex->Attributes.discipline ) { - case CORE_MUTEX_DISCIPLINES_FIFO: - case CORE_MUTEX_DISCIPLINES_PRIORITY: - break; case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: the_thread->resource_count++; _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread ); -- cgit v1.2.3