forked from Imagelibrary/rtems
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:
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user