summaryrefslogtreecommitdiff
path: root/cpukit/rtems
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/rtems')
-rw-r--r--cpukit/rtems/include/rtems/rtems/semimpl.h1
-rw-r--r--cpukit/rtems/src/semcreate.c41
-rw-r--r--cpukit/rtems/src/semdelete.c2
-rw-r--r--cpukit/rtems/src/semflush.c1
-rw-r--r--cpukit/rtems/src/semobtain.c10
-rw-r--r--cpukit/rtems/src/semrelease.c12
-rw-r--r--cpukit/rtems/src/semsetpriority.c84
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 );