summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/coremutexsurrender.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-30 06:59:55 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-30 16:16:23 +0200
commit0b713f8940d90b480f8cd36663c11aa0688587d8 (patch)
treec71a01748c3749e0243518b486c2bb32a1c67df1 /cpukit/score/src/coremutexsurrender.c
parentscore: Rework CORE priority ceiling mutex (diff)
downloadrtems-0b713f8940d90b480f8cd36663c11aa0688587d8.tar.bz2
score: Rework CORE inherit priority mutex
Provide dedicated seize and surrender methods for inherit priority mutexes. This eliminates CORE_mutex_Attributes.
Diffstat (limited to '')
-rw-r--r--cpukit/score/src/coremutexsurrender.c127
1 files changed, 22 insertions, 105 deletions
diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c
index 5075e204c9..6604be89da 100644
--- a/cpukit/score/src/coremutexsurrender.c
+++ b/cpukit/score/src/coremutexsurrender.c
@@ -18,141 +18,58 @@
#include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/score/isr.h>
#include <rtems/score/coremuteximpl.h>
-#include <rtems/score/thread.h>
-Status_Control _CORE_mutex_Surrender(
+Status_Control _CORE_mutex_Surrender_slow(
CORE_mutex_Control *the_mutex,
+ Thread_Control *executing,
+ Thread_queue_Heads *heads,
+ bool keep_priority,
Thread_queue_Context *queue_context
)
{
- Thread_Control *the_thread;
- Thread_Control *holder;
+ if ( heads != NULL ) {
+ const Thread_queue_Operations *operations;
+ Thread_Control *new_owner;
+ bool unblock;
- holder = the_mutex->holder;
+ operations = CORE_MUTEX_TQ_OPERATIONS;
+ new_owner = ( *operations->first )( heads );
- /*
- * Priority Ceiling or Priority Inheritance mutexes must be released by the
- * thread which acquired them.
- */
- if ( !_Thread_Is_executing( holder ) ) {
- _ISR_lock_ISR_enable( &queue_context->Lock_context );
- return STATUS_NOT_OWNER;
- }
-
- _CORE_mutex_Acquire_critical( the_mutex, queue_context );
-
- /* XXX already unlocked -- not right status */
-
- if ( !the_mutex->nest_count ) {
- _CORE_mutex_Release( the_mutex, queue_context );
- return STATUS_SUCCESSFUL;
- }
-
- the_mutex->nest_count--;
+ _CORE_mutex_Set_owner( the_mutex, new_owner );
- if ( the_mutex->nest_count != 0 ) {
- /*
- * All error checking is on the locking side, so if the lock was
- * allowed to acquired multiple times, then we should just deal with
- * that. The RTEMS_DEBUG is just a validation.
- */
- #if defined(RTEMS_DEBUG)
- switch ( the_mutex->Attributes.lock_nesting_behavior ) {
- case CORE_MUTEX_NESTING_ACQUIRES:
- _CORE_mutex_Release( the_mutex, queue_context );
- return STATUS_SUCCESSFUL;
- #if defined(RTEMS_POSIX_API)
- case CORE_MUTEX_NESTING_IS_ERROR:
- /* should never occur */
- _CORE_mutex_Release( the_mutex, queue_context );
- return STATUS_NESTING_NOT_ALLOWED;
- #endif
- }
- #else
- _CORE_mutex_Release( the_mutex, queue_context );
- /* must be CORE_MUTEX_NESTING_ACQUIRES or we wouldn't be here */
- return STATUS_SUCCESSFUL;
- #endif
- }
-
- /*
- * Formally release the mutex before possibly transferring it to a
- * blocked thread.
- */
- holder->resource_count--;
- the_mutex->holder = NULL;
-
- /*
- * Now we check if another thread was waiting for this mutex. If so,
- * transfer the mutex to that thread.
- */
- if (
- ( the_thread = _Thread_queue_First_locked(
- &the_mutex->Wait_queue,
- CORE_MUTEX_TQ_OPERATIONS
- )
- )
- ) {
- bool unblock;
-
- the_mutex->holder = the_thread;
- the_mutex->nest_count = 1;
-
- /*
- * 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->Wait_queue.Queue,
- CORE_MUTEX_TQ_OPERATIONS,
- the_thread,
+ operations,
+ new_owner,
queue_context
);
#if defined(RTEMS_MULTIPROCESSING)
- if ( _Objects_Is_local_id( the_thread->Object.id ) )
+ if ( _Objects_Is_local_id( new_owner->Object.id ) )
#endif
{
- the_thread->resource_count++;
- _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
+ ++new_owner->resource_count;
+ _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, new_owner );
}
_Thread_queue_Unblock_critical(
unblock,
&the_mutex->Wait_queue.Queue,
- the_thread,
+ new_owner,
&queue_context->Lock_context
);
} else {
_CORE_mutex_Release( the_mutex, queue_context );
}
- /*
- * 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( holder ) ) {
- /*
- * Ensure that the holder resource count is visible to all other processors
- * and that we read the latest priority restore hint.
- */
- _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
-
- if ( holder->priority_restore_hint ) {
- Per_CPU_Control *cpu_self;
+ if ( !keep_priority ) {
+ Per_CPU_Control *cpu_self;
- cpu_self = _Thread_Dispatch_disable();
- _Thread_Restore_priority( holder );
- _Thread_Dispatch_enable( cpu_self );
- }
+ cpu_self = _Thread_Dispatch_disable();
+ _Thread_Restore_priority( executing );
+ _Thread_Dispatch_enable( cpu_self );
}
- _CORE_mutex_Restore_priority( holder );
return STATUS_SUCCESSFUL;
}