diff options
Diffstat (limited to 'cpukit/rtems/src')
-rw-r--r-- | cpukit/rtems/src/semcreate.c | 38 | ||||
-rw-r--r-- | cpukit/rtems/src/semdelete.c | 21 | ||||
-rw-r--r-- | cpukit/rtems/src/semflush.c | 10 | ||||
-rw-r--r-- | cpukit/rtems/src/semobtain.c | 19 | ||||
-rw-r--r-- | cpukit/rtems/src/semrelease.c | 14 | ||||
-rw-r--r-- | cpukit/rtems/src/semsetpriority.c | 116 |
6 files changed, 208 insertions, 10 deletions
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c index fb597d1cbd..5e93e02632 100644 --- a/cpukit/rtems/src/semcreate.c +++ b/cpukit/rtems/src/semcreate.c @@ -78,12 +78,19 @@ rtems_status_code rtems_semaphore_create( return RTEMS_MP_NOT_CONFIGURED; if ( _Attributes_Is_inherit_priority( attribute_set ) || - _Attributes_Is_priority_ceiling( attribute_set ) ) + _Attributes_Is_priority_ceiling( attribute_set ) || + _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) return RTEMS_NOT_DEFINED; } else #endif + if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) && + !( _Attributes_Is_binary_semaphore( attribute_set ) && + !_Attributes_Is_priority( attribute_set ) ) ) { + return RTEMS_NOT_DEFINED; + } + if ( _Attributes_Is_inherit_priority( attribute_set ) || _Attributes_Is_priority_ceiling( attribute_set ) ) { @@ -93,13 +100,22 @@ rtems_status_code rtems_semaphore_create( } - if ( _Attributes_Is_inherit_priority( attribute_set ) && - _Attributes_Is_priority_ceiling( attribute_set ) ) + if ( !_Attributes_Has_at_most_one_protocol( attribute_set ) ) return RTEMS_NOT_DEFINED; if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) ) return RTEMS_INVALID_NUMBER; +#if !defined(RTEMS_SMP) + /* + * On uni-processor configurations the Multiprocessor Resource Sharing + * Protocol is equivalent to the Priority Ceiling Protocol. + */ + if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + attribute_set |= RTEMS_PRIORITY_CEILING | RTEMS_PRIORITY; + } +#endif + the_semaphore = _Semaphore_Allocate(); if ( !the_semaphore ) { @@ -144,6 +160,22 @@ rtems_status_code rtems_semaphore_create( &the_semaphore_attr, count ); +#if defined(RTEMS_SMP) + } else if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + MRSP_Status mrsp_status = _MRSP_Initialize( + &the_semaphore->Core_control.mrsp, + priority_ceiling, + _Thread_Get_executing(), + count != 1 + ); + + if ( mrsp_status != MRSP_SUCCESSFUL ) { + _Semaphore_Free( the_semaphore ); + _Objects_Allocator_unlock(); + + return _Semaphore_Translate_MRSP_status_code( mrsp_status ); + } +#endif } else { /* * It is either simple binary semaphore or a more powerful mutex diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index 6e7c5eafad..52bb14e33c 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -43,6 +43,7 @@ rtems_status_code rtems_semaphore_delete( { Semaphore_Control *the_semaphore; Objects_Locations location; + rtems_attribute attribute_set; _Objects_Allocator_lock(); @@ -50,10 +51,22 @@ rtems_status_code rtems_semaphore_delete( switch ( location ) { case OBJECTS_LOCAL: - if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + attribute_set = the_semaphore->attribute_set; +#if defined(RTEMS_SMP) + if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + MRSP_Status mrsp_status = _MRSP_Destroy( + &the_semaphore->Core_control.mrsp + ); + if ( mrsp_status != MRSP_SUCCESSFUL ) { + _Objects_Put( &the_semaphore->Object ); + _Objects_Allocator_unlock(); + return _Semaphore_Translate_MRSP_status_code( mrsp_status ); + } + } else +#endif + if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) && - !_Attributes_Is_simple_binary_semaphore( - the_semaphore->attribute_set ) ) { + !_Attributes_Is_simple_binary_semaphore( attribute_set ) ) { _Objects_Put( &the_semaphore->Object ); _Objects_Allocator_unlock(); return RTEMS_RESOURCE_IN_USE; @@ -74,7 +87,7 @@ rtems_status_code rtems_semaphore_delete( _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); #if defined(RTEMS_MULTIPROCESSING) - if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) { + if ( _Attributes_Is_global( attribute_set ) ) { _Objects_MP_Close( &_Semaphore_Information, the_semaphore->Object.id ); diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c index f73c92949d..b9b1ec6992 100644 --- a/cpukit/rtems/src/semflush.c +++ b/cpukit/rtems/src/semflush.c @@ -43,12 +43,20 @@ rtems_status_code rtems_semaphore_flush( { Semaphore_Control *the_semaphore; Objects_Locations location; + rtems_attribute attribute_set; the_semaphore = _Semaphore_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: - if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + attribute_set = the_semaphore->attribute_set; +#if defined(RTEMS_SMP) + if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + _Objects_Put( &the_semaphore->Object ); + return RTEMS_NOT_DEFINED; + } else +#endif + if ( !_Attributes_Is_counting_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 c9433ca6d9..3608a00053 100644 --- a/cpukit/rtems/src/semobtain.c +++ b/cpukit/rtems/src/semobtain.c @@ -41,6 +41,7 @@ rtems_status_code rtems_semaphore_obtain( Objects_Locations location; ISR_Level level; Thread_Control *executing; + rtems_attribute attribute_set; bool wait; the_semaphore = _Semaphore_Get_interrupt_disable( id, &location, &level ); @@ -48,8 +49,24 @@ rtems_status_code rtems_semaphore_obtain( case OBJECTS_LOCAL: executing = _Thread_Executing; + attribute_set = the_semaphore->attribute_set; wait = !_Options_Is_no_wait( option_set ); - if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { +#if defined(RTEMS_SMP) + if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + MRSP_Status mrsp_status; + + _ISR_Enable( level ); + mrsp_status = _MRSP_Obtain( + &the_semaphore->Core_control.mrsp, + executing, + wait, + timeout + ); + _Objects_Put_for_get_isr_disable( &the_semaphore->Object ); + return _Semaphore_Translate_MRSP_status_code( mrsp_status ); + } else +#endif + if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { _CORE_mutex_Seize( &the_semaphore->Core_control.mutex, executing, diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c index ff4e792b92..2c4be04c78 100644 --- a/cpukit/rtems/src/semrelease.c +++ b/cpukit/rtems/src/semrelease.c @@ -73,12 +73,24 @@ rtems_status_code rtems_semaphore_release( Objects_Locations location; CORE_mutex_Status mutex_status; CORE_semaphore_Status semaphore_status; + rtems_attribute attribute_set; the_semaphore = _Semaphore_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: - if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + attribute_set = the_semaphore->attribute_set; +#if defined(RTEMS_SMP) + if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { + MRSP_Status mrsp_status = _MRSP_Release( + &the_semaphore->Core_control.mrsp, + _Thread_Get_executing() + ); + _Objects_Put( &the_semaphore->Object ); + return _Semaphore_Translate_MRSP_status_code( mrsp_status ); + } else +#endif + if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) { mutex_status = _CORE_mutex_Surrender( &the_semaphore->Core_control.mutex, id, diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c new file mode 100644 index 0000000000..b5dd1db101 --- /dev/null +++ b/cpukit/rtems/src/semsetpriority.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include <rtems/rtems/semimpl.h> +#include <rtems/rtems/attrimpl.h> +#include <rtems/rtems/tasksimpl.h> +#include <rtems/score/schedulerimpl.h> + +static rtems_status_code _Semaphore_Set_priority( + Semaphore_Control *the_semaphore, + rtems_id scheduler_id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority_p +) +{ + rtems_status_code sc; + rtems_attribute attribute_set = the_semaphore->attribute_set; + rtems_task_priority old_priority; + + new_priority = _RTEMS_tasks_Priority_to_Core( new_priority ); + +#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 ); + + old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index ); + + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority ); + } + + sc = RTEMS_SUCCESSFUL; + } else +#endif + if ( _Attributes_Is_priority_ceiling( attribute_set ) ) { + CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex; + + old_priority = mutex->Attributes.priority_ceiling; + + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + mutex->Attributes.priority_ceiling = new_priority; + } + + sc = RTEMS_SUCCESSFUL; + } else { + old_priority = 0; + + sc = RTEMS_NOT_DEFINED; + } + + *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority ); + + _Objects_Put( &the_semaphore->Object ); + + return sc; +} + +rtems_status_code rtems_semaphore_set_priority( + rtems_id semaphore_id, + rtems_id scheduler_id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +) +{ + Semaphore_Control *the_semaphore; + Objects_Locations location; + + if ( new_priority != RTEMS_CURRENT_PRIORITY && + !_RTEMS_tasks_Priority_is_valid( new_priority ) ) { + return RTEMS_INVALID_PRIORITY; + } + + if ( old_priority == NULL ) { + return RTEMS_INVALID_ADDRESS; + } + + if ( !_Scheduler_Is_id_valid( scheduler_id ) ) { + return RTEMS_INVALID_ID; + } + + the_semaphore = _Semaphore_Get( semaphore_id, &location ); + switch ( location ) { + case OBJECTS_LOCAL: + return _Semaphore_Set_priority( + the_semaphore, + scheduler_id, + new_priority, + old_priority + ); +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} |