score: Add _Thread_queue_Surrender()

Add _Thread_queue_Surrender() to unify the mutex surrender procedures
which involve a thread queue operation.
This commit is contained in:
Sebastian Huber
2016-08-11 08:32:49 +02:00
parent 03c1038edb
commit fef3ea9e87
6 changed files with 86 additions and 134 deletions

View File

@@ -183,7 +183,6 @@ libscore_a_SOURCES += src/coremsg.c src/coremsgbroadcast.c \
## CORE_MUTEX_C_FILES
libscore_a_SOURCES += src/coremutexseize.c
libscore_a_SOURCES += src/coremutexsurrender.c
## CORE_PERCPU_C_FILES
libscore_a_SOURCES += src/percpu.c

View File

@@ -114,14 +114,6 @@ Status_Control _CORE_mutex_Seize_no_protocol_slow(
Thread_queue_Context *queue_context
);
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
);
RTEMS_INLINE_ROUTINE void _CORE_mutex_Set_owner(
CORE_mutex_Control *the_mutex,
Thread_Control *owner
@@ -262,13 +254,15 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender(
return STATUS_SUCCESSFUL;
}
return _CORE_mutex_Surrender_slow(
&the_mutex->Mutex,
executing,
_Thread_queue_Surrender(
&the_mutex->Mutex.Wait_queue.Queue,
CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS,
heads,
executing,
keep_priority,
queue_context
);
return STATUS_SUCCESSFUL;
}
RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_no_protocol(

View File

@@ -711,6 +711,33 @@ void _Thread_queue_Extract_with_proxy(
Thread_Control *the_thread
);
/**
* @brief Surrenders the thread queue previously owned by the thread to the
* first enqueued thread if it exists.
*
* The owner of the thread queue must be set to NULL by the caller.
*
* This function releases the thread queue lock. In addition it performs a
* thread dispatch if necessary.
*
* @param[in] queue The actual thread queue.
* @param[in] operations The thread queue operations.
* @param[in] heads The thread queue heads.
* @param[in] previous_owner The previous owner thread surrendering the thread
* queue.
* @param[in] keep_priority Indicates if the previous owner thread should keep
* its current priority.
* @param[in] queue_context The thread queue context of the lock acquire.
*/
void _Thread_queue_Surrender(
Thread_queue_Queue *queue,
const Thread_queue_Operations *operations,
Thread_queue_Heads *heads,
Thread_Control *previous_owner,
bool keep_priority,
Thread_queue_Context *queue_context
);
RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_empty(
const Thread_queue_Queue *queue
)

View File

@@ -1,75 +0,0 @@
/**
* @file
*
* @brief Surrender the Mutex
* @ingroup ScoreMutex
*/
/*
* COPYRIGHT (c) 1989-2006.
* On-Line Applications Research Corporation (OAR).
*
* 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/score/coremuteximpl.h>
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
)
{
if ( heads != NULL ) {
const Thread_queue_Operations *operations;
Thread_Control *new_owner;
bool unblock;
operations = CORE_MUTEX_TQ_OPERATIONS;
new_owner = ( *operations->first )( heads );
_CORE_mutex_Set_owner( the_mutex, new_owner );
#if defined(RTEMS_MULTIPROCESSING)
if ( _Objects_Is_local_id( new_owner->Object.id ) )
#endif
{
++new_owner->resource_count;
_Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, new_owner );
}
unblock = _Thread_queue_Extract_locked(
&the_mutex->Wait_queue.Queue,
operations,
new_owner,
queue_context
);
_Thread_queue_Unblock_critical(
unblock,
&the_mutex->Wait_queue.Queue,
new_owner,
&queue_context->Lock_context
);
} else {
_CORE_mutex_Release( the_mutex, queue_context );
}
if ( !keep_priority ) {
Per_CPU_Control *cpu_self;
cpu_self = _Thread_Dispatch_disable();
_Thread_Restore_priority( executing );
_Thread_Dispatch_enable( cpu_self );
}
return STATUS_SUCCESSFUL;
}

View File

@@ -121,50 +121,6 @@ static void _Mutex_Acquire_slow(
);
}
static void _Mutex_Release_slow(
Mutex_Control *mutex,
Thread_Control *executing,
Thread_queue_Heads *heads,
bool keep_priority,
Thread_queue_Context *queue_context
)
{
if (heads != NULL) {
const Thread_queue_Operations *operations;
Thread_Control *first;
bool unblock;
operations = MUTEX_TQ_OPERATIONS;
first = ( *operations->first )( heads );
mutex->Queue.Queue.owner = first;
++first->resource_count;
_Thread_queue_Boost_priority( &mutex->Queue.Queue, first );
unblock = _Thread_queue_Extract_locked(
&mutex->Queue.Queue,
operations,
first,
queue_context
);
_Thread_queue_Unblock_critical(
unblock,
&mutex->Queue.Queue,
first,
&queue_context->Lock_context
);
} else {
_Mutex_Queue_release( mutex, queue_context );
}
if ( !keep_priority ) {
Per_CPU_Control *cpu_self;
cpu_self = _Thread_Dispatch_disable();
_Thread_Restore_priority( executing );
_Thread_Dispatch_enable( cpu_self );
}
}
static void _Mutex_Release_critical(
Mutex_Control *mutex,
Thread_Control *executing,
@@ -192,10 +148,11 @@ static void _Mutex_Release_critical(
if ( __predict_true( heads == NULL && keep_priority ) ) {
_Mutex_Queue_release( mutex, queue_context );
} else {
_Mutex_Release_slow(
mutex,
executing,
_Thread_queue_Surrender(
&mutex->Queue.Queue,
MUTEX_TQ_OPERATIONS,
heads,
executing,
keep_priority,
queue_context
);

View File

@@ -568,6 +568,56 @@ void _Thread_queue_Extract( Thread_Control *the_thread )
}
}
void _Thread_queue_Surrender(
Thread_queue_Queue *queue,
const Thread_queue_Operations *operations,
Thread_queue_Heads *heads,
Thread_Control *previous_owner,
bool keep_priority,
Thread_queue_Context *queue_context
)
{
if ( heads != NULL ) {
Thread_Control *new_owner;
bool unblock;
new_owner = ( *operations->first )( heads );
queue->owner = new_owner;
#if defined(RTEMS_MULTIPROCESSING)
if ( _Objects_Is_local_id( new_owner->Object.id ) )
#endif
{
++new_owner->resource_count;
_Thread_queue_Boost_priority( queue, new_owner );
}
unblock = _Thread_queue_Extract_locked(
queue,
operations,
new_owner,
queue_context
);
_Thread_queue_Unblock_critical(
unblock,
queue,
new_owner,
&queue_context->Lock_context
);
} else {
_Thread_queue_Queue_release( queue, &queue_context->Lock_context );
}
if ( !keep_priority ) {
Per_CPU_Control *cpu_self;
cpu_self = _Thread_Dispatch_disable();
_Thread_Restore_priority( previous_owner );
_Thread_Dispatch_enable( cpu_self );
}
}
Thread_Control *_Thread_queue_Do_dequeue(
Thread_queue_Control *the_thread_queue,
const Thread_queue_Operations *operations