score: Introduce Thread_queue_Queue

Separate the thread queue heads and lock from the operations.  This
enables the support for light weight objects which only support one
queuing discipline.
This commit is contained in:
Sebastian Huber
2015-06-24 11:05:39 +02:00
parent 579f16efd7
commit e273501233
20 changed files with 241 additions and 169 deletions

View File

@@ -140,7 +140,7 @@ int killinfo(
/* XXX violation of visibility -- need to define thread queue support */ /* XXX violation of visibility -- need to define thread queue support */
the_chain = &_POSIX_signals_Wait_queue.Queues.Fifo; the_chain = &_POSIX_signals_Wait_queue.Queue.Heads.Fifo;
for ( the_node = _Chain_First( the_chain ); for ( the_node = _Chain_First( the_chain );
!_Chain_Is_tail( the_chain, the_node ) ; !_Chain_Is_tail( the_chain, the_node ) ;

View File

@@ -156,7 +156,8 @@ int sigtimedwait(
executing->Wait.option = *set; executing->Wait.option = *set;
executing->Wait.return_argument = the_info; executing->Wait.return_argument = the_info;
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&_POSIX_signals_Wait_queue, &_POSIX_signals_Wait_queue.Queue,
_POSIX_signals_Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL,
interval, interval,

View File

@@ -599,7 +599,8 @@ RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
); );
_Thread_queue_Extract_critical( _Thread_queue_Extract_critical(
&the_message_queue->Wait_queue, &the_message_queue->Wait_queue.Queue,
the_message_queue->Wait_queue.operations,
the_thread, the_thread,
lock_context lock_context
); );

View File

@@ -140,7 +140,8 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
#endif #endif
_Thread_queue_Extract_critical( _Thread_queue_Extract_critical(
&the_semaphore->Wait_queue, &the_semaphore->Wait_queue.Queue,
the_semaphore->Wait_queue.operations,
the_thread, the_thread,
lock_context lock_context
); );
@@ -263,7 +264,8 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize(
executing->Wait.id = id; executing->Wait.id = id;
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_semaphore->Wait_queue, &the_semaphore->Wait_queue.Queue,
the_semaphore->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_SEMAPHORE, STATES_WAITING_FOR_SEMAPHORE,
timeout, timeout,

View File

@@ -329,7 +329,7 @@ typedef struct {
* *
* @see _Thread_Lock_set() and _Thread_Wait_set_queue(). * @see _Thread_Lock_set() and _Thread_Wait_set_queue().
*/ */
Thread_queue_Control *queue; Thread_queue_Queue *queue;
/** /**
* @brief This field contains several flags used to control the wait class * @brief This field contains several flags used to control the wait class

View File

@@ -1368,8 +1368,8 @@ RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change(
* @see _Thread_Lock_set(). * @see _Thread_Lock_set().
*/ */
RTEMS_INLINE_ROUTINE void _Thread_Wait_set_queue( RTEMS_INLINE_ROUTINE void _Thread_Wait_set_queue(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_queue_Control *new_queue Thread_queue_Queue *new_queue
) )
{ {
the_thread->Wait.queue = new_queue; the_thread->Wait.queue = new_queue;

View File

@@ -41,64 +41,85 @@ extern "C" {
typedef struct Thread_Control Thread_Control; typedef struct Thread_Control Thread_Control;
typedef struct Thread_queue_Control Thread_queue_Control; typedef struct {
/** This union contains the data structures used to manage the blocked
* set of tasks which varies based upon the discipline.
*/
union {
/** This is the FIFO discipline list. */
Chain_Control Fifo;
/** This is the set of threads for priority discipline waiting. */
RBTree_Control Priority;
} Heads;
/**
* @brief Lock to protect this thread queue.
*
* It may be used to protect additional state of the object embedding this
* thread queue.
*
* @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
* _Thread_queue_Release().
*/
ISR_LOCK_MEMBER( Lock )
} Thread_queue_Queue;
/** /**
* @brief Thread queue priority change operation. * @brief Thread queue priority change operation.
* *
* @param[in] the_thread The thread. * @param[in] the_thread The thread.
* @param[in] new_priority The new priority value. * @param[in] new_priority The new priority value.
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* *
* @see Thread_queue_Operations. * @see Thread_queue_Operations.
*/ */
typedef void ( *Thread_queue_Priority_change_operation )( typedef void ( *Thread_queue_Priority_change_operation )(
Thread_Control *the_thread, Thread_Control *the_thread,
Priority_Control new_priority, Priority_Control new_priority,
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
); );
/** /**
* @brief Thread queue initialize operation. * @brief Thread queue initialize operation.
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* *
* @see _Thread_Wait_set_operations(). * @see _Thread_Wait_set_operations().
*/ */
typedef void ( *Thread_queue_Initialize_operation )( typedef void ( *Thread_queue_Initialize_operation )(
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
); );
/** /**
* @brief Thread queue enqueue operation. * @brief Thread queue enqueue operation.
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* @param[in] the_thread The thread to enqueue on the queue. * @param[in] the_thread The thread to enqueue on the queue.
* *
* @see _Thread_Wait_set_operations(). * @see _Thread_Wait_set_operations().
*/ */
typedef void ( *Thread_queue_Enqueue_operation )( typedef void ( *Thread_queue_Enqueue_operation )(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
); );
/** /**
* @brief Thread queue extract operation. * @brief Thread queue extract operation.
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* @param[in] the_thread The thread to extract from the thread queue. * @param[in] the_thread The thread to extract from the thread queue.
* *
* @see _Thread_Wait_set_operations(). * @see _Thread_Wait_set_operations().
*/ */
typedef void ( *Thread_queue_Extract_operation )( typedef void ( *Thread_queue_Extract_operation )(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
); );
/** /**
* @brief Thread queue first operation. * @brief Thread queue first operation.
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* *
* @retval NULL No thread is present on the thread queue. * @retval NULL No thread is present on the thread queue.
* @retval first The first thread of the thread queue according to the insert * @retval first The first thread of the thread queue according to the insert
@@ -107,7 +128,7 @@ typedef void ( *Thread_queue_Extract_operation )(
* @see _Thread_Wait_set_operations(). * @see _Thread_Wait_set_operations().
*/ */
typedef Thread_Control *( *Thread_queue_First_operation )( typedef Thread_Control *( *Thread_queue_First_operation )(
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
); );
/** /**
@@ -168,33 +189,17 @@ typedef enum {
* This is the structure used to manage sets of tasks which are blocked * This is the structure used to manage sets of tasks which are blocked
* waiting to acquire a resource. * waiting to acquire a resource.
*/ */
struct Thread_queue_Control { typedef struct {
/** This union contains the data structures used to manage the blocked /**
* set of tasks which varies based upon the discipline. * @brief The actual thread queue.
*/ */
union { Thread_queue_Queue Queue;
/** This is the FIFO discipline list. */
Chain_Control Fifo;
/** This is the set of threads for priority discipline waiting. */
RBTree_Control Priority;
} Queues;
/** /**
* @brief The operations for this thread queue. * @brief The operations for the actual thread queue.
*/ */
const Thread_queue_Operations *operations; const Thread_queue_Operations *operations;
} Thread_queue_Control;
/**
* @brief Lock to protect this thread queue.
*
* It may be used to protect additional state of the object embedding this
* thread queue.
*
* @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
* _Thread_queue_Release().
*/
ISR_LOCK_MEMBER( Lock )
};
/**@}*/ /**@}*/

View File

@@ -33,12 +33,31 @@ extern "C" {
*/ */
/**@{*/ /**@{*/
RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_acquire_critical(
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
)
{
_ISR_lock_Acquire( &queue->Lock, lock_context );
}
RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
Thread_queue_Queue *queue,
ISR_lock_Context *lock_context
)
{
_ISR_lock_Release_and_ISR_enable( &queue->Lock, lock_context );
}
RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical( RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Control *the_thread_queue,
ISR_lock_Context *lock_context ISR_lock_Context *lock_context
) )
{ {
_ISR_lock_Acquire( &the_thread_queue->Lock, lock_context ); _Thread_queue_Queue_acquire_critical(
&the_thread_queue->Queue,
lock_context
);
} }
RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire( RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
@@ -55,7 +74,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
ISR_lock_Context *lock_context ISR_lock_Context *lock_context
) )
{ {
_ISR_lock_Release_and_ISR_enable( &the_thread_queue->Lock, lock_context ); _Thread_queue_Queue_release( &the_thread_queue->Queue, lock_context );
} }
/** /**
@@ -120,7 +139,8 @@ Thread_Control *_Thread_queue_Dequeue(
* _Thread_queue_Release( &mutex->Queue, &lock_context ); * _Thread_queue_Release( &mutex->Queue, &lock_context );
* } else { * } else {
* _Thread_queue_Enqueue_critical( * _Thread_queue_Enqueue_critical(
* &mutex->Queue, * &mutex->Queue.Queue,
* mutex->Queue.operations,
* executing, * executing,
* STATES_WAITING_FOR_MUTEX, * STATES_WAITING_FOR_MUTEX,
* WATCHDOG_NO_TIMEOUT, * WATCHDOG_NO_TIMEOUT,
@@ -131,7 +151,8 @@ Thread_Control *_Thread_queue_Dequeue(
* } * }
* @endcode * @endcode
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* @param[in] operations The thread queue operations.
* @param[in] the_thread The thread to enqueue. * @param[in] the_thread The thread to enqueue.
* @param[in] state The new state of the thread. * @param[in] state The new state of the thread.
* @param[in] timeout Interval to wait. Use WATCHDOG_NO_TIMEOUT to block * @param[in] timeout Interval to wait. Use WATCHDOG_NO_TIMEOUT to block
@@ -140,12 +161,13 @@ Thread_Control *_Thread_queue_Dequeue(
* @param[in] lock_context The lock context of the lock acquire. * @param[in] lock_context The lock context of the lock acquire.
*/ */
void _Thread_queue_Enqueue_critical( void _Thread_queue_Enqueue_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, const Thread_queue_Operations *operations,
States_Control state, Thread_Control *the_thread,
Watchdog_Interval timeout, States_Control state,
uint32_t timeout_code, Watchdog_Interval timeout,
ISR_lock_Context *lock_context uint32_t timeout_code,
ISR_lock_Context *lock_context
); );
/** /**
@@ -164,7 +186,8 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
_Thread_queue_Acquire( the_thread_queue, &lock_context ); _Thread_queue_Acquire( the_thread_queue, &lock_context );
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
the_thread_queue, &the_thread_queue->Queue,
the_thread_queue->operations,
the_thread, the_thread,
state, state,
timeout, timeout,
@@ -180,12 +203,14 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
* The caller must be the owner of the thread queue lock. The thread queue * The caller must be the owner of the thread queue lock. The thread queue
* lock is not released. * lock is not released.
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* @param[in] operations The thread queue operations.
* @param[in] the_thread The thread to extract. * @param[in] the_thread The thread to extract.
*/ */
void _Thread_queue_Extract_locked( void _Thread_queue_Extract_locked(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread const Thread_queue_Operations *operations,
Thread_Control *the_thread
); );
/** /**
@@ -196,14 +221,14 @@ void _Thread_queue_Extract_locked(
* thread queue lock is released and an unblock is necessary. Thread * thread queue lock is released and an unblock is necessary. Thread
* dispatching is enabled once the sequence to unblock the thread is complete. * dispatching is enabled once the sequence to unblock the thread is complete.
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* @param[in] the_thread The thread to extract. * @param[in] the_thread The thread to extract.
* @param[in] lock_context The lock context of the lock acquire. * @param[in] lock_context The lock context of the lock acquire.
*/ */
void _Thread_queue_Unblock_critical( void _Thread_queue_Unblock_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, Thread_Control *the_thread,
ISR_lock_Context *lock_context ISR_lock_Context *lock_context
); );
/** /**
@@ -238,21 +263,24 @@ void _Thread_queue_Unblock_critical(
* *
* if ( first != NULL ) { * if ( first != NULL ) {
* _Thread_queue_Extract_critical( * _Thread_queue_Extract_critical(
* &mutex->Queue, * &mutex->Queue.Queue,
* mutex->Queue.operations,
* first, * first,
* &lock_context * &lock_context
* ); * );
* } * }
* @endcode * @endcode
* *
* @param[in] the_thread_queue The thread queue. * @param[in] queue The actual thread queue.
* @param[in] operations The thread queue operations.
* @param[in] the_thread The thread to extract. * @param[in] the_thread The thread to extract.
* @param[in] lock_context The lock context of the lock acquire. * @param[in] lock_context The lock context of the lock acquire.
*/ */
void _Thread_queue_Extract_critical( void _Thread_queue_Extract_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, const Thread_queue_Operations *operations,
ISR_lock_Context *lock_context Thread_Control *the_thread,
ISR_lock_Context *lock_context
); );
/** /**
@@ -294,7 +322,7 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
Thread_queue_Control *the_thread_queue Thread_queue_Control *the_thread_queue
) )
{ {
return ( *the_thread_queue->operations->first )( the_thread_queue ); return ( *the_thread_queue->operations->first )( &the_thread_queue->Queue );
} }
/** /**
@@ -346,31 +374,43 @@ void _Thread_queue_Initialize(
#if defined(RTEMS_SMP) #if defined(RTEMS_SMP)
#define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
.Queues = { \ .Queue = { \
.Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queues.Fifo ) \ .Heads = { \
}, \ .Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queue.Heads.Fifo ) \
.operations = &_Thread_queue_Operations_FIFO, \ }, \
.Lock = ISR_LOCK_INITIALIZER( name ) \ .Lock = ISR_LOCK_INITIALIZER( name ), \
}
#define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \
.Queues = { \
.Priority = RBTREE_INITIALIZER_EMPTY( designator.Queues.Priority ) \
}, \
.operations = &_Thread_queue_Operations_priority, \
.Lock = ISR_LOCK_INITIALIZER( name ) \
}
#else
#define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
.Queues = { \
.Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queues.Fifo ) \
}, \ }, \
.operations = &_Thread_queue_Operations_FIFO \ .operations = &_Thread_queue_Operations_FIFO \
} }
#define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \
.Queues = { \ .Queue = { \
.Priority = RBTREE_INITIALIZER_EMPTY( designator.Queues.Priority ) \ .Heads = { \
.Priority = RBTREE_INITIALIZER_EMPTY( \
designator.Queue.Heads.Priority \
) \
}, \
.Lock = ISR_LOCK_INITIALIZER( name ), \
}, \
.operations = &_Thread_queue_Operations_priority \
}
#else
#define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
.Queue = { \
.Heads = { \
.Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queue.Heads.Fifo ) \
} \
}, \
.operations = &_Thread_queue_Operations_FIFO \
}
#define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \
.Queue = { \
.Heads = { \
.Priority = RBTREE_INITIALIZER_EMPTY( \
designator.Queue.Heads.Priority \
) \
} \
}, \ }, \
.operations = &_Thread_queue_Operations_priority \ .operations = &_Thread_queue_Operations_priority \
} }
@@ -380,7 +420,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
Thread_queue_Control *the_thread_queue Thread_queue_Control *the_thread_queue
) )
{ {
_ISR_lock_Destroy( &the_thread_queue->Lock ); _ISR_lock_Destroy( &the_thread_queue->Queue.Lock );
} }
/** /**

View File

@@ -50,7 +50,8 @@ void _CORE_barrier_Wait(
executing->Wait.id = id; executing->Wait.id = id;
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_barrier->Wait_queue, &the_barrier->Wait_queue.Queue,
the_barrier->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_BARRIER, STATES_WAITING_FOR_BARRIER,
timeout, timeout,

View File

@@ -107,7 +107,8 @@ void _CORE_message_queue_Seize(
_CORE_message_queue_Get_message_priority( the_message ) _CORE_message_queue_Get_message_priority( the_message )
); );
_Thread_queue_Extract_critical( _Thread_queue_Extract_critical(
&the_message_queue->Wait_queue, &the_message_queue->Wait_queue.Queue,
the_message_queue->Wait_queue.operations,
the_thread, the_thread,
lock_context lock_context
); );
@@ -131,7 +132,8 @@ void _CORE_message_queue_Seize(
/* Wait.count will be filled in with the message priority */ /* Wait.count will be filled in with the message priority */
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_message_queue->Wait_queue, &the_message_queue->Wait_queue.Queue,
the_message_queue->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_MESSAGE, STATES_WAITING_FOR_MESSAGE,
timeout, timeout,

View File

@@ -132,7 +132,8 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
executing->Wait.count = submit_type; executing->Wait.count = submit_type;
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_message_queue->Wait_queue, &the_message_queue->Wait_queue.Queue,
the_message_queue->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_MESSAGE, STATES_WAITING_FOR_MESSAGE,
timeout, timeout,

View File

@@ -83,7 +83,8 @@ void _CORE_mutex_Seize_interrupt_blocking(
} }
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_mutex->Wait_queue, &the_mutex->Wait_queue.Queue,
the_mutex->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_MUTEX, STATES_WAITING_FOR_MUTEX,
timeout, timeout,

View File

@@ -185,7 +185,11 @@ CORE_mutex_Status _CORE_mutex_Surrender(
* _Thread_Change_priority() below due to a recursive thread queue lock * _Thread_Change_priority() below due to a recursive thread queue lock
* acquire. * acquire.
*/ */
_Thread_queue_Extract_locked( &the_mutex->Wait_queue, the_thread ); _Thread_queue_Extract_locked(
&the_mutex->Wait_queue.Queue,
the_mutex->Wait_queue.operations,
the_thread
);
#if defined(RTEMS_MULTIPROCESSING) #if defined(RTEMS_MULTIPROCESSING)
_Thread_Dispatch_disable(); _Thread_Dispatch_disable();
@@ -216,7 +220,7 @@ CORE_mutex_Status _CORE_mutex_Surrender(
} }
_Thread_queue_Unblock_critical( _Thread_queue_Unblock_critical(
&the_mutex->Wait_queue, &the_mutex->Wait_queue.Queue,
the_thread, the_thread,
lock_context lock_context
); );

View File

@@ -83,7 +83,8 @@ void _CORE_RWLock_Obtain_for_reading(
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL; executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_rwlock->Wait_queue, &the_rwlock->Wait_queue.Queue,
the_rwlock->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_RWLOCK, STATES_WAITING_FOR_RWLOCK,
timeout, timeout,

View File

@@ -73,7 +73,8 @@ void _CORE_RWLock_Obtain_for_writing(
executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL; executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
_Thread_queue_Enqueue_critical( _Thread_queue_Enqueue_critical(
&the_rwlock->Wait_queue, &the_rwlock->Wait_queue.Queue,
the_rwlock->Wait_queue.operations,
executing, executing,
STATES_WAITING_FOR_RWLOCK, STATES_WAITING_FOR_RWLOCK,
timeout, timeout,

View File

@@ -50,7 +50,7 @@ void _Thread_queue_Initialize(
{ {
const Thread_queue_Operations *operations; const Thread_queue_Operations *operations;
_ISR_lock_Initialize( &the_thread_queue->Lock, "Thread Queue" ); _ISR_lock_Initialize( &the_thread_queue->Queue.Lock, "Thread Queue" );
if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) { if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
operations = &_Thread_queue_Operations_priority; operations = &_Thread_queue_Operations_priority;
@@ -60,5 +60,5 @@ void _Thread_queue_Initialize(
} }
the_thread_queue->operations = operations; the_thread_queue->operations = operations;
( *operations->initialize )( the_thread_queue ); ( *operations->initialize )( &the_thread_queue->Queue );
} }

View File

@@ -46,29 +46,28 @@ static void _Thread_queue_Unblock( Thread_Control *the_thread )
} }
void _Thread_queue_Enqueue_critical( void _Thread_queue_Enqueue_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, const Thread_queue_Operations *operations,
States_Control state, Thread_Control *the_thread,
Watchdog_Interval timeout, States_Control state,
uint32_t timeout_code, Watchdog_Interval timeout,
ISR_lock_Context *lock_context uint32_t timeout_code,
ISR_lock_Context *lock_context
) )
{ {
const Thread_queue_Operations *operations; Per_CPU_Control *cpu_self;
Per_CPU_Control *cpu_self; bool success;
bool success;
_Thread_Lock_set( the_thread, &the_thread_queue->Lock ); _Thread_Lock_set( the_thread, &queue->Lock );
operations = the_thread_queue->operations; _Thread_Wait_set_queue( the_thread, queue );
_Thread_Wait_set_queue( the_thread, the_thread_queue );
_Thread_Wait_set_operations( the_thread, operations ); _Thread_Wait_set_operations( the_thread, operations );
( *operations->enqueue )( the_thread_queue, the_thread ); ( *operations->enqueue )( queue, the_thread );
_Thread_Wait_flags_set( the_thread, THREAD_QUEUE_INTEND_TO_BLOCK ); _Thread_Wait_flags_set( the_thread, THREAD_QUEUE_INTEND_TO_BLOCK );
cpu_self = _Thread_Dispatch_disable_critical( lock_context ); cpu_self = _Thread_Dispatch_disable_critical( lock_context );
_Thread_queue_Release( the_thread_queue, lock_context ); _Thread_queue_Queue_release( queue, lock_context );
#if defined(RTEMS_MULTIPROCESSING) #if defined(RTEMS_MULTIPROCESSING)
if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet )
@@ -102,11 +101,12 @@ void _Thread_queue_Enqueue_critical(
} }
void _Thread_queue_Extract_locked( void _Thread_queue_Extract_locked(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread const Thread_queue_Operations *operations,
Thread_Control *the_thread
) )
{ {
( *the_thread_queue->operations->extract )( the_thread_queue, the_thread ); ( *operations->extract )( queue, the_thread );
_Thread_Wait_set_queue( the_thread, NULL ); _Thread_Wait_set_queue( the_thread, NULL );
_Thread_Wait_restore_default_operations( the_thread ); _Thread_Wait_restore_default_operations( the_thread );
@@ -114,9 +114,9 @@ void _Thread_queue_Extract_locked(
} }
void _Thread_queue_Unblock_critical( void _Thread_queue_Unblock_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, Thread_Control *the_thread,
ISR_lock_Context *lock_context ISR_lock_Context *lock_context
) )
{ {
bool success; bool success;
@@ -139,40 +139,46 @@ void _Thread_queue_Unblock_critical(
Per_CPU_Control *cpu_self; Per_CPU_Control *cpu_self;
cpu_self = _Thread_Dispatch_disable_critical( lock_context ); cpu_self = _Thread_Dispatch_disable_critical( lock_context );
_Thread_queue_Release( the_thread_queue, lock_context ); _Thread_queue_Queue_release( queue, lock_context );
_Thread_queue_Unblock( the_thread ); _Thread_queue_Unblock( the_thread );
_Thread_Dispatch_enable( cpu_self ); _Thread_Dispatch_enable( cpu_self );
} else { } else {
_Thread_queue_Release( the_thread_queue, lock_context ); _Thread_queue_Queue_release( queue, lock_context );
} }
} }
void _Thread_queue_Extract_critical( void _Thread_queue_Extract_critical(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, const Thread_queue_Operations *operations,
ISR_lock_Context *lock_context Thread_Control *the_thread,
ISR_lock_Context *lock_context
) )
{ {
_Thread_queue_Extract_locked( the_thread_queue, the_thread ); _Thread_queue_Extract_locked( queue, operations, the_thread );
_Thread_queue_Unblock_critical( the_thread_queue, the_thread, lock_context ); _Thread_queue_Unblock_critical( queue, the_thread, lock_context );
} }
void _Thread_queue_Extract( Thread_Control *the_thread ) void _Thread_queue_Extract( Thread_Control *the_thread )
{ {
ISR_lock_Context lock_context; ISR_lock_Context lock_context;
ISR_lock_Control *lock; ISR_lock_Control *lock;
Thread_queue_Control *the_thread_queue; Thread_queue_Queue *queue;
lock = _Thread_Lock_acquire( the_thread, &lock_context ); lock = _Thread_Lock_acquire( the_thread, &lock_context );
the_thread_queue = the_thread->Wait.queue; queue = the_thread->Wait.queue;
if ( the_thread_queue != NULL ) { if ( queue != NULL ) {
_SMP_Assert( lock == &the_thread_queue->Lock ); _SMP_Assert( lock == &queue->Lock );
_Thread_queue_Extract_critical( the_thread_queue, the_thread, &lock_context ); _Thread_queue_Extract_critical(
queue,
the_thread->Wait.operations,
the_thread,
&lock_context
);
} else { } else {
_Thread_Lock_release( lock, &lock_context ); _Thread_Lock_release( lock, &lock_context );
} }
@@ -188,9 +194,14 @@ Thread_Control *_Thread_queue_Dequeue( Thread_queue_Control *the_thread_queue )
the_thread = _Thread_queue_First_locked( the_thread_queue ); the_thread = _Thread_queue_First_locked( the_thread_queue );
if ( the_thread != NULL ) { if ( the_thread != NULL ) {
_SMP_Assert( the_thread->Lock.current == &the_thread_queue->Lock ); _SMP_Assert( the_thread->Lock.current == &the_thread_queue->Queue.Lock );
_Thread_queue_Extract_critical( the_thread_queue, the_thread, &lock_context ); _Thread_queue_Extract_critical(
&the_thread_queue->Queue,
the_thread_queue->operations,
the_thread,
&lock_context
);
} else { } else {
_Thread_queue_Release( the_thread_queue, &lock_context ); _Thread_queue_Release( the_thread_queue, &lock_context );
} }

View File

@@ -43,7 +43,8 @@ void _Thread_queue_Flush(
the_thread->Wait.return_code = status; the_thread->Wait.return_code = status;
_Thread_queue_Extract_critical( _Thread_queue_Extract_critical(
the_thread_queue, &the_thread_queue->Queue,
the_thread_queue->operations,
the_thread, the_thread,
&lock_context &lock_context
); );

View File

@@ -21,70 +21,70 @@
#include <rtems/score/rbtreeimpl.h> #include <rtems/score/rbtreeimpl.h>
static void _Thread_queue_Do_nothing_priority_change( static void _Thread_queue_Do_nothing_priority_change(
Thread_Control *the_thread, Thread_Control *the_thread,
Priority_Control new_priority, Priority_Control new_priority,
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
) )
{ {
/* Do nothing */ /* Do nothing */
} }
static void _Thread_queue_Do_nothing_extract( static void _Thread_queue_Do_nothing_extract(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
) )
{ {
/* Do nothing */ /* Do nothing */
} }
static void _Thread_queue_FIFO_initialize( static void _Thread_queue_FIFO_initialize(
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
) )
{ {
_Chain_Initialize_empty( &the_thread_queue->Queues.Fifo ); _Chain_Initialize_empty( &queue->Heads.Fifo );
} }
static void _Thread_queue_FIFO_enqueue( static void _Thread_queue_FIFO_enqueue(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
) )
{ {
_Chain_Append_unprotected( _Chain_Append_unprotected(
&the_thread_queue->Queues.Fifo, &queue->Heads.Fifo,
&the_thread->Wait.Node.Chain &the_thread->Wait.Node.Chain
); );
} }
static void _Thread_queue_FIFO_extract( static void _Thread_queue_FIFO_extract(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
) )
{ {
_Chain_Extract_unprotected( &the_thread->Wait.Node.Chain ); _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain );
} }
static Thread_Control *_Thread_queue_FIFO_first( static Thread_Control *_Thread_queue_FIFO_first(
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
) )
{ {
Chain_Control *fifo = &the_thread_queue->Queues.Fifo; Chain_Control *fifo = &queue->Heads.Fifo;
return _Chain_Is_empty( fifo ) ? return _Chain_Is_empty( fifo ) ?
NULL : THREAD_CHAIN_NODE_TO_THREAD( _Chain_First( fifo ) ); NULL : THREAD_CHAIN_NODE_TO_THREAD( _Chain_First( fifo ) );
} }
static void _Thread_queue_Priority_priority_change( static void _Thread_queue_Priority_priority_change(
Thread_Control *the_thread, Thread_Control *the_thread,
Priority_Control new_priority, Priority_Control new_priority,
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
) )
{ {
_RBTree_Extract( _RBTree_Extract(
&the_thread_queue->Queues.Priority, &queue->Heads.Priority,
&the_thread->Wait.Node.RBTree &the_thread->Wait.Node.RBTree
); );
_RBTree_Insert( _RBTree_Insert(
&the_thread_queue->Queues.Priority, &queue->Heads.Priority,
&the_thread->Wait.Node.RBTree, &the_thread->Wait.Node.RBTree,
_Thread_queue_Compare_priority, _Thread_queue_Compare_priority,
false false
@@ -92,19 +92,19 @@ static void _Thread_queue_Priority_priority_change(
} }
static void _Thread_queue_Priority_initialize( static void _Thread_queue_Priority_initialize(
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
) )
{ {
_RBTree_Initialize_empty( &the_thread_queue->Queues.Priority ); _RBTree_Initialize_empty( &queue->Heads.Priority );
} }
static void _Thread_queue_Priority_enqueue( static void _Thread_queue_Priority_enqueue(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
) )
{ {
_RBTree_Insert( _RBTree_Insert(
&the_thread_queue->Queues.Priority, &queue->Heads.Priority,
&the_thread->Wait.Node.RBTree, &the_thread->Wait.Node.RBTree,
_Thread_queue_Compare_priority, _Thread_queue_Compare_priority,
false false
@@ -112,23 +112,23 @@ static void _Thread_queue_Priority_enqueue(
} }
static void _Thread_queue_Priority_extract( static void _Thread_queue_Priority_extract(
Thread_queue_Control *the_thread_queue, Thread_queue_Queue *queue,
Thread_Control *the_thread Thread_Control *the_thread
) )
{ {
_RBTree_Extract( _RBTree_Extract(
&the_thread_queue->Queues.Priority, &queue->Heads.Priority,
&the_thread->Wait.Node.RBTree &the_thread->Wait.Node.RBTree
); );
} }
static Thread_Control *_Thread_queue_Priority_first( static Thread_Control *_Thread_queue_Priority_first(
Thread_queue_Control *the_thread_queue Thread_queue_Queue *queue
) )
{ {
RBTree_Node *first; RBTree_Node *first;
first = _RBTree_First( &the_thread_queue->Queues.Priority, RBT_LEFT ); first = _RBTree_First( &queue->Heads.Priority, RBT_LEFT );
return first != NULL ? THREAD_RBTREE_NODE_TO_THREAD( first ) : NULL; return first != NULL ? THREAD_RBTREE_NODE_TO_THREAD( first ) : NULL;
} }

View File

@@ -36,10 +36,10 @@ static rtems_task Init(
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
/* is there more to check? */ /* is there more to check? */
rtems_test_assert( _Chain_Is_empty( &fifo_queue.Queues.Fifo ) ); rtems_test_assert( _Chain_Is_empty( &fifo_queue.Queue.Heads.Fifo ) );
rtems_test_assert( fifo_queue.operations == &_Thread_queue_Operations_FIFO ); rtems_test_assert( fifo_queue.operations == &_Thread_queue_Operations_FIFO );
rtems_test_assert( _RBTree_Is_empty( &fifo_queue.Queues.Priority ) ); rtems_test_assert( _RBTree_Is_empty( &fifo_queue.Queue.Heads.Priority ) );
rtems_test_assert( rtems_test_assert(
prio_queue.operations == &_Thread_queue_Operations_priority prio_queue.operations == &_Thread_queue_Operations_priority
); );