From 5870ac55678115857215a4199f519263599ee341 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 5 Jan 2000 22:19:21 +0000 Subject: Added support for simple binary semaphores in addition to the high power binary/mutex style semaphores already supported by RTEMS. This was done at the request of Eric Norum in support of his effort to port EPICS to RTEMS. This change consisted of changing the nesting_allowed boolean into a lock_nesting_behavior enumerated value as well as allowing the core mutex object to optionally support ensuring that the holder of a binary semaphore released it. Finally, a more subtle enhancement was to allow the non-holder to release a priority inheritance/ceiling mutex and still allow the holding task to return to its original priority. --- cpukit/score/src/coremutex.c | 13 +++++++++++- cpukit/score/src/coremutexseize.c | 22 ++++++++++++-------- cpukit/score/src/coremutexsurrender.c | 39 +++++++++++++++-------------------- 3 files changed, 42 insertions(+), 32 deletions(-) (limited to 'cpukit/score/src') diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c index 2f5b4a6675..a5842efb91 100644 --- a/cpukit/score/src/coremutex.c +++ b/cpukit/score/src/coremutex.c @@ -55,7 +55,18 @@ void _CORE_mutex_Initialize( */ the_mutex->Attributes = *the_mutex_attributes; - the_mutex->lock = initial_lock; + the_mutex->lock = initial_lock; + +#if 0 + if ( !the_mutex_attributes->only_owner_release && + the_mutex_attributes->nesting_allowed ) { + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + TRUE, + INTERNAL_ERROR_BAD_ATTRIBUTES + ); + } +#endif if ( initial_lock == CORE_MUTEX_LOCKED ) { the_mutex->nest_count = 1; diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index c2a70da762..db576c6ef1 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -94,15 +94,19 @@ void _CORE_mutex_Seize( return; } - if ( _Objects_Are_ids_equal( - _Thread_Executing->Object.id, the_mutex->holder_id ) ) { - if ( _CORE_mutex_Is_nesting_allowed( &the_mutex->Attributes ) ) - the_mutex->nest_count++; - else - executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED; - - _ISR_Enable( level ); - return; + if ( _Thread_Is_executing( the_mutex->holder ) ) { + switch ( the_mutex->Attributes.lock_nesting_behavior ) { + case CORE_MUTEX_NESTING_ACQUIRES: + the_mutex->nest_count++; + _ISR_Enable( level ); + return; + case CORE_MUTEX_NESTING_IS_ERROR: + executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED; + _ISR_Enable( level ); + return; + case CORE_MUTEX_NESTING_BLOCKS: + break; + } } if ( !wait ) { diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c index 447a5421e8..d64badae1f 100644 --- a/cpukit/score/src/coremutexsurrender.c +++ b/cpukit/score/src/coremutexsurrender.c @@ -49,9 +49,9 @@ CORE_mutex_Status _CORE_mutex_Surrender( ) { Thread_Control *the_thread; - Thread_Control *executing; + Thread_Control *holder; - executing = _Thread_Executing; + holder = the_mutex->holder; /* * The following code allows a thread (or ISR) other than the thread @@ -61,20 +61,9 @@ CORE_mutex_Status _CORE_mutex_Surrender( * must be released by the thread which acquired them. */ - if ( the_mutex->Attributes.allow_nesting ) { - if ( !_Objects_Are_ids_equal( - _Thread_Executing->Object.id, the_mutex->holder_id ) ) { - - switch ( the_mutex->Attributes.discipline ) { - case CORE_MUTEX_DISCIPLINES_FIFO: - case CORE_MUTEX_DISCIPLINES_PRIORITY: - break; - case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: - case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: - return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE ); - break; - } - } + if ( the_mutex->Attributes.only_owner_release ) { + if ( !_Thread_Is_executing( holder ) ) + return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE ); } /* XXX already unlocked -- not right status */ @@ -85,9 +74,15 @@ CORE_mutex_Status _CORE_mutex_Surrender( the_mutex->nest_count--; if ( the_mutex->nest_count != 0 ) { - if ( the_mutex->Attributes.allow_nesting ) - return( CORE_MUTEX_STATUS_SUCCESSFUL ); - return( CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED ); + switch ( the_mutex->Attributes.lock_nesting_behavior ) { + case CORE_MUTEX_NESTING_ACQUIRES: + return CORE_MUTEX_STATUS_SUCCESSFUL; + case CORE_MUTEX_NESTING_IS_ERROR: + /* should never occur */ + return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED; + case CORE_MUTEX_NESTING_BLOCKS: + break; + } } _Thread_Executing->resource_count--; @@ -106,9 +101,9 @@ CORE_mutex_Status _CORE_mutex_Surrender( break; case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: - if ( executing->resource_count == 0 && - executing->real_priority != executing->current_priority ) { - _Thread_Change_priority( executing, executing->real_priority, TRUE ); + if ( holder->resource_count == 0 && + holder->real_priority != holder->current_priority ) { + _Thread_Change_priority( holder, holder->real_priority, TRUE ); } break; } -- cgit v1.2.3