forked from Imagelibrary/rtems
score: Remove Thread_queue_Queue::operations field
Remove the Thread_queue_Queue::operations field to reduce the size of this structure. Add a thread queue operations parameter to the _Thread_queue_First(), _Thread_queue_First_locked(), _Thread_queue_Enqueue(), _Thread_queue_Dequeue() and _Thread_queue_Flush() functions. This is a preparation patch to reduce the size of several synchronization objects.
This commit is contained in:
@@ -32,6 +32,8 @@ extern "C" {
|
||||
*/
|
||||
#define POSIX_CONDITION_VARIABLES_NO_MUTEX 0
|
||||
|
||||
#define POSIX_CONDITION_VARIABLES_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
/**
|
||||
* The following defines the information control block used to manage
|
||||
* this class of objects.
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
#define POSIX_SIGNALS_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
#define _States_Is_interruptible_signal( _states ) \
|
||||
( ((_states) & \
|
||||
(STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \
|
||||
|
||||
@@ -35,6 +35,8 @@ extern "C" {
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
#define POSIX_THREAD_JOIN_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
/**
|
||||
* The following sets the minimum stack size for POSIX threads.
|
||||
*/
|
||||
@@ -209,6 +211,16 @@ RTEMS_INLINE_ROUTINE bool _POSIX_Threads_Is_null (
|
||||
return !the_pthread;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Join_dequeue(
|
||||
POSIX_API_Control *api
|
||||
)
|
||||
{
|
||||
return _Thread_queue_Dequeue(
|
||||
&api->Join_List,
|
||||
POSIX_THREAD_JOIN_TQ_OPERATIONS
|
||||
);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -43,7 +43,12 @@ int pthread_cond_destroy(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {
|
||||
if (
|
||||
_Thread_queue_First(
|
||||
&the_cond->Wait_queue,
|
||||
POSIX_CONDITION_VARIABLES_TQ_OPERATIONS
|
||||
)
|
||||
) {
|
||||
_Objects_Put( &the_cond->Object );
|
||||
_Objects_Allocator_unlock();
|
||||
return EBUSY;
|
||||
|
||||
@@ -61,10 +61,7 @@ int pthread_cond_init(
|
||||
|
||||
the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&the_cond->Wait_queue,
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
_Thread_queue_Initialize( &the_cond->Wait_queue );
|
||||
|
||||
_Objects_Open_u32(
|
||||
&_POSIX_Condition_variables_Information,
|
||||
|
||||
@@ -47,7 +47,10 @@ int _POSIX_Condition_variables_Signal_support(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
do {
|
||||
the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
|
||||
the_thread = _Thread_queue_Dequeue(
|
||||
&the_cond->Wait_queue,
|
||||
POSIX_CONDITION_VARIABLES_TQ_OPERATIONS
|
||||
);
|
||||
if ( !the_thread )
|
||||
the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
|
||||
} while ( is_broadcast && the_thread );
|
||||
|
||||
@@ -79,6 +79,7 @@ int _POSIX_Condition_variables_Wait_support(
|
||||
|
||||
_Thread_queue_Enqueue(
|
||||
&the_cond->Wait_queue,
|
||||
POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_CONDITION_VARIABLE
|
||||
| STATES_INTERRUPTIBLE_BY_SIGNAL,
|
||||
|
||||
@@ -55,7 +55,6 @@ int _POSIX_Message_queue_Create_support(
|
||||
)
|
||||
{
|
||||
POSIX_Message_queue_Control *the_mq;
|
||||
CORE_message_queue_Attributes *the_mq_attr;
|
||||
struct mq_attr attr;
|
||||
char *name;
|
||||
|
||||
@@ -111,12 +110,9 @@ int _POSIX_Message_queue_Create_support(
|
||||
* Joel: Cite POSIX or OpenGroup on above statement so we can determine
|
||||
* if it is a real requirement.
|
||||
*/
|
||||
the_mq_attr = &the_mq->Message_queue.Attributes;
|
||||
the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||
|
||||
if ( !_CORE_message_queue_Initialize(
|
||||
&the_mq->Message_queue,
|
||||
the_mq_attr,
|
||||
CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
|
||||
attr.mq_maxmsg,
|
||||
attr.mq_msgsize
|
||||
) ) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <rtems/score/watchdogimpl.h>
|
||||
|
||||
static Thread_queue_Control _Nanosleep_Pseudo_queue =
|
||||
THREAD_QUEUE_FIFO_INITIALIZER( _Nanosleep_Pseudo_queue, "Nanosleep" );
|
||||
THREAD_QUEUE_INITIALIZER( "Nanosleep" );
|
||||
|
||||
/*
|
||||
* 14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
|
||||
@@ -89,6 +89,7 @@ int nanosleep(
|
||||
*/
|
||||
_Thread_queue_Enqueue(
|
||||
&_Nanosleep_Pseudo_queue,
|
||||
&_Thread_queue_Operations_FIFO,
|
||||
executing,
|
||||
STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL,
|
||||
ticks,
|
||||
|
||||
@@ -49,7 +49,12 @@ int pthread_rwlock_destroy(
|
||||
/*
|
||||
* If there is at least one thread waiting, then do not delete it.
|
||||
*/
|
||||
if ( _Thread_queue_First( &the_rwlock->RWLock.Wait_queue ) != NULL ) {
|
||||
if (
|
||||
_Thread_queue_First(
|
||||
&the_rwlock->RWLock.Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
) != NULL
|
||||
) {
|
||||
_Objects_Put( &the_rwlock->Object );
|
||||
_Objects_Allocator_unlock();
|
||||
return EBUSY;
|
||||
|
||||
@@ -92,7 +92,8 @@ const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
|
||||
|
||||
struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
|
||||
|
||||
Thread_queue_Control _POSIX_signals_Wait_queue;
|
||||
Thread_queue_Control _POSIX_signals_Wait_queue =
|
||||
THREAD_QUEUE_INITIALIZER( "POSIX Signals" );
|
||||
|
||||
Chain_Control _POSIX_signals_Inactive_siginfo;
|
||||
Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
|
||||
@@ -185,14 +186,6 @@ static void _POSIX_signals_Manager_Initialization(void)
|
||||
*/
|
||||
sigemptyset( &_POSIX_signals_Pending );
|
||||
|
||||
/*
|
||||
* Initialize the queue we use to block for signals
|
||||
*/
|
||||
_Thread_queue_Initialize(
|
||||
&_POSIX_signals_Wait_queue,
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
|
||||
/* XXX status codes */
|
||||
|
||||
/*
|
||||
|
||||
@@ -233,7 +233,7 @@ static bool _POSIX_Threads_Create_extension(
|
||||
api->signals_unblocked = executing_api->signals_unblocked;
|
||||
}
|
||||
|
||||
_Thread_queue_Initialize( &api->Join_List, THREAD_QUEUE_DISCIPLINE_FIFO );
|
||||
_Thread_queue_Initialize( &api->Join_List );
|
||||
|
||||
_Watchdog_Preinitialize( &api->Sporadic_timer, _Per_CPU_Get_by_index( 0 ) );
|
||||
_Watchdog_Initialize(
|
||||
@@ -261,8 +261,9 @@ static void _POSIX_Threads_Terminate_extension(
|
||||
*/
|
||||
value_ptr = (void **) executing->Wait.return_argument;
|
||||
|
||||
while ( (the_thread = _Thread_queue_Dequeue( &api->Join_List )) )
|
||||
*(void **)the_thread->Wait.return_argument = value_ptr;
|
||||
while ( ( the_thread = _POSIX_Threads_Join_dequeue( api ) ) ) {
|
||||
*(void **)the_thread->Wait.return_argument = value_ptr;
|
||||
}
|
||||
|
||||
if ( api->schedpolicy == SCHED_SPORADIC )
|
||||
_Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
|
||||
|
||||
@@ -48,11 +48,11 @@ void _POSIX_Thread_Exit(
|
||||
* Process join
|
||||
*/
|
||||
if ( api->detachstate == PTHREAD_CREATE_JOINABLE ) {
|
||||
unblocked = _Thread_queue_Dequeue( &api->Join_List );
|
||||
unblocked = _POSIX_Threads_Join_dequeue( api );
|
||||
if ( unblocked ) {
|
||||
do {
|
||||
*(void **)unblocked->Wait.return_argument = value_ptr;
|
||||
} while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) );
|
||||
} while ( ( unblocked = _POSIX_Threads_Join_dequeue( api ) ) );
|
||||
} else {
|
||||
_Thread_Set_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
@@ -69,6 +69,7 @@ on_EINTR:
|
||||
executing->Wait.return_argument = &return_pointer;
|
||||
_Thread_queue_Enqueue(
|
||||
&api->Join_List,
|
||||
POSIX_THREAD_JOIN_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_JOIN | STATES_INTERRUPTIBLE_BY_SIGNAL,
|
||||
WATCHDOG_NO_TIMEOUT,
|
||||
|
||||
@@ -47,9 +47,8 @@ int _POSIX_Semaphore_Create_support(
|
||||
POSIX_Semaphore_Control **the_sem
|
||||
)
|
||||
{
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
CORE_semaphore_Attributes *the_sem_attr;
|
||||
char *name;
|
||||
POSIX_Semaphore_Control *the_semaphore;
|
||||
char *name;
|
||||
|
||||
/* Sharing semaphores among processes is not currently supported */
|
||||
if (pshared != 0)
|
||||
@@ -86,8 +85,6 @@ int _POSIX_Semaphore_Create_support(
|
||||
the_semaphore->linked = false;
|
||||
}
|
||||
|
||||
the_sem_attr = &the_semaphore->Semaphore.Attributes;
|
||||
|
||||
/*
|
||||
* POSIX does not appear to specify what the discipline for
|
||||
* blocking tasks on this semaphore should be. It could somehow
|
||||
@@ -95,14 +92,12 @@ int _POSIX_Semaphore_Create_support(
|
||||
* thing is certain, no matter what we decide, it won't be
|
||||
* the same as all other POSIX implementations. :)
|
||||
*/
|
||||
the_sem_attr->discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
|
||||
|
||||
/*
|
||||
* This effectively disables limit checking.
|
||||
*/
|
||||
the_sem_attr->maximum_count = 0xFFFFFFFF;
|
||||
|
||||
_CORE_semaphore_Initialize( &the_semaphore->Semaphore, the_sem_attr, value );
|
||||
_CORE_semaphore_Initialize(
|
||||
&the_semaphore->Semaphore,
|
||||
CORE_SEMAPHORE_DISCIPLINES_FIFO,
|
||||
0xFFFFFFFF,
|
||||
value
|
||||
);
|
||||
|
||||
/*
|
||||
* Make the semaphore available for use.
|
||||
|
||||
@@ -156,7 +156,7 @@ int sigtimedwait(
|
||||
executing->Wait.return_argument = the_info;
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&_POSIX_signals_Wait_queue.Queue,
|
||||
_POSIX_signals_Wait_queue.operations,
|
||||
POSIX_SIGNALS_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL,
|
||||
interval,
|
||||
|
||||
@@ -59,6 +59,7 @@ extern "C" {
|
||||
typedef struct {
|
||||
Objects_Control Object;
|
||||
Thread_queue_Control Wait_queue; /* waiting threads */
|
||||
const Thread_queue_Operations *wait_operations;
|
||||
void *starting_address; /* physical start addr */
|
||||
uintptr_t length; /* physical length(bytes) */
|
||||
uintptr_t page_size; /* in bytes */
|
||||
|
||||
@@ -40,7 +40,7 @@ rtems_status_code rtems_message_queue_create(
|
||||
)
|
||||
{
|
||||
Message_queue_Control *the_message_queue;
|
||||
CORE_message_queue_Attributes the_msgq_attributes;
|
||||
CORE_message_queue_Disciplines discipline;
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
bool is_global;
|
||||
#endif
|
||||
@@ -101,13 +101,13 @@ rtems_status_code rtems_message_queue_create(
|
||||
the_message_queue->attribute_set = attribute_set;
|
||||
|
||||
if (_Attributes_Is_priority( attribute_set ) )
|
||||
the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
|
||||
discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
|
||||
else
|
||||
the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||
discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||
|
||||
if ( ! _CORE_message_queue_Initialize(
|
||||
&the_message_queue->message_queue,
|
||||
&the_msgq_attributes,
|
||||
discipline,
|
||||
count,
|
||||
max_message_size
|
||||
) ) {
|
||||
|
||||
@@ -71,11 +71,13 @@ rtems_status_code rtems_region_create(
|
||||
return_status = RTEMS_TOO_MANY;
|
||||
|
||||
else {
|
||||
_Thread_queue_Initialize(
|
||||
&the_region->Wait_queue,
|
||||
_Attributes_Is_priority( attribute_set ) ?
|
||||
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
_Thread_queue_Initialize( &the_region->Wait_queue );
|
||||
|
||||
if ( _Attributes_Is_priority( attribute_set ) ) {
|
||||
the_region->wait_operations = &_Thread_queue_Operations_priority;
|
||||
} else {
|
||||
the_region->wait_operations = &_Thread_queue_Operations_FIFO;
|
||||
}
|
||||
|
||||
the_region->maximum_segment_size = _Heap_Initialize(
|
||||
&the_region->Memory, starting_address, length, page_size
|
||||
|
||||
@@ -81,6 +81,7 @@ rtems_status_code rtems_region_get_segment(
|
||||
|
||||
_Thread_queue_Enqueue(
|
||||
&the_region->Wait_queue,
|
||||
the_region->wait_operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_SEGMENT,
|
||||
timeout,
|
||||
|
||||
@@ -46,7 +46,10 @@ void _Region_Process_queue(
|
||||
* threads whose memory request is satisfied.
|
||||
*/
|
||||
for ( ; ; ) {
|
||||
the_thread = _Thread_queue_First( &the_region->Wait_queue );
|
||||
the_thread = _Thread_queue_First(
|
||||
&the_region->Wait_queue,
|
||||
the_region->wait_operations
|
||||
);
|
||||
|
||||
if ( the_thread == NULL )
|
||||
break;
|
||||
|
||||
@@ -62,7 +62,7 @@ rtems_status_code rtems_semaphore_create(
|
||||
{
|
||||
Semaphore_Control *the_semaphore;
|
||||
CORE_mutex_Attributes the_mutex_attr;
|
||||
CORE_semaphore_Attributes the_semaphore_attr;
|
||||
CORE_semaphore_Disciplines semaphore_discipline;
|
||||
CORE_mutex_Status mutex_status;
|
||||
|
||||
if ( !rtems_is_name_valid( name ) )
|
||||
@@ -139,15 +139,10 @@ rtems_status_code rtems_semaphore_create(
|
||||
* Initialize it as a counting semaphore.
|
||||
*/
|
||||
if ( _Attributes_Is_counting_semaphore( attribute_set ) ) {
|
||||
/*
|
||||
* This effectively disables limit checking.
|
||||
*/
|
||||
the_semaphore_attr.maximum_count = 0xFFFFFFFF;
|
||||
|
||||
if ( _Attributes_Is_priority( attribute_set ) )
|
||||
the_semaphore_attr.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
|
||||
semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
|
||||
else
|
||||
the_semaphore_attr.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
|
||||
semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
|
||||
|
||||
/*
|
||||
* The following are just to make Purify happy.
|
||||
@@ -157,7 +152,8 @@ rtems_status_code rtems_semaphore_create(
|
||||
|
||||
_CORE_semaphore_Initialize(
|
||||
&the_semaphore->Core_control.semaphore,
|
||||
&the_semaphore_attr,
|
||||
semaphore_discipline,
|
||||
0xFFFFFFFF,
|
||||
count
|
||||
);
|
||||
#if defined(RTEMS_SMP)
|
||||
|
||||
@@ -62,6 +62,8 @@ typedef enum {
|
||||
*/
|
||||
#define CORE_BARRIER_STATUS_LAST CORE_BARRIER_TIMEOUT
|
||||
|
||||
#define CORE_BARRIER_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
/**
|
||||
* The following type defines the callout which the API provides
|
||||
* to support global/multiprocessor operations on barriers.
|
||||
@@ -150,6 +152,7 @@ uint32_t _CORE_barrier_Release(
|
||||
#define _CORE_barrier_Flush( _the_barrier, _remote_extract_callout, _status) \
|
||||
_Thread_queue_Flush( \
|
||||
&((_the_barrier)->Wait_queue), \
|
||||
CORE_BARRIER_TQ_OPERATIONS, \
|
||||
(_remote_extract_callout), \
|
||||
(_status) \
|
||||
)
|
||||
|
||||
@@ -109,17 +109,6 @@ typedef enum {
|
||||
CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY
|
||||
} CORE_message_queue_Disciplines;
|
||||
|
||||
/**
|
||||
* @brief Control block used to manage the attributes of each message queue.
|
||||
*
|
||||
* The following defines the control block used to manage the
|
||||
* attributes of each message queue.
|
||||
*/
|
||||
typedef struct {
|
||||
/** This field specifies the order in which blocking tasks will be ordered. */
|
||||
CORE_message_queue_Disciplines discipline;
|
||||
} CORE_message_queue_Attributes;
|
||||
|
||||
#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
|
||||
/**
|
||||
* @brief Type for a notification handler.
|
||||
@@ -142,10 +131,12 @@ typedef struct {
|
||||
* which are blocked waiting to receive a message from this queue.
|
||||
*/
|
||||
Thread_queue_Control Wait_queue;
|
||||
/** This element is the set of attributes which define this instance's
|
||||
* behavior.
|
||||
|
||||
/**
|
||||
* @brief The thread queue operations according to the blocking discipline.
|
||||
*/
|
||||
CORE_message_queue_Attributes Attributes;
|
||||
const Thread_queue_Operations *operations;
|
||||
|
||||
/** This element is maximum number of messages which may be pending
|
||||
* at any given time.
|
||||
*/
|
||||
|
||||
@@ -122,8 +122,7 @@ typedef void ( *CORE_message_queue_API_mp_support_callout )(
|
||||
* based on the parameters passed.
|
||||
*
|
||||
* @param[in] the_message_queue points to the message queue to initialize
|
||||
* @param[in] the_message_queue_attributes points to the attributes that
|
||||
* will be used with this message queue instance
|
||||
* @param[in] discipline the blocking discipline
|
||||
* @param[in] maximum_pending_messages is the maximum number of messages
|
||||
* that will be allowed to pend at any given time
|
||||
* @param[in] maximum_message_size is the size of largest message that
|
||||
@@ -134,10 +133,10 @@ typedef void ( *CORE_message_queue_API_mp_support_callout )(
|
||||
* messages cannot be allocated.
|
||||
*/
|
||||
bool _CORE_message_queue_Initialize(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
CORE_message_queue_Attributes *the_message_queue_attributes,
|
||||
uint32_t maximum_pending_messages,
|
||||
size_t maximum_message_size
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
CORE_message_queue_Disciplines discipline,
|
||||
uint32_t maximum_pending_messages,
|
||||
size_t maximum_message_size
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -513,18 +512,6 @@ RTEMS_INLINE_ROUTINE
|
||||
_Chain_Get_unprotected( &the_message_queue->Pending_messages );
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns true if the priority attribute is
|
||||
* enabled in the attribute_set and false otherwise.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_message_queue_Is_priority(
|
||||
CORE_message_queue_Attributes *the_attribute
|
||||
)
|
||||
{
|
||||
return
|
||||
(the_attribute->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY);
|
||||
}
|
||||
|
||||
#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
|
||||
/**
|
||||
* This function returns true if notification is enabled on this message
|
||||
@@ -584,7 +571,10 @@ RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
|
||||
* There must be no pending messages if there is a thread waiting to
|
||||
* receive a message.
|
||||
*/
|
||||
the_thread = _Thread_queue_First_locked( &the_message_queue->Wait_queue );
|
||||
the_thread = _Thread_queue_First_locked(
|
||||
&the_message_queue->Wait_queue,
|
||||
the_message_queue->operations
|
||||
);
|
||||
if ( the_thread == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -600,7 +590,7 @@ RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
|
||||
|
||||
_Thread_queue_Extract_critical(
|
||||
&the_message_queue->Wait_queue.Queue,
|
||||
the_message_queue->Wait_queue.operations,
|
||||
the_message_queue->operations,
|
||||
the_thread,
|
||||
lock_context
|
||||
);
|
||||
|
||||
@@ -151,6 +151,12 @@ typedef struct {
|
||||
* which are blocked waiting to lock the mutex.
|
||||
*/
|
||||
Thread_queue_Control Wait_queue;
|
||||
|
||||
/**
|
||||
* @brief The thread queue operations according to the blocking discipline.
|
||||
*/
|
||||
const Thread_queue_Operations *operations;
|
||||
|
||||
/** This element is the set of attributes which define this instance's
|
||||
* behavior.
|
||||
*/
|
||||
|
||||
@@ -392,7 +392,7 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
|
||||
*
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(
|
||||
CORE_mutex_Attributes *the_attribute
|
||||
const CORE_mutex_Attributes *the_attribute
|
||||
)
|
||||
{
|
||||
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
|
||||
@@ -410,7 +410,7 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(
|
||||
* @retval false The mutex is not using priority inheritance.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
|
||||
CORE_mutex_Attributes *the_attribute
|
||||
const CORE_mutex_Attributes *the_attribute
|
||||
)
|
||||
{
|
||||
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
|
||||
@@ -428,7 +428,7 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
|
||||
* @retval false The mutex is not using priority ceiling.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
|
||||
CORE_mutex_Attributes *the_attribute
|
||||
const CORE_mutex_Attributes *the_attribute
|
||||
)
|
||||
{
|
||||
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
|
||||
|
||||
@@ -33,6 +33,8 @@ extern "C" {
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
#define CORE_RWLOCK_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
/**
|
||||
* The following type defines the callout which the API provides
|
||||
* to support global/multiprocessor operations on RWLocks.
|
||||
|
||||
@@ -56,10 +56,6 @@ typedef enum {
|
||||
typedef struct {
|
||||
/** This element indicates the maximum count this semaphore may have. */
|
||||
uint32_t maximum_count;
|
||||
/** This field indicates whether threads waiting on the semaphore block in
|
||||
* FIFO or priority order.
|
||||
*/
|
||||
CORE_semaphore_Disciplines discipline;
|
||||
} CORE_semaphore_Attributes;
|
||||
|
||||
/**
|
||||
@@ -71,6 +67,12 @@ typedef struct {
|
||||
* which are blocked waiting to obtain the semaphore.
|
||||
*/
|
||||
Thread_queue_Control Wait_queue;
|
||||
|
||||
/**
|
||||
* @brief The thread queue operations according to the blocking discipline.
|
||||
*/
|
||||
const Thread_queue_Operations *operations;
|
||||
|
||||
/** This element is the set of attributes which define this instance's
|
||||
* behavior.
|
||||
*/
|
||||
|
||||
@@ -86,13 +86,15 @@ typedef void ( *CORE_semaphore_API_mp_support_callout )(
|
||||
* This routine initializes the semaphore based on the parameters passed.
|
||||
*
|
||||
* @param[in] the_semaphore is the semaphore to initialize
|
||||
* @param[in] the_semaphore_attributes define the behavior of this instance
|
||||
* @param[in] discipline the blocking discipline
|
||||
* @param[in] maximum_count the maximum count
|
||||
* @param[in] initial_value is the initial count of the semaphore
|
||||
*/
|
||||
void _CORE_semaphore_Initialize(
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
const CORE_semaphore_Attributes *the_semaphore_attributes,
|
||||
uint32_t initial_value
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
CORE_semaphore_Disciplines discipline,
|
||||
uint32_t maximum_count,
|
||||
uint32_t initial_value
|
||||
);
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
|
||||
@@ -133,7 +135,10 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
|
||||
|
||||
_Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
|
||||
|
||||
the_thread = _Thread_queue_First_locked( &the_semaphore->Wait_queue );
|
||||
the_thread = _Thread_queue_First_locked(
|
||||
&the_semaphore->Wait_queue,
|
||||
the_semaphore->operations
|
||||
);
|
||||
if ( the_thread != NULL ) {
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
_Thread_Dispatch_disable();
|
||||
@@ -141,7 +146,7 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
|
||||
|
||||
_Thread_queue_Extract_critical(
|
||||
&the_semaphore->Wait_queue.Queue,
|
||||
the_semaphore->Wait_queue.operations,
|
||||
the_semaphore->operations,
|
||||
the_thread,
|
||||
lock_context
|
||||
);
|
||||
@@ -187,26 +192,12 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Flush(
|
||||
{
|
||||
_Thread_queue_Flush(
|
||||
&the_semaphore->Wait_queue,
|
||||
the_semaphore->operations,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns true if the priority attribute is
|
||||
* enabled in the @a attribute_set and false otherwise.
|
||||
*
|
||||
* @param[in] the_attribute is the attribute set to test
|
||||
*
|
||||
* @return true if the priority attribute is enabled
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_semaphore_Is_priority(
|
||||
const CORE_semaphore_Attributes *the_attribute
|
||||
)
|
||||
{
|
||||
return ( the_attribute->discipline == CORE_SEMAPHORE_DISCIPLINES_PRIORITY );
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine returns the current count associated with the semaphore.
|
||||
*
|
||||
@@ -265,7 +256,7 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize(
|
||||
executing->Wait.id = id;
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_semaphore->Wait_queue.Queue,
|
||||
the_semaphore->Wait_queue.operations,
|
||||
the_semaphore->operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_SEMAPHORE,
|
||||
timeout,
|
||||
|
||||
@@ -243,15 +243,6 @@ typedef struct {
|
||||
Thread_queue_First_operation first;
|
||||
} Thread_queue_Operations;
|
||||
|
||||
/**
|
||||
* The following enumerated type details all of the disciplines
|
||||
* supported by the Thread Queue Handler.
|
||||
*/
|
||||
typedef enum {
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO, /* FIFO queue discipline */
|
||||
THREAD_QUEUE_DISCIPLINE_PRIORITY /* PRIORITY queue discipline */
|
||||
} Thread_queue_Disciplines;
|
||||
|
||||
/**
|
||||
* This is the structure used to manage sets of tasks which are blocked
|
||||
* waiting to acquire a resource.
|
||||
@@ -265,11 +256,6 @@ typedef struct {
|
||||
#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
|
||||
SMP_lock_Stats Lock_stats;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The operations for the actual thread queue.
|
||||
*/
|
||||
const Thread_queue_Operations *operations;
|
||||
} Thread_queue_Control;
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -173,7 +173,8 @@ typedef void ( *Thread_queue_Flush_callout )(
|
||||
* + single case
|
||||
*/
|
||||
Thread_Control *_Thread_queue_Dequeue(
|
||||
Thread_queue_Control *the_thread_queue
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -196,6 +197,8 @@ Thread_Control *_Thread_queue_Dequeue(
|
||||
* #include <rtems/score/threadqimpl.h>
|
||||
* #include <rtems/score/statesimpl.h>
|
||||
*
|
||||
* #define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
|
||||
*
|
||||
* typedef struct {
|
||||
* Thread_queue_Control Queue;
|
||||
* Thread_Control *owner;
|
||||
@@ -216,7 +219,7 @@ Thread_Control *_Thread_queue_Dequeue(
|
||||
* } else {
|
||||
* _Thread_queue_Enqueue_critical(
|
||||
* &mutex->Queue.Queue,
|
||||
* mutex->Queue.operations,
|
||||
* MUTEX_TQ_OPERATIONS,
|
||||
* executing,
|
||||
* STATES_WAITING_FOR_MUTEX,
|
||||
* WATCHDOG_NO_TIMEOUT,
|
||||
@@ -251,11 +254,12 @@ void _Thread_queue_Enqueue_critical(
|
||||
* _Thread_queue_Enqueue_critical().
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
Thread_Control *the_thread,
|
||||
States_Control state,
|
||||
Watchdog_Interval timeout,
|
||||
uint32_t timeout_code
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_Control *the_thread,
|
||||
States_Control state,
|
||||
Watchdog_Interval timeout,
|
||||
uint32_t timeout_code
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
@@ -263,7 +267,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
|
||||
_Thread_queue_Acquire( the_thread_queue, &lock_context );
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_thread_queue->Queue,
|
||||
the_thread_queue->operations,
|
||||
operations,
|
||||
the_thread,
|
||||
state,
|
||||
timeout,
|
||||
@@ -400,19 +404,21 @@ void _Thread_queue_Extract_with_proxy(
|
||||
* lock is not released.
|
||||
*
|
||||
* @param[in] the_thread_queue The thread queue.
|
||||
* @param[in] operations The thread queue operations.
|
||||
*
|
||||
* @retval NULL No thread is present on the thread queue.
|
||||
* @retval first The first thread on the thread queue according to the enqueue
|
||||
* order.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
|
||||
Thread_queue_Control *the_thread_queue
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations
|
||||
)
|
||||
{
|
||||
Thread_queue_Heads *heads = the_thread_queue->Queue.heads;
|
||||
|
||||
if ( heads != NULL ) {
|
||||
return ( *the_thread_queue->operations->first )( heads );
|
||||
return ( *operations->first )( heads );
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@@ -429,7 +435,8 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
|
||||
* order.
|
||||
*/
|
||||
Thread_Control *_Thread_queue_First(
|
||||
Thread_queue_Control *the_thread_queue
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -439,76 +446,41 @@ Thread_Control *_Thread_queue_First(
|
||||
* and cancels any associated timeouts.
|
||||
*
|
||||
* @param[in] the_thread_queue is the pointer to a threadq header
|
||||
* @param[in] operations The thread queue operations.
|
||||
* @param[in] remote_extract_callout points to a method to invoke to
|
||||
* invoke when a remote thread is unblocked
|
||||
* @param[in] status is the status which will be returned to
|
||||
* all unblocked threads
|
||||
*/
|
||||
void _Thread_queue_Flush(
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
uint32_t status
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
uint32_t status
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Initialize the_thread_queue.
|
||||
*
|
||||
* This routine initializes the_thread_queue based on the
|
||||
* discipline indicated in attribute_set. The state set on
|
||||
* threads which block on the_thread_queue is state.
|
||||
*
|
||||
* @param[in] the_thread_queue is the pointer to a threadq header
|
||||
* @param[in] the_discipline is the queueing discipline
|
||||
*/
|
||||
void _Thread_queue_Initialize(
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
Thread_queue_Disciplines the_discipline
|
||||
);
|
||||
void _Thread_queue_Initialize( Thread_queue_Control *the_thread_queue );
|
||||
|
||||
#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
|
||||
#define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
|
||||
#define THREAD_QUEUE_INITIALIZER( name ) \
|
||||
{ \
|
||||
.Queue = { \
|
||||
.heads = NULL, \
|
||||
.Lock = SMP_TICKET_LOCK_INITIALIZER, \
|
||||
}, \
|
||||
.Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \
|
||||
.operations = &_Thread_queue_Operations_FIFO \
|
||||
}
|
||||
|
||||
#define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \
|
||||
.Queue = { \
|
||||
.heads = NULL, \
|
||||
.Lock = SMP_TICKET_LOCK_INITIALIZER, \
|
||||
}, \
|
||||
.Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \
|
||||
.operations = &_Thread_queue_Operations_priority \
|
||||
.Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ) \
|
||||
}
|
||||
#elif defined(RTEMS_SMP)
|
||||
#define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
|
||||
#define THREAD_QUEUE_INITIALIZER( name ) \
|
||||
{ \
|
||||
.Queue = { \
|
||||
.heads = NULL, \
|
||||
.Lock = SMP_TICKET_LOCK_INITIALIZER, \
|
||||
}, \
|
||||
.operations = &_Thread_queue_Operations_FIFO \
|
||||
}
|
||||
|
||||
#define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \
|
||||
.Queue = { \
|
||||
.heads = NULL, \
|
||||
.Lock = SMP_TICKET_LOCK_INITIALIZER, \
|
||||
}, \
|
||||
.operations = &_Thread_queue_Operations_priority \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \
|
||||
.Queue = { .heads = NULL }, \
|
||||
.operations = &_Thread_queue_Operations_FIFO \
|
||||
}
|
||||
|
||||
#define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \
|
||||
.Queue = { .heads = NULL }, \
|
||||
.operations = &_Thread_queue_Operations_priority \
|
||||
}
|
||||
#define THREAD_QUEUE_INITIALIZER( name ) \
|
||||
{ .Queue = { .heads = NULL } }
|
||||
#endif
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
|
||||
|
||||
@@ -30,8 +30,5 @@ void _CORE_barrier_Initialize(
|
||||
the_barrier->Attributes = *the_barrier_attributes;
|
||||
the_barrier->number_of_waiting_threads = 0;
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&the_barrier->Wait_queue,
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
_Thread_queue_Initialize( &the_barrier->Wait_queue );
|
||||
}
|
||||
|
||||
@@ -23,6 +23,16 @@
|
||||
#include <rtems/score/objectimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
static Thread_Control *_CORE_barrier_Dequeue(
|
||||
CORE_barrier_Control *the_barrier
|
||||
)
|
||||
{
|
||||
return _Thread_queue_Dequeue(
|
||||
&the_barrier->Wait_queue,
|
||||
CORE_BARRIER_TQ_OPERATIONS
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t _CORE_barrier_Release(
|
||||
CORE_barrier_Control *the_barrier,
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
@@ -38,7 +48,7 @@ uint32_t _CORE_barrier_Release(
|
||||
uint32_t count;
|
||||
|
||||
count = 0;
|
||||
while ( (the_thread = _Thread_queue_Dequeue(&the_barrier->Wait_queue)) ) {
|
||||
while ( ( the_thread = _CORE_barrier_Dequeue( the_barrier ) ) ) {
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_barrier_mp_support) ( the_thread, id );
|
||||
|
||||
@@ -51,7 +51,7 @@ void _CORE_barrier_Wait(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_barrier->Wait_queue.Queue,
|
||||
the_barrier->Wait_queue.operations,
|
||||
CORE_BARRIER_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_BARRIER,
|
||||
timeout,
|
||||
|
||||
@@ -43,10 +43,10 @@ static inline bool size_t_mult32_with_overflow(
|
||||
}
|
||||
|
||||
bool _CORE_message_queue_Initialize(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
CORE_message_queue_Attributes *the_message_queue_attributes,
|
||||
uint32_t maximum_pending_messages,
|
||||
size_t maximum_message_size
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
CORE_message_queue_Disciplines discipline,
|
||||
uint32_t maximum_pending_messages,
|
||||
size_t maximum_message_size
|
||||
)
|
||||
{
|
||||
size_t message_buffering_required = 0;
|
||||
@@ -108,11 +108,13 @@ bool _CORE_message_queue_Initialize(
|
||||
|
||||
_Chain_Initialize_empty( &the_message_queue->Pending_messages );
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&the_message_queue->Wait_queue,
|
||||
_CORE_message_queue_Is_priority( the_message_queue_attributes ) ?
|
||||
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
_Thread_queue_Initialize( &the_message_queue->Wait_queue );
|
||||
|
||||
if ( discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY ) {
|
||||
the_message_queue->operations = &_Thread_queue_Operations_priority;
|
||||
} else {
|
||||
the_message_queue->operations = &_Thread_queue_Operations_FIFO;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ void _CORE_message_queue_Close(
|
||||
|
||||
_Thread_queue_Flush(
|
||||
&the_message_queue->Wait_queue,
|
||||
the_message_queue->operations,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
|
||||
@@ -74,7 +74,8 @@ void _CORE_message_queue_Seize(
|
||||
* then we can avoid this dequeue.
|
||||
*/
|
||||
the_thread = _Thread_queue_First_locked(
|
||||
&the_message_queue->Wait_queue
|
||||
&the_message_queue->Wait_queue,
|
||||
the_message_queue->operations
|
||||
);
|
||||
if ( the_thread == NULL ) {
|
||||
_CORE_message_queue_Free_message_buffer(
|
||||
@@ -108,7 +109,7 @@ void _CORE_message_queue_Seize(
|
||||
);
|
||||
_Thread_queue_Extract_critical(
|
||||
&the_message_queue->Wait_queue.Queue,
|
||||
the_message_queue->Wait_queue.operations,
|
||||
the_message_queue->operations,
|
||||
the_thread,
|
||||
lock_context
|
||||
);
|
||||
@@ -133,7 +134,7 @@ void _CORE_message_queue_Seize(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_message_queue->Wait_queue.Queue,
|
||||
the_message_queue->Wait_queue.operations,
|
||||
the_message_queue->operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_MESSAGE,
|
||||
timeout,
|
||||
|
||||
@@ -133,7 +133,7 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_message_queue->Wait_queue.Queue,
|
||||
the_message_queue->Wait_queue.operations,
|
||||
the_message_queue->operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_MESSAGE,
|
||||
timeout,
|
||||
|
||||
@@ -86,11 +86,13 @@ CORE_mutex_Status _CORE_mutex_Initialize(
|
||||
the_mutex->holder = NULL;
|
||||
}
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&the_mutex->Wait_queue,
|
||||
_CORE_mutex_Is_fifo( the_mutex_attributes ) ?
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO : THREAD_QUEUE_DISCIPLINE_PRIORITY
|
||||
);
|
||||
_Thread_queue_Initialize( &the_mutex->Wait_queue );
|
||||
|
||||
if ( _CORE_mutex_Is_priority( the_mutex_attributes ) ) {
|
||||
the_mutex->operations = &_Thread_queue_Operations_priority;
|
||||
} else {
|
||||
the_mutex->operations = &_Thread_queue_Operations_FIFO;
|
||||
}
|
||||
|
||||
return CORE_MUTEX_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ void _CORE_mutex_Flush(
|
||||
{
|
||||
_Thread_queue_Flush(
|
||||
&the_mutex->Wait_queue,
|
||||
the_mutex->operations,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
|
||||
@@ -84,7 +84,7 @@ void _CORE_mutex_Seize_interrupt_blocking(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_mutex->Wait_queue.Queue,
|
||||
the_mutex->Wait_queue.operations,
|
||||
the_mutex->operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_MUTEX,
|
||||
timeout,
|
||||
|
||||
@@ -178,7 +178,13 @@ CORE_mutex_Status _CORE_mutex_Surrender(
|
||||
* 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 ) ) ) {
|
||||
if (
|
||||
( the_thread = _Thread_queue_First_locked(
|
||||
&the_mutex->Wait_queue,
|
||||
the_mutex->operations
|
||||
)
|
||||
)
|
||||
) {
|
||||
bool unblock;
|
||||
|
||||
/*
|
||||
@@ -189,7 +195,7 @@ CORE_mutex_Status _CORE_mutex_Surrender(
|
||||
*/
|
||||
unblock = _Thread_queue_Extract_locked(
|
||||
&the_mutex->Wait_queue.Queue,
|
||||
the_mutex->Wait_queue.operations,
|
||||
the_mutex->operations,
|
||||
the_thread
|
||||
);
|
||||
|
||||
|
||||
@@ -34,8 +34,5 @@ void _CORE_RWLock_Initialize(
|
||||
the_rwlock->number_of_readers = 0;
|
||||
the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&the_rwlock->Wait_queue,
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
_Thread_queue_Initialize( &the_rwlock->Wait_queue );
|
||||
}
|
||||
|
||||
@@ -51,7 +51,10 @@ void _CORE_RWLock_Obtain_for_reading(
|
||||
|
||||
case CORE_RWLOCK_LOCKED_FOR_READING: {
|
||||
Thread_Control *waiter;
|
||||
waiter = _Thread_queue_First_locked( &the_rwlock->Wait_queue );
|
||||
waiter = _Thread_queue_First_locked(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
if ( !waiter ) {
|
||||
the_rwlock->number_of_readers += 1;
|
||||
_Thread_queue_Release( &the_rwlock->Wait_queue, &lock_context );
|
||||
@@ -84,7 +87,7 @@ void _CORE_RWLock_Obtain_for_reading(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
the_rwlock->Wait_queue.operations,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RWLOCK,
|
||||
timeout,
|
||||
|
||||
@@ -74,7 +74,7 @@ void _CORE_RWLock_Obtain_for_writing(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_rwlock->Wait_queue.Queue,
|
||||
the_rwlock->Wait_queue.operations,
|
||||
CORE_RWLOCK_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RWLOCK,
|
||||
timeout,
|
||||
|
||||
@@ -64,7 +64,10 @@ CORE_RWLock_Status _CORE_RWLock_Release(
|
||||
the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
|
||||
_ISR_Enable( level );
|
||||
|
||||
next = _Thread_queue_Dequeue( &the_rwlock->Wait_queue );
|
||||
next = _Thread_queue_Dequeue(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
|
||||
if ( next ) {
|
||||
if ( next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) {
|
||||
@@ -82,7 +85,10 @@ CORE_RWLock_Status _CORE_RWLock_Release(
|
||||
* Now see if more readers can be let go.
|
||||
*/
|
||||
while ( 1 ) {
|
||||
next = _Thread_queue_First( &the_rwlock->Wait_queue );
|
||||
next = _Thread_queue_First(
|
||||
&the_rwlock->Wait_queue,
|
||||
CORE_RWLOCK_TQ_OPERATIONS
|
||||
);
|
||||
if ( !next ||
|
||||
next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE )
|
||||
return CORE_RWLOCK_SUCCESSFUL;
|
||||
|
||||
@@ -21,18 +21,21 @@
|
||||
#include <rtems/score/coresemimpl.h>
|
||||
|
||||
void _CORE_semaphore_Initialize(
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
const CORE_semaphore_Attributes *the_semaphore_attributes,
|
||||
uint32_t initial_value
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
CORE_semaphore_Disciplines discipline,
|
||||
uint32_t maximum_count,
|
||||
uint32_t initial_value
|
||||
)
|
||||
{
|
||||
|
||||
the_semaphore->Attributes = *the_semaphore_attributes;
|
||||
the_semaphore->count = initial_value;
|
||||
the_semaphore->Attributes.maximum_count = maximum_count;
|
||||
the_semaphore->count = initial_value;
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&the_semaphore->Wait_queue,
|
||||
_CORE_semaphore_Is_priority( the_semaphore_attributes ) ?
|
||||
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
_Thread_queue_Initialize( &the_semaphore->Wait_queue );
|
||||
|
||||
if ( discipline == CORE_SEMAPHORE_DISCIPLINES_PRIORITY ) {
|
||||
the_semaphore->operations = &_Thread_queue_Operations_priority;
|
||||
} else {
|
||||
the_semaphore->operations = &_Thread_queue_Operations_FIFO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ const rtems_multiprocessing_table
|
||||
*/
|
||||
CORE_semaphore_Control _MPCI_Semaphore;
|
||||
|
||||
Thread_queue_Control _MPCI_Remote_blocked_threads;
|
||||
Thread_queue_Control _MPCI_Remote_blocked_threads =
|
||||
THREAD_QUEUE_INITIALIZER( "MPCI Remote Blocked Threads" );
|
||||
|
||||
MPCI_Control *_MPCI_table;
|
||||
|
||||
@@ -85,7 +86,6 @@ static void _MPCI_Handler_early_initialization( void )
|
||||
|
||||
static void _MPCI_Handler_initialization( void )
|
||||
{
|
||||
CORE_semaphore_Attributes attributes;
|
||||
MPCI_Control *users_mpci_table;
|
||||
|
||||
_Objects_MP_Handler_initialization();
|
||||
@@ -117,18 +117,12 @@ static void _MPCI_Handler_initialization( void )
|
||||
* Create the counting semaphore used by the MPCI Receive Server.
|
||||
*/
|
||||
|
||||
attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
|
||||
|
||||
_CORE_semaphore_Initialize(
|
||||
&_MPCI_Semaphore,
|
||||
&attributes, /* the_semaphore_attributes */
|
||||
CORE_SEMAPHORE_DISCIPLINES_FIFO,
|
||||
0xffffffff,
|
||||
0 /* initial_value */
|
||||
);
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&_MPCI_Remote_blocked_threads,
|
||||
THREAD_QUEUE_DISCIPLINE_FIFO
|
||||
);
|
||||
}
|
||||
|
||||
static void _MPCI_Create_server( void )
|
||||
@@ -262,6 +256,7 @@ uint32_t _MPCI_Send_request_packet (
|
||||
|
||||
_Thread_queue_Enqueue(
|
||||
&_MPCI_Remote_blocked_threads,
|
||||
&_Thread_queue_Operations_FIFO,
|
||||
executing,
|
||||
STATES_WAITING_FOR_RPC_REPLY | extra_state,
|
||||
the_packet->timeout,
|
||||
|
||||
@@ -79,22 +79,8 @@ RBTree_Compare_result _Thread_queue_Compare_priority(
|
||||
return ( left_prio > right_prio ) - ( left_prio < right_prio );
|
||||
}
|
||||
|
||||
void _Thread_queue_Initialize(
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
Thread_queue_Disciplines the_discipline
|
||||
)
|
||||
void _Thread_queue_Initialize( Thread_queue_Control *the_thread_queue )
|
||||
{
|
||||
const Thread_queue_Operations *operations;
|
||||
|
||||
if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
|
||||
operations = &_Thread_queue_Operations_priority;
|
||||
} else {
|
||||
_Assert( the_discipline == THREAD_QUEUE_DISCIPLINE_FIFO );
|
||||
operations = &_Thread_queue_Operations_FIFO;
|
||||
}
|
||||
|
||||
the_thread_queue->operations = operations;
|
||||
|
||||
_Thread_queue_Queue_initialize( &the_thread_queue->Queue );
|
||||
#if defined(RTEMS_SMP)
|
||||
_SMP_lock_Stats_initialize( &the_thread_queue->Lock_stats, "Thread Queue" );
|
||||
|
||||
@@ -193,21 +193,24 @@ void _Thread_queue_Extract( Thread_Control *the_thread )
|
||||
}
|
||||
}
|
||||
|
||||
Thread_Control *_Thread_queue_Dequeue( Thread_queue_Control *the_thread_queue )
|
||||
Thread_Control *_Thread_queue_Dequeue(
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
Thread_Control *the_thread;
|
||||
|
||||
_Thread_queue_Acquire( the_thread_queue, &lock_context );
|
||||
|
||||
the_thread = _Thread_queue_First_locked( the_thread_queue );
|
||||
the_thread = _Thread_queue_First_locked( the_thread_queue, operations );
|
||||
|
||||
if ( the_thread != NULL ) {
|
||||
_SMP_Assert( the_thread->Lock.current == &the_thread_queue->Queue.Lock );
|
||||
|
||||
_Thread_queue_Extract_critical(
|
||||
&the_thread_queue->Queue,
|
||||
the_thread_queue->operations,
|
||||
operations,
|
||||
the_thread,
|
||||
&lock_context
|
||||
);
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
Thread_Control *_Thread_queue_First(
|
||||
Thread_queue_Control *the_thread_queue
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_Thread_queue_Acquire( the_thread_queue, &lock_context );
|
||||
the_thread = _Thread_queue_First_locked( the_thread_queue );
|
||||
the_thread = _Thread_queue_First_locked( the_thread_queue, operations );
|
||||
_Thread_queue_Release( the_thread_queue, &lock_context );
|
||||
|
||||
return the_thread;
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
#include <rtems/score/objectimpl.h>
|
||||
|
||||
void _Thread_queue_Flush(
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
Thread_queue_Control *the_thread_queue,
|
||||
const Thread_queue_Operations *operations,
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
#else
|
||||
Thread_queue_Flush_callout remote_extract_callout RTEMS_UNUSED,
|
||||
Thread_queue_Flush_callout remote_extract_callout RTEMS_UNUSED,
|
||||
#endif
|
||||
uint32_t status
|
||||
uint32_t status
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
@@ -36,7 +37,14 @@ void _Thread_queue_Flush(
|
||||
|
||||
_Thread_queue_Acquire( the_thread_queue, &lock_context );
|
||||
|
||||
while ( (the_thread = _Thread_queue_First_locked( the_thread_queue ) ) ) {
|
||||
while (
|
||||
(
|
||||
the_thread = _Thread_queue_First_locked(
|
||||
the_thread_queue,
|
||||
operations
|
||||
)
|
||||
)
|
||||
) {
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( _Objects_Is_local_id( the_thread->Object.id ) )
|
||||
#endif
|
||||
@@ -44,7 +52,7 @@ void _Thread_queue_Flush(
|
||||
|
||||
_Thread_queue_Extract_critical(
|
||||
&the_thread_queue->Queue,
|
||||
the_thread_queue->operations,
|
||||
operations,
|
||||
the_thread,
|
||||
&lock_context
|
||||
);
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
|
||||
const char rtems_test_name[] = "SPTHREADQ 1";
|
||||
|
||||
static Thread_queue_Control fifo_queue =
|
||||
THREAD_QUEUE_FIFO_INITIALIZER( fifo_queue, "FIFO" );
|
||||
|
||||
static Thread_queue_Control prio_queue =
|
||||
THREAD_QUEUE_PRIORITY_INITIALIZER( prio_queue, "Prio" );
|
||||
static Thread_queue_Control queue = THREAD_QUEUE_INITIALIZER( "Queue" );
|
||||
|
||||
static rtems_task Init(
|
||||
rtems_task_argument ignored
|
||||
@@ -36,13 +32,7 @@ static rtems_task Init(
|
||||
_Thread_Enable_dispatch();
|
||||
/* is there more to check? */
|
||||
|
||||
rtems_test_assert( fifo_queue.Queue.heads == NULL );
|
||||
rtems_test_assert( fifo_queue.operations == &_Thread_queue_Operations_FIFO );
|
||||
|
||||
rtems_test_assert( prio_queue.Queue.heads == NULL );
|
||||
rtems_test_assert(
|
||||
prio_queue.operations == &_Thread_queue_Operations_priority
|
||||
);
|
||||
rtems_test_assert( queue.Queue.heads == NULL );
|
||||
|
||||
TEST_END();
|
||||
rtems_test_exit(0);
|
||||
|
||||
Reference in New Issue
Block a user