summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/coremuteximpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/include/rtems/score/coremuteximpl.h')
-rw-r--r--cpukit/score/include/rtems/score/coremuteximpl.h146
1 files changed, 69 insertions, 77 deletions
diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
index 25094a49df..a30d1a880e 100644
--- a/cpukit/score/include/rtems/score/coremuteximpl.h
+++ b/cpukit/score/include/rtems/score/coremuteximpl.h
@@ -124,32 +124,6 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
}
-RTEMS_INLINE_ROUTINE void _CORE_mutex_Restore_priority(
- Thread_Control *executing
-)
-{
- /*
- * Whether or not someone is waiting for the mutex, an
- * inherited priority must be lowered if this is the last
- * mutex (i.e. resource) this task has.
- */
- if ( !_Thread_Owns_resources( executing ) ) {
- /*
- * Ensure that the executing resource count is visible to all other
- * processors and that we read the latest priority restore hint.
- */
- _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
-
- if ( executing->priority_restore_hint ) {
- Per_CPU_Control *cpu_self;
-
- cpu_self = _Thread_Dispatch_disable();
- _Thread_Restore_priority( executing );
- _Thread_Dispatch_enable( cpu_self );
- }
- }
-}
-
RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
CORE_recursive_mutex_Control *the_mutex
)
@@ -212,7 +186,6 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender(
{
unsigned int nest_level;
Thread_queue_Heads *heads;
- bool keep_priority;
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
@@ -232,29 +205,19 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender(
--executing->resource_count;
_CORE_mutex_Set_owner( &the_mutex->Mutex, NULL );
- /*
- * Ensure that the owner resource count is visible to all other
- * processors and that we read the latest priority restore
- * hint.
- */
- _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
-
heads = the_mutex->Mutex.Wait_queue.Queue.heads;
- keep_priority = _Thread_Owns_resources( executing )
- || !executing->priority_restore_hint;
- if ( heads == NULL && keep_priority ) {
+ if ( heads == NULL ) {
_CORE_mutex_Release( &the_mutex->Mutex, queue_context );
return STATUS_SUCCESSFUL;
}
_Thread_queue_Surrender(
&the_mutex->Mutex.Wait_queue.Queue,
- CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS,
heads,
executing,
- keep_priority,
- queue_context
+ queue_context,
+ CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS
);
return STATUS_SUCCESSFUL;
}
@@ -349,7 +312,7 @@ RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize(
)
{
_CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
- the_mutex->priority_ceiling = priority_ceiling;
+ _Priority_Node_initialize( &the_mutex->Priority_ceiling, priority_ceiling );
#if defined(RTEMS_SMP)
the_mutex->scheduler = scheduler;
#endif
@@ -369,17 +332,34 @@ _CORE_ceiling_mutex_Get_scheduler(
RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Set_priority(
CORE_ceiling_mutex_Control *the_mutex,
- Priority_Control priority_ceiling
+ Priority_Control priority_ceiling,
+ Thread_queue_Context *queue_context
)
{
- the_mutex->priority_ceiling = priority_ceiling;
+ Thread_Control *owner;
+
+ owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
+
+ if ( owner != NULL ) {
+ _Thread_Wait_acquire( owner, queue_context );
+ _Thread_Priority_change(
+ owner,
+ &the_mutex->Priority_ceiling,
+ priority_ceiling,
+ false,
+ queue_context
+ );
+ _Thread_Wait_release( owner, queue_context );
+ } else {
+ the_mutex->Priority_ceiling.priority = priority_ceiling;
+ }
}
RTEMS_INLINE_ROUTINE Priority_Control _CORE_ceiling_mutex_Get_priority(
const CORE_ceiling_mutex_Control *the_mutex
)
{
- return the_mutex->priority_ceiling;
+ return the_mutex->Priority_ceiling.priority;
}
RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
@@ -388,31 +368,38 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
Thread_queue_Context *queue_context
)
{
- Priority_Control priority_ceiling;
- Priority_Control current_priority;
+ ISR_lock_Context lock_context;
+ Scheduler_Node *own_node;
Per_CPU_Control *cpu_self;
- priority_ceiling = the_mutex->priority_ceiling;
- current_priority = _Thread_Get_priority( owner );
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ _Thread_Wait_acquire_default_critical( owner, &lock_context );
- if ( current_priority < priority_ceiling ) {
+ own_node = _Thread_Scheduler_get_own_node( owner );
+
+ if (
+ own_node->Wait.Priority.Node.priority
+ < the_mutex->Priority_ceiling.priority
+ ) {
+ _Thread_Wait_release_default_critical( owner, &lock_context );
_CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
return STATUS_MUTEX_CEILING_VIOLATED;
}
_CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
++owner->resource_count;
-
- if ( current_priority == priority_ceiling ) {
- _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
- return STATUS_SUCCESSFUL;
- }
+ _Thread_Priority_add(
+ owner,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_Wait_release_default_critical( owner, &lock_context );
cpu_self = _Thread_Dispatch_disable_critical(
&queue_context->Lock_context.Lock_context
);
_CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
- _Thread_Raise_priority( owner, priority_ceiling );
+ _Thread_Priority_update( queue_context );
_Thread_Dispatch_enable( cpu_self );
return STATUS_SUCCESSFUL;
}
@@ -472,8 +459,10 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Surrender(
Thread_queue_Context *queue_context
)
{
- unsigned int nest_level;
- Thread_Control *new_owner;
+ unsigned int nest_level;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu_self;
+ Thread_Control *new_owner;
_CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
@@ -492,47 +481,50 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Surrender(
--executing->resource_count;
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ _Thread_Wait_acquire_default_critical( executing, &lock_context );
+ _Thread_Priority_remove(
+ executing,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_Wait_release_default_critical( executing, &lock_context );
+
new_owner = _Thread_queue_First_locked(
&the_mutex->Recursive.Mutex.Wait_queue,
CORE_MUTEX_TQ_OPERATIONS
);
_CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, new_owner );
- if ( new_owner != NULL ) {
- bool unblock;
-
- /*
- * We must extract the thread now since this will restore its default
- * thread lock. This is necessary to avoid a deadlock in the
- * _Thread_Change_priority() below due to a recursive thread queue lock
- * acquire.
- */
- unblock = _Thread_queue_Extract_locked(
- &the_mutex->Recursive.Mutex.Wait_queue.Queue,
- CORE_MUTEX_TQ_OPERATIONS,
- new_owner,
- queue_context
- );
+ cpu_self = _Thread_Dispatch_disable_critical(
+ &queue_context->Lock_context.Lock_context
+ );
+ if ( new_owner != NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
if ( _Objects_Is_local_id( new_owner->Object.id ) )
#endif
{
++new_owner->resource_count;
- _Thread_Raise_priority( new_owner, the_mutex->priority_ceiling );
+ _Thread_Priority_add(
+ new_owner,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
}
- _Thread_queue_Unblock_critical(
- unblock,
+ _Thread_queue_Extract_critical(
&the_mutex->Recursive.Mutex.Wait_queue.Queue,
+ CORE_MUTEX_TQ_OPERATIONS,
new_owner,
- &queue_context->Lock_context.Lock_context
+ queue_context
);
} else {
_CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
}
- _CORE_mutex_Restore_priority( executing );
+ _Thread_Priority_update( queue_context );
+ _Thread_Dispatch_enable( cpu_self );
return STATUS_SUCCESSFUL;
}