diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-20 21:39:56 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-30 16:16:21 +0200 |
commit | 2581a563f9182dc2debdba97f33feee6d797e53a (patch) | |
tree | 97883371771f9a2905d159d8e11c0b2e9da0408c /cpukit/rtems | |
parent | rtems: Simplify rtems_semaphore_delete() (diff) | |
download | rtems-2581a563f9182dc2debdba97f33feee6d797e53a.tar.bz2 |
score: Add semaphore variants
Diffstat (limited to '')
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/sem.h | 18 | ||||
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/semimpl.h | 25 | ||||
-rw-r--r-- | cpukit/rtems/src/semcreate.c | 31 | ||||
-rw-r--r-- | cpukit/rtems/src/semdelete.c | 68 | ||||
-rw-r--r-- | cpukit/rtems/src/semflush.c | 54 | ||||
-rw-r--r-- | cpukit/rtems/src/semobtain.c | 60 | ||||
-rw-r--r-- | cpukit/rtems/src/semrelease.c | 44 |
7 files changed, 178 insertions, 122 deletions
diff --git a/cpukit/rtems/include/rtems/rtems/sem.h b/cpukit/rtems/include/rtems/rtems/sem.h index 2c99f57deb..fe74f44dfa 100644 --- a/cpukit/rtems/include/rtems/rtems/sem.h +++ b/cpukit/rtems/include/rtems/rtems/sem.h @@ -97,6 +97,24 @@ typedef struct { } Core_control; /** + * @brief The semaphore variant. + * + * @see Semaphore_Variant. + */ + unsigned int variant : 3; + + /** + * @brief The semaphore thread queue discipline. + * + * @see Semaphore_Discipline. + */ + unsigned int discipline : 1; + +#if defined(RTEMS_MULTIPROCESSING) + unsigned int is_global : 1; +#endif + + /** * This is the Classic API attribute provided to the create directive. * It is translated into behavioral attributes on the SuperCore Semaphore * or Mutex instance. diff --git a/cpukit/rtems/include/rtems/rtems/semimpl.h b/cpukit/rtems/include/rtems/rtems/semimpl.h index a498927691..813f885d5f 100644 --- a/cpukit/rtems/include/rtems/rtems/semimpl.h +++ b/cpukit/rtems/include/rtems/rtems/semimpl.h @@ -26,12 +26,37 @@ extern "C" { #endif +typedef enum { + SEMAPHORE_VARIANT_MUTEX, + SEMAPHORE_VARIANT_COUNTING +#if defined(RTEMS_SMP) + , + SEMAPHORE_VARIANT_MRSP +#endif +} Semaphore_Variant; + +typedef enum { + SEMAPHORE_DISCIPLINE_PRIORITY, + SEMAPHORE_DISCIPLINE_FIFO +} Semaphore_Discipline; + /** * The following defines the information control block used to manage * this class of objects. */ extern Objects_Information _Semaphore_Information; +RTEMS_INLINE_ROUTINE const Thread_queue_Operations *_Semaphore_Get_operations( + const Semaphore_Control *the_semaphore +) +{ + if ( the_semaphore->discipline == SEMAPHORE_DISCIPLINE_PRIORITY ) { + return &_Thread_queue_Operations_priority; + } else { + return &_Thread_queue_Operations_FIFO; + } +} + /** * @brief Allocates a semaphore control block from * the inactive chain of free semaphore control blocks. diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c index 83d46b607e..be8f9f5d3b 100644 --- a/cpukit/rtems/src/semcreate.c +++ b/cpukit/rtems/src/semcreate.c @@ -61,10 +61,9 @@ rtems_status_code rtems_semaphore_create( rtems_id *id ) { - Semaphore_Control *the_semaphore; - CORE_mutex_Attributes the_mutex_attr; - CORE_semaphore_Disciplines semaphore_discipline; - Status_Control status; + Semaphore_Control *the_semaphore; + CORE_mutex_Attributes the_mutex_attr; + Status_Control status; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; @@ -125,6 +124,8 @@ rtems_status_code rtems_semaphore_create( } #if defined(RTEMS_MULTIPROCESSING) + the_semaphore->is_global = _Attributes_Is_global( attribute_set ); + if ( _Attributes_Is_global( attribute_set ) && ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name, the_semaphore->Object.id, false ) ) ) { @@ -136,29 +137,25 @@ rtems_status_code rtems_semaphore_create( the_semaphore->attribute_set = attribute_set; + if ( _Attributes_Is_priority( attribute_set ) ) { + the_semaphore->discipline = SEMAPHORE_DISCIPLINE_PRIORITY; + } else { + the_semaphore->discipline = SEMAPHORE_DISCIPLINE_FIFO; + } + /* * Initialize it as a counting semaphore. */ if ( _Attributes_Is_counting_semaphore( attribute_set ) ) { - if ( _Attributes_Is_priority( attribute_set ) ) - semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY; - else - semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO; - - /* - * The following are just to make Purify happy. - */ - the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; - the_mutex_attr.priority_ceiling = PRIORITY_MINIMUM; - + the_semaphore->variant = SEMAPHORE_VARIANT_COUNTING; _CORE_semaphore_Initialize( &the_semaphore->Core_control.semaphore, - semaphore_discipline, count ); status = STATUS_SUCCESSFUL; #if defined(RTEMS_SMP) } else if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + the_semaphore->variant = SEMAPHORE_VARIANT_MRSP; status = _MRSP_Initialize( &the_semaphore->Core_control.mrsp, priority_ceiling, @@ -167,6 +164,8 @@ rtems_status_code rtems_semaphore_create( ); #endif } else { + the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX; + /* * It is either simple binary semaphore or a more powerful mutex * style binary semaphore. This is the mutex style. diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index 16889cd6b6..45c356f452 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -53,22 +53,27 @@ rtems_status_code rtems_semaphore_delete( &queue_context.Lock_context ); + switch ( the_semaphore->variant ) { + case SEMAPHORE_VARIANT_MUTEX: + if ( + _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) + && !_Attributes_Is_simple_binary_semaphore( attribute_set ) + ) { + status = STATUS_RESOURCE_IN_USE; + } else { + status = STATUS_SUCCESSFUL; + } + + break; #if defined(RTEMS_SMP) - if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - status = _MRSP_Can_destroy( &the_semaphore->Core_control.mrsp ); - } else + case SEMAPHORE_VARIANT_MRSP: + status = _MRSP_Can_destroy( &the_semaphore->Core_control.mrsp ); + break; #endif - if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { - if ( - _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) - && !_Attributes_Is_simple_binary_semaphore( attribute_set ) - ) { - status = STATUS_RESOURCE_IN_USE; - } else { + default: + _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); status = STATUS_SUCCESSFUL; - } - } else { - status = STATUS_SUCCESSFUL; + break; } if ( status != STATUS_SUCCESSFUL ) { @@ -82,27 +87,32 @@ rtems_status_code rtems_semaphore_delete( _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); + switch ( the_semaphore->variant ) { + case SEMAPHORE_VARIANT_MUTEX: + _CORE_mutex_Flush( + &the_semaphore->Core_control.mutex, + _Thread_queue_Flush_status_object_was_deleted, + &queue_context + ); + _CORE_mutex_Destroy( &the_semaphore->Core_control.mutex ); + break; #if defined(RTEMS_SMP) - if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - _MRSP_Destroy( &the_semaphore->Core_control.mrsp, &queue_context ); - } else + case SEMAPHORE_VARIANT_MRSP: + _MRSP_Destroy( &the_semaphore->Core_control.mrsp, &queue_context ); + break; #endif - if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { - _CORE_mutex_Flush( - &the_semaphore->Core_control.mutex, - _Thread_queue_Flush_status_object_was_deleted, - &queue_context - ); - _CORE_mutex_Destroy( &the_semaphore->Core_control.mutex ); - } else { - _CORE_semaphore_Destroy( - &the_semaphore->Core_control.semaphore, - &queue_context - ); + default: + _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); + _CORE_semaphore_Destroy( + &the_semaphore->Core_control.semaphore, + _Semaphore_Get_operations( the_semaphore ), + &queue_context + ); + break; } #if defined(RTEMS_MULTIPROCESSING) - if ( _Attributes_Is_global( attribute_set ) ) { + if ( the_semaphore->is_global ) { _Objects_MP_Close( &_Semaphore_Information, id ); diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c index 07d4aa98b4..f768bbd4a7 100644 --- a/cpukit/rtems/src/semflush.c +++ b/cpukit/rtems/src/semflush.c @@ -19,13 +19,11 @@ #endif #include <rtems/rtems/semimpl.h> -#include <rtems/rtems/attrimpl.h> rtems_status_code rtems_semaphore_flush( rtems_id id ) { Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; - rtems_attribute attribute_set; the_semaphore = _Semaphore_Get( id, &queue_context ); @@ -39,38 +37,40 @@ rtems_status_code rtems_semaphore_flush( rtems_id id ) return RTEMS_INVALID_ID; } - attribute_set = the_semaphore->attribute_set; - + _Thread_queue_Acquire_critical( + &the_semaphore->Core_control.Wait_queue, + &queue_context.Lock_context + ); _Thread_queue_Context_set_MP_callout( &queue_context, _Semaphore_MP_Send_object_was_deleted ); + switch ( the_semaphore->variant ) { #if defined(RTEMS_SMP) - if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - _ISR_lock_ISR_enable( &queue_context.Lock_context ); - return RTEMS_NOT_DEFINED; - } else + case SEMAPHORE_VARIANT_MRSP: + _Thread_queue_Release( + &the_semaphore->Core_control.Wait_queue, + &queue_context.Lock_context + ); + return RTEMS_NOT_DEFINED; #endif - if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { - _CORE_mutex_Acquire_critical( - &the_semaphore->Core_control.mutex, - &queue_context - ); - _CORE_mutex_Flush( - &the_semaphore->Core_control.mutex, - _Thread_queue_Flush_status_unavailable, - &queue_context - ); - } else { - _CORE_semaphore_Acquire_critical( - &the_semaphore->Core_control.semaphore, - &queue_context - ); - _CORE_semaphore_Flush( - &the_semaphore->Core_control.semaphore, - &queue_context - ); + case SEMAPHORE_VARIANT_MUTEX: + _CORE_mutex_Flush( + &the_semaphore->Core_control.mutex, + _Thread_queue_Flush_status_unavailable, + &queue_context + ); + break; + default: + _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); + _CORE_semaphore_Flush( + &the_semaphore->Core_control.semaphore, + _Semaphore_Get_operations( the_semaphore ), + &queue_context + ); + break; } + return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c index 8cb195c5a2..93591b87c6 100644 --- a/cpukit/rtems/src/semobtain.c +++ b/cpukit/rtems/src/semobtain.c @@ -19,7 +19,6 @@ #endif #include <rtems/rtems/semimpl.h> -#include <rtems/rtems/attrimpl.h> #include <rtems/rtems/optionsimpl.h> #include <rtems/rtems/statusimpl.h> @@ -54,7 +53,6 @@ rtems_status_code rtems_semaphore_obtain( Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; Thread_Control *executing; - rtems_attribute attribute_set; bool wait; Status_Control status; @@ -69,36 +67,40 @@ rtems_status_code rtems_semaphore_obtain( } executing = _Thread_Executing; - attribute_set = the_semaphore->attribute_set; wait = !_Options_Is_no_wait( option_set ); + + switch ( the_semaphore->variant ) { #if defined(RTEMS_SMP) - if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - status = _MRSP_Seize( - &the_semaphore->Core_control.mrsp, - executing, - wait, - timeout, - &queue_context - ); - } else + case SEMAPHORE_VARIANT_MRSP: + status = _MRSP_Seize( + &the_semaphore->Core_control.mrsp, + executing, + wait, + timeout, + &queue_context + ); + break; #endif - if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { - status = _CORE_mutex_Seize( - &the_semaphore->Core_control.mutex, - executing, - wait, - timeout, - &queue_context - ); - } else { - /* must be a counting semaphore */ - status = _CORE_semaphore_Seize( - &the_semaphore->Core_control.semaphore, - executing, - wait, - timeout, - &queue_context - ); + case SEMAPHORE_VARIANT_MUTEX: + status = _CORE_mutex_Seize( + &the_semaphore->Core_control.mutex, + executing, + wait, + timeout, + &queue_context + ); + break; + default: + _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); + status = _CORE_semaphore_Seize( + &the_semaphore->Core_control.semaphore, + _Semaphore_Get_operations( the_semaphore ), + executing, + wait, + timeout, + &queue_context + ); + break; } return _Status_Get( status ); diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c index 10fe743480..d18901a40c 100644 --- a/cpukit/rtems/src/semrelease.c +++ b/cpukit/rtems/src/semrelease.c @@ -22,14 +22,12 @@ #endif #include <rtems/rtems/semimpl.h> -#include <rtems/rtems/attrimpl.h> #include <rtems/rtems/statusimpl.h> rtems_status_code rtems_semaphore_release( rtems_id id ) { Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; - rtems_attribute attribute_set; Status_Control status; the_semaphore = _Semaphore_Get( id, &queue_context ); @@ -47,27 +45,31 @@ rtems_status_code rtems_semaphore_release( rtems_id id ) _Semaphore_Core_mutex_mp_support ); - attribute_set = the_semaphore->attribute_set; + switch ( the_semaphore->variant ) { #if defined(RTEMS_SMP) - if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - status = _MRSP_Surrender( - &the_semaphore->Core_control.mrsp, - _Thread_Executing, - &queue_context - ); - } else + case SEMAPHORE_VARIANT_MRSP: + status = _MRSP_Surrender( + &the_semaphore->Core_control.mrsp, + _Thread_Executing, + &queue_context + ); + break; #endif - if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { - status = _CORE_mutex_Surrender( - &the_semaphore->Core_control.mutex, - &queue_context - ); - } else { - status = _CORE_semaphore_Surrender( - &the_semaphore->Core_control.semaphore, - UINT32_MAX, - &queue_context - ); + case SEMAPHORE_VARIANT_MUTEX: + status = _CORE_mutex_Surrender( + &the_semaphore->Core_control.mutex, + &queue_context + ); + break; + default: + _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); + status = _CORE_semaphore_Surrender( + &the_semaphore->Core_control.semaphore, + _Semaphore_Get_operations( the_semaphore ), + UINT32_MAX, + &queue_context + ); + break; } return _Status_Get( status ); |