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/rtems/include/rtems/rtems/attr.h | 13 ++++----- cpukit/rtems/inline/rtems/rtems/attr.inl | 48 ++++++++++++++++++++++---------- cpukit/rtems/macros/rtems/rtems/attr.inl | 29 ++++++++++++------- cpukit/rtems/src/semcreate.c | 41 +++++++++++++++++++-------- cpukit/rtems/src/semdelete.c | 2 +- cpukit/rtems/src/semflush.c | 2 +- cpukit/rtems/src/semobtain.c | 2 +- cpukit/rtems/src/semrelease.c | 2 +- 8 files changed, 92 insertions(+), 47 deletions(-) (limited to 'cpukit/rtems') diff --git a/cpukit/rtems/include/rtems/rtems/attr.h b/cpukit/rtems/include/rtems/rtems/attr.h index 20d8eebe01..b054bd6684 100644 --- a/cpukit/rtems/include/rtems/rtems/attr.h +++ b/cpukit/rtems/include/rtems/rtems/attr.h @@ -37,17 +37,16 @@ typedef unsigned32 rtems_attribute; #define RTEMS_FIFO 0x00000000 /* process RTEMS_FIFO */ #define RTEMS_PRIORITY 0x00000004 /* process by priority */ -#define RTEMS_COUNTING_SEMAPHORE 0x00000000 -#define RTEMS_BINARY_SEMAPHORE 0x00000010 +#define RTEMS_SEMAPHORE_CLASS 0x00000030 /* mask */ +#define RTEMS_COUNTING_SEMAPHORE 0x00000000 +#define RTEMS_BINARY_SEMAPHORE 0x00000010 +#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020 #define RTEMS_NO_INHERIT_PRIORITY 0x00000000 -#define RTEMS_INHERIT_PRIORITY 0x00000020 +#define RTEMS_INHERIT_PRIORITY 0x00000040 #define RTEMS_NO_PRIORITY_CEILING 0x00000000 -#define RTEMS_PRIORITY_CEILING 0x00000040 - -#define RTEMS_NESTING_ALLOWED 0x00000000 -#define RTEMS_NO_NESTING_ALLOWED 0x00000080 +#define RTEMS_PRIORITY_CEILING 0x00000080 #define RTEMS_APPLICATION_TASK 0x00000000 #define RTEMS_SYSTEM_TASK 0x00000100 diff --git a/cpukit/rtems/inline/rtems/rtems/attr.inl b/cpukit/rtems/inline/rtems/rtems/attr.inl index 94a8052648..d35be0dca4 100644 --- a/cpukit/rtems/inline/rtems/rtems/attr.inl +++ b/cpukit/rtems/inline/rtems/rtems/attr.inl @@ -119,58 +119,76 @@ RTEMS_INLINE_ROUTINE boolean _Attributes_Is_binary_semaphore( rtems_attribute attribute_set ) { - return ( attribute_set & RTEMS_BINARY_SEMAPHORE ); + return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE); } /*PAGE * - * _Attributes_Is_inherit_priority + * _Attributes_Is_simple_binary_semaphore * * DESCRIPTION: * - * This function returns TRUE if the priority inheritance attribute - * is enabled in the attribute_set and FALSE otherwise. + * This function returns TRUE if the simple binary semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. */ -RTEMS_INLINE_ROUTINE boolean _Attributes_Is_inherit_priority( +RTEMS_INLINE_ROUTINE boolean _Attributes_Is_simple_binary_semaphore( + rtems_attribute attribute_set +) +{ + return + ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE); +} + +/*PAGE + * + * _Attributes_Is_counting_semaphore + * + * DESCRIPTION: + * + * This function returns TRUE if the counting semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ + +RTEMS_INLINE_ROUTINE boolean _Attributes_Is_counting_semaphore( rtems_attribute attribute_set ) { - return ( attribute_set & RTEMS_INHERIT_PRIORITY ); + return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE); } /*PAGE * - * _Attributes_Is_priority_ceiling + * _Attributes_Is_inherit_priority * * DESCRIPTION: * - * This function returns TRUE if the priority ceiling attribute + * This function returns TRUE if the priority inheritance attribute * is enabled in the attribute_set and FALSE otherwise. */ - -RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority_ceiling( + +RTEMS_INLINE_ROUTINE boolean _Attributes_Is_inherit_priority( rtems_attribute attribute_set ) { - return ( attribute_set & RTEMS_PRIORITY_CEILING ); + return ( attribute_set & RTEMS_INHERIT_PRIORITY ); } /*PAGE * - * _Attributes_Is_nesting_allowed + * _Attributes_Is_priority_ceiling * * DESCRIPTION: * - * This function returns TRUE if the nesting allowed attribute + * This function returns TRUE if the priority ceiling attribute * is enabled in the attribute_set and FALSE otherwise. */ -RTEMS_INLINE_ROUTINE boolean _Attributes_Is_nesting_allowed( +RTEMS_INLINE_ROUTINE boolean _Attributes_Is_priority_ceiling( rtems_attribute attribute_set ) { - return ( !(attribute_set & RTEMS_NO_NESTING_ALLOWED) ); + return ( attribute_set & RTEMS_PRIORITY_CEILING ); } /*PAGE diff --git a/cpukit/rtems/macros/rtems/rtems/attr.inl b/cpukit/rtems/macros/rtems/rtems/attr.inl index 516752b7d1..56ccac6657 100644 --- a/cpukit/rtems/macros/rtems/rtems/attr.inl +++ b/cpukit/rtems/macros/rtems/rtems/attr.inl @@ -68,7 +68,25 @@ */ #define _Attributes_Is_binary_semaphore( _attribute_set ) \ - ( (_attribute_set) & RTEMS_BINARY_SEMAPHORE ) + (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE) + +/*PAGE + * + * _Attributes_Is_simple_binary_semaphore + * + */ + +#define _Attributes_Is_simple_binary_semaphore( _attribute_set ) \ + (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE) + +/*PAGE + * + * _Attributes_Is_counting_semaphore + * + */ + +#define _Attributes_Is_counting_semaphore( _attribute_set ) \ + (((_attribute_set) & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE) /*PAGE * @@ -88,15 +106,6 @@ #define _Attributes_Is_priority_ceiling( _attribute_set ) \ ( (_attribute_set) & RTEMS_PRIORITY_CEILING ) -/*PAGE - * - * _Attributes_Is_nesting_allowed - * - */ - -#define _Attributes_Is_nesting_allowed( _attribute_set ) \ - ( !((_attribute_set) & RTEMS_NO_NESTING_ALLOWED) ) - /*PAGE * * _Attributes_Is_system_task diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c index a63814acfe..3ffbfc39c0 100644 --- a/cpukit/rtems/src/semcreate.c +++ b/cpukit/rtems/src/semcreate.c @@ -96,13 +96,15 @@ rtems_status_code rtems_semaphore_create( if ( _Attributes_Is_inherit_priority( attribute_set ) || _Attributes_Is_priority_ceiling( attribute_set ) ) { - if ( ! ( _Attributes_Is_binary_semaphore( attribute_set ) && + if ( ! ( (_Attributes_Is_binary_semaphore( attribute_set ) || + _Attributes_Is_simple_binary_semaphore( attribute_set )) && + _Attributes_Is_priority( attribute_set ) ) ) return RTEMS_NOT_DEFINED; } - if ( _Attributes_Is_binary_semaphore( attribute_set ) && ( count > 1 ) ) + if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) ) return RTEMS_INVALID_NUMBER; _Thread_Disable_dispatch(); /* prevents deletion */ @@ -126,7 +128,13 @@ rtems_status_code rtems_semaphore_create( the_semaphore->attribute_set = attribute_set; - if ( _Attributes_Is_binary_semaphore( attribute_set ) ) { + /* + * If it is not a counting, semaphore, then it is either a + * simple binary semaphore or a more powerful lmutex style binary + * semaphore. + */ + + if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { if ( _Attributes_Is_inherit_priority( attribute_set ) ) the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT; else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) @@ -136,12 +144,24 @@ rtems_status_code rtems_semaphore_create( else the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO; - if ( _Attributes_Is_nesting_allowed( attribute_set ) ) - the_mutex_attributes.allow_nesting = TRUE; - else - the_mutex_attributes.allow_nesting = FALSE; - /* Add priority ceiling code here ????? */ + if ( _Attributes_Is_binary_semaphore( attribute_set ) ) { + the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; + + switch ( the_mutex_attributes.discipline ) { + case CORE_MUTEX_DISCIPLINES_FIFO: + case CORE_MUTEX_DISCIPLINES_PRIORITY: + the_mutex_attributes.only_owner_release = FALSE; + break; + case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: + case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: + the_mutex_attributes.only_owner_release = TRUE; + break; + } + } else { + the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS; + the_mutex_attributes.only_owner_release = FALSE; + } the_mutex_attributes.priority_ceiling = priority_ceiling; @@ -161,8 +181,7 @@ rtems_status_code rtems_semaphore_create( NULL #endif ); - } - else { + } else { if ( _Attributes_Is_priority( attribute_set ) ) the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY; else @@ -178,7 +197,7 @@ rtems_status_code rtems_semaphore_create( * The following are just to make Purify happy. */ - the_mutex_attributes.allow_nesting = TRUE; + the_mutex_attributes.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; the_mutex_attributes.priority_ceiling = PRIORITY_MINIMUM; _CORE_semaphore_Initialize( diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index 3bbc4001a1..1e9b165c71 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -81,7 +81,7 @@ rtems_status_code rtems_semaphore_delete( return RTEMS_INVALID_ID; case OBJECTS_LOCAL: - if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) ) { + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) { _Thread_Enable_dispatch(); return RTEMS_RESOURCE_IN_USE; diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c index 43e690479a..dcdd8b1b34 100644 --- a/cpukit/rtems/src/semflush.c +++ b/cpukit/rtems/src/semflush.c @@ -77,7 +77,7 @@ rtems_status_code rtems_semaphore_flush( return RTEMS_INVALID_ID; case OBJECTS_LOCAL: - if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) { + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { _CORE_mutex_Flush( &the_semaphore->Core_control.mutex, SEND_OBJECT_WAS_DELETED, diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c index 5c8eb400fb..fef659d3cb 100644 --- a/cpukit/rtems/src/semobtain.c +++ b/cpukit/rtems/src/semobtain.c @@ -92,7 +92,7 @@ rtems_status_code rtems_semaphore_obtain( else wait = TRUE; - if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) { + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { _CORE_mutex_Seize( &the_semaphore->Core_control.mutex, id, diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c index d33c857437..2f05b6503f 100644 --- a/cpukit/rtems/src/semrelease.c +++ b/cpukit/rtems/src/semrelease.c @@ -85,7 +85,7 @@ rtems_status_code rtems_semaphore_release( return RTEMS_INVALID_ID; case OBJECTS_LOCAL: - if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) { + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { mutex_status = _CORE_mutex_Surrender( &the_semaphore->Core_control.mutex, id, -- cgit v1.2.3