diff options
Diffstat (limited to 'cpukit/rtems')
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/semimpl.h | 1 | ||||
-rw-r--r-- | cpukit/rtems/src/semcreate.c | 41 | ||||
-rw-r--r-- | cpukit/rtems/src/semdelete.c | 2 | ||||
-rw-r--r-- | cpukit/rtems/src/semflush.c | 1 | ||||
-rw-r--r-- | cpukit/rtems/src/semobtain.c | 10 | ||||
-rw-r--r-- | cpukit/rtems/src/semrelease.c | 12 | ||||
-rw-r--r-- | cpukit/rtems/src/semsetpriority.c | 84 |
7 files changed, 100 insertions, 51 deletions
diff --git a/cpukit/rtems/include/rtems/rtems/semimpl.h b/cpukit/rtems/include/rtems/rtems/semimpl.h index 5b789d627d..9d82a12b3c 100644 --- a/cpukit/rtems/include/rtems/rtems/semimpl.h +++ b/cpukit/rtems/include/rtems/rtems/semimpl.h @@ -33,6 +33,7 @@ extern "C" { */ typedef enum { SEMAPHORE_VARIANT_MUTEX, + SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING, SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL, SEMAPHORE_VARIANT_SIMPLE_BINARY, SEMAPHORE_VARIANT_COUNTING diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c index 91f693c6c0..720fb63a0d 100644 --- a/cpukit/rtems/src/semcreate.c +++ b/cpukit/rtems/src/semcreate.c @@ -136,6 +136,7 @@ rtems_status_code rtems_semaphore_create( } #endif + priority_ceiling = _RTEMS_tasks_Priority_to_Core( priority_ceiling ); the_semaphore->attribute_set = attribute_set; executing = _Thread_Get_executing(); @@ -169,10 +170,32 @@ rtems_status_code rtems_semaphore_create( count != 1 ); #endif - } else if ( - !_Attributes_Is_inherit_priority( attribute_set ) - && !_Attributes_Is_priority_ceiling( attribute_set ) - ) { + } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) { + _Assert( _Attributes_Is_binary_semaphore( attribute_set ) ); + the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING; + _CORE_ceiling_mutex_Initialize( + &the_semaphore->Core_control.Mutex, + priority_ceiling + ); + + if ( count == 0 ) { + Thread_queue_Context queue_context; + + _Thread_queue_Context_initialize( &queue_context ); + _ISR_lock_ISR_disable( &queue_context.Lock_context ); + _CORE_mutex_Acquire_critical( + &the_semaphore->Core_control.Mutex.Recursive.Mutex, + &queue_context + ); + status = _CORE_ceiling_mutex_Set_owner( + &the_semaphore->Core_control.Mutex, + executing, + &queue_context + ); + } else { + status = STATUS_SUCCESSFUL; + } + } else if ( !_Attributes_Is_inherit_priority( attribute_set ) ) { _Assert( _Attributes_Is_binary_semaphore( attribute_set ) ); the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL; _CORE_recursive_mutex_Initialize( @@ -189,19 +212,11 @@ rtems_status_code rtems_semaphore_create( status = STATUS_SUCCESSFUL; } else { _Assert( _Attributes_Is_binary_semaphore( attribute_set ) ); + _Assert( _Attributes_Is_inherit_priority( attribute_set ) ); the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX; - the_mutex_attr.priority_ceiling = - _RTEMS_tasks_Priority_to_Core( priority_ceiling ); the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; - if ( _Attributes_Is_inherit_priority( attribute_set ) ) { - the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT; - } else { - _Assert( _Attributes_Is_priority_ceiling( attribute_set ) ); - the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING; - } - status = _CORE_mutex_Initialize( &the_semaphore->Core_control.Mutex.Recursive.Mutex, executing, diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index 365d895362..a38d761320 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -51,6 +51,7 @@ rtems_status_code rtems_semaphore_delete( switch ( the_semaphore->variant ) { case SEMAPHORE_VARIANT_MUTEX: + case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL: if ( _CORE_mutex_Is_locked( @@ -97,6 +98,7 @@ rtems_status_code rtems_semaphore_delete( default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX + || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c index 6c1f4ddf2c..17c589f588 100644 --- a/cpukit/rtems/src/semflush.c +++ b/cpukit/rtems/src/semflush.c @@ -58,6 +58,7 @@ rtems_status_code rtems_semaphore_flush( rtems_id id ) default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX + || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c index a7774d6f91..44507abefb 100644 --- a/cpukit/rtems/src/semobtain.c +++ b/cpukit/rtems/src/semobtain.c @@ -90,6 +90,16 @@ rtems_status_code rtems_semaphore_obtain( &queue_context ); break; + case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: + status = _CORE_ceiling_mutex_Seize( + &the_semaphore->Core_control.Mutex, + executing, + wait, + timeout, + _CORE_recursive_mutex_Seize_nested, + &queue_context + ); + break; case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL: status = _CORE_recursive_mutex_Seize_no_protocol( &the_semaphore->Core_control.Mutex.Recursive, diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c index 7cd92cfe0d..d92197b8f4 100644 --- a/cpukit/rtems/src/semrelease.c +++ b/cpukit/rtems/src/semrelease.c @@ -28,6 +28,7 @@ rtems_status_code rtems_semaphore_release( rtems_id id ) { Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; + Thread_Control *executing; Status_Control status; the_semaphore = _Semaphore_Get( id, &queue_context ); @@ -40,6 +41,8 @@ rtems_status_code rtems_semaphore_release( rtems_id id ) #endif } + executing = _Thread_Executing; + _Thread_queue_Context_set_MP_callout( &queue_context, _Semaphore_Core_mutex_mp_support @@ -50,7 +53,7 @@ rtems_status_code rtems_semaphore_release( rtems_id id ) case SEMAPHORE_VARIANT_MRSP: status = _MRSP_Surrender( &the_semaphore->Core_control.mrsp, - _Thread_Executing, + executing, &queue_context ); break; @@ -61,6 +64,13 @@ rtems_status_code rtems_semaphore_release( rtems_id id ) &queue_context ); break; + case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: + status = _CORE_ceiling_mutex_Surrender( + &the_semaphore->Core_control.Mutex, + executing, + &queue_context + ); + break; case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL: _CORE_recursive_mutex_Surrender_no_protocol_classic( &the_semaphore->Core_control.Mutex.Recursive, diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c index 0a8c58cde2..57a5368353 100644 --- a/cpukit/rtems/src/semsetpriority.c +++ b/cpukit/rtems/src/semsetpriority.c @@ -17,7 +17,6 @@ #endif #include <rtems/rtems/semimpl.h> -#include <rtems/rtems/attrimpl.h> #include <rtems/rtems/tasksimpl.h> #include <rtems/score/schedulerimpl.h> @@ -29,51 +28,62 @@ static rtems_status_code _Semaphore_Set_priority( Thread_queue_Context *queue_context ) { - rtems_status_code sc; - rtems_attribute attribute_set = the_semaphore->attribute_set; - rtems_task_priority old_priority; + rtems_status_code sc; + rtems_task_priority old_priority; +#if defined(RTEMS_SMP) + MRSP_Control *mrsp; + uint32_t scheduler_index; +#endif new_priority = _RTEMS_tasks_Priority_to_Core( new_priority ); + switch ( the_semaphore->variant ) { + case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: + _CORE_mutex_Acquire_critical( + &the_semaphore->Core_control.Mutex.Recursive.Mutex, + queue_context + ); + + old_priority = the_semaphore->Core_control.Mutex.priority_ceiling; + + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + the_semaphore->Core_control.Mutex.priority_ceiling = new_priority; + } + + _CORE_mutex_Release( + &the_semaphore->Core_control.Mutex.Recursive.Mutex, + queue_context + ); + sc = RTEMS_SUCCESSFUL; + break; #if defined(RTEMS_SMP) - if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - MRSP_Control *mrsp = &the_semaphore->Core_control.mrsp; - uint32_t scheduler_index = _Scheduler_Get_index_by_id( scheduler_id ); - - _MRSP_Acquire_critical( mrsp, queue_context ); + case SEMAPHORE_VARIANT_MRSP: + mrsp = &the_semaphore->Core_control.mrsp; + scheduler_index = _Scheduler_Get_index_by_id( scheduler_id ); - old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index ); + _MRSP_Acquire_critical( mrsp, queue_context ); - if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority ); - } + old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index ); - _MRSP_Release( mrsp, queue_context ); + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority ); + } - sc = RTEMS_SUCCESSFUL; - } else + _MRSP_Release( mrsp, queue_context ); + sc = RTEMS_SUCCESSFUL; + break; #endif - if ( _Attributes_Is_priority_ceiling( attribute_set ) ) { - CORE_mutex_Control *mutex; - - mutex = &the_semaphore->Core_control.Mutex.Recursive.Mutex; - _CORE_mutex_Acquire_critical( mutex, queue_context ); - - old_priority = mutex->Attributes.priority_ceiling; - - if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - mutex->Attributes.priority_ceiling = new_priority; - } - - _CORE_mutex_Release( mutex, queue_context ); - - sc = RTEMS_SUCCESSFUL; - } else { - _ISR_lock_ISR_enable( &queue_context->Lock_context ); - - old_priority = 0; - - sc = RTEMS_NOT_DEFINED; + default: + _Assert( + the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX + || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL + || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY + || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING + ); + _ISR_lock_ISR_enable( &queue_context->Lock_context ); + old_priority = 0; + sc = RTEMS_NOT_DEFINED; + break; } *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority ); |