mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Replace the #define that maps the uxRecursiveCallCount to the pcReadFrom pointer with a union - although this is against the coding standard it seemed the best way of ensuring complete adherence to the C standard and allow correct builds with LLVM when the optimiser is on.
This commit is contained in:
parent
00136d4b51
commit
cdae14a8cb
|
@ -96,13 +96,22 @@ task.h is included from an application file. */
|
||||||
|
|
||||||
#define queueERRONEOUS_UNBLOCK ( -1 )
|
#define queueERRONEOUS_UNBLOCK ( -1 )
|
||||||
|
|
||||||
/* Effectively make a union out of the xQUEUE structure. */
|
/* When the xQUEUE structure is used to represent a base queue its pcHead and
|
||||||
|
pcTail members are used as pointers into the queue storage area. When the
|
||||||
|
xQUEUE structure is used to represent a mutex pcHead and pcTail pointers are
|
||||||
|
not necessary, and the pcHead pointer is set to NULL to indicate that the
|
||||||
|
pcTail pointer actually points to the mutex holder (if any). Map alternative
|
||||||
|
names to the pcHead and pcTail structure members to ensure the readability of
|
||||||
|
the code is maintained despite this dual use of two structure members. An
|
||||||
|
alternative implementation would be to use a union, but use of a union is
|
||||||
|
against the coding standard (although an exception to the standard has been
|
||||||
|
permitted where the dual use also significantly changes the type of the
|
||||||
|
structure member). */
|
||||||
#define pxMutexHolder pcTail
|
#define pxMutexHolder pcTail
|
||||||
#define uxQueueType pcHead
|
#define uxQueueType pcHead
|
||||||
#define uxRecursiveCallCount pcReadFrom
|
|
||||||
#define queueQUEUE_IS_MUTEX NULL
|
#define queueQUEUE_IS_MUTEX NULL
|
||||||
|
|
||||||
/* Semaphores do not actually store or copy data, so have an items size of
|
/* Semaphores do not actually store or copy data, so have an item size of
|
||||||
zero. */
|
zero. */
|
||||||
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )
|
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )
|
||||||
#define queueDONT_BLOCK ( ( portTickType ) 0U )
|
#define queueDONT_BLOCK ( ( portTickType ) 0U )
|
||||||
|
@ -119,7 +128,12 @@ typedef struct QueueDefinition
|
||||||
signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
|
signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
|
||||||
|
|
||||||
signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
|
signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
|
||||||
signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
|
|
||||||
|
union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */
|
||||||
|
{
|
||||||
|
signed char *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */
|
||||||
|
unsigned portBASE_TYPE uxRecursiveCallCount;/*< Maintains a count of the numebr of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */
|
||||||
|
} u;
|
||||||
|
|
||||||
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
|
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
|
||||||
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
|
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
|
||||||
|
@ -241,7 +255,7 @@ xQUEUE *pxQueue;
|
||||||
pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );
|
pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );
|
||||||
pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
|
pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
|
||||||
pxQueue->pcWriteTo = pxQueue->pcHead;
|
pxQueue->pcWriteTo = pxQueue->pcHead;
|
||||||
pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );
|
pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );
|
||||||
pxQueue->xRxLock = queueUNLOCKED;
|
pxQueue->xRxLock = queueUNLOCKED;
|
||||||
pxQueue->xTxLock = queueUNLOCKED;
|
pxQueue->xTxLock = queueUNLOCKED;
|
||||||
|
|
||||||
|
@ -354,7 +368,7 @@ xQueueHandle xReturn = NULL;
|
||||||
/* Queues used as a mutex no data is actually copied into or out
|
/* Queues used as a mutex no data is actually copied into or out
|
||||||
of the queue. */
|
of the queue. */
|
||||||
pxNewQueue->pcWriteTo = NULL;
|
pxNewQueue->pcWriteTo = NULL;
|
||||||
pxNewQueue->pcReadFrom = NULL;
|
pxNewQueue->u.pcReadFrom = NULL;
|
||||||
|
|
||||||
/* Each mutex has a length of 1 (like a binary semaphore) and
|
/* Each mutex has a length of 1 (like a binary semaphore) and
|
||||||
an item size of 0 as nothing is actually copied into or out
|
an item size of 0 as nothing is actually copied into or out
|
||||||
|
@ -444,7 +458,7 @@ xQueueHandle xReturn = NULL;
|
||||||
this is the only condition we are interested in it does not matter if
|
this is the only condition we are interested in it does not matter if
|
||||||
pxMutexHolder is accessed simultaneously by another task. Therefore no
|
pxMutexHolder is accessed simultaneously by another task. Therefore no
|
||||||
mutual exclusion is required to test the pxMutexHolder variable. */
|
mutual exclusion is required to test the pxMutexHolder variable. */
|
||||||
if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
|
if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() )
|
||||||
{
|
{
|
||||||
traceGIVE_MUTEX_RECURSIVE( pxMutex );
|
traceGIVE_MUTEX_RECURSIVE( pxMutex );
|
||||||
|
|
||||||
|
@ -453,10 +467,10 @@ xQueueHandle xReturn = NULL;
|
||||||
uxRecursiveCallCount is only modified by the mutex holder, and as
|
uxRecursiveCallCount is only modified by the mutex holder, and as
|
||||||
there can only be one, no mutual exclusion is required to modify the
|
there can only be one, no mutual exclusion is required to modify the
|
||||||
uxRecursiveCallCount member. */
|
uxRecursiveCallCount member. */
|
||||||
( pxMutex->uxRecursiveCallCount )--;
|
( pxMutex->u.uxRecursiveCallCount )--;
|
||||||
|
|
||||||
/* Have we unwound the call count? */
|
/* Have we unwound the call count? */
|
||||||
if( pxMutex->uxRecursiveCallCount == 0 )
|
if( pxMutex->u.uxRecursiveCallCount == 0 )
|
||||||
{
|
{
|
||||||
/* Return the mutex. This will automatically unblock any other
|
/* Return the mutex. This will automatically unblock any other
|
||||||
task that might be waiting to access the mutex. */
|
task that might be waiting to access the mutex. */
|
||||||
|
@ -494,9 +508,9 @@ xQueueHandle xReturn = NULL;
|
||||||
|
|
||||||
traceTAKE_MUTEX_RECURSIVE( pxMutex );
|
traceTAKE_MUTEX_RECURSIVE( pxMutex );
|
||||||
|
|
||||||
if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
|
if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() )
|
||||||
{
|
{
|
||||||
( pxMutex->uxRecursiveCallCount )++;
|
( pxMutex->u.uxRecursiveCallCount )++;
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -507,7 +521,7 @@ xQueueHandle xReturn = NULL;
|
||||||
we may have blocked to reach here. */
|
we may have blocked to reach here. */
|
||||||
if( xReturn == pdPASS )
|
if( xReturn == pdPASS )
|
||||||
{
|
{
|
||||||
( pxMutex->uxRecursiveCallCount )++;
|
( pxMutex->u.uxRecursiveCallCount )++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -800,7 +814,7 @@ xQUEUE *pxQueue;
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
{
|
{
|
||||||
/* Remember our read position in case we are just peeking. */
|
/* Remember our read position in case we are just peeking. */
|
||||||
pcOriginalReadPosition = pxQueue->pcReadFrom;
|
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
|
||||||
|
|
||||||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||||
|
|
||||||
|
@ -817,7 +831,7 @@ xQUEUE *pxQueue;
|
||||||
{
|
{
|
||||||
/* Record the information required to implement
|
/* Record the information required to implement
|
||||||
priority inheritance should it become necessary. */
|
priority inheritance should it become necessary. */
|
||||||
pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
|
pxQueue->pxMutexHolder = ( void * ) xTaskGetCurrentTaskHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -836,7 +850,7 @@ xQUEUE *pxQueue;
|
||||||
|
|
||||||
/* We are not removing the data, so reset our read
|
/* We are not removing the data, so reset our read
|
||||||
pointer. */
|
pointer. */
|
||||||
pxQueue->pcReadFrom = pcOriginalReadPosition;
|
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
|
||||||
|
|
||||||
/* The data is being left in the queue, so see if there are
|
/* The data is being left in the queue, so see if there are
|
||||||
any other tasks waiting for the data. */
|
any other tasks waiting for the data. */
|
||||||
|
@ -1033,7 +1047,7 @@ xQUEUE *pxQueue;
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
{
|
{
|
||||||
/* Remember our read position in case we are just peeking. */
|
/* Remember our read position in case we are just peeking. */
|
||||||
pcOriginalReadPosition = pxQueue->pcReadFrom;
|
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
|
||||||
|
|
||||||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||||
|
|
||||||
|
@ -1050,7 +1064,7 @@ xQUEUE *pxQueue;
|
||||||
{
|
{
|
||||||
/* Record the information required to implement
|
/* Record the information required to implement
|
||||||
priority inheritance should it become necessary. */
|
priority inheritance should it become necessary. */
|
||||||
pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
|
pxQueue->pxMutexHolder = ( void * ) xTaskGetCurrentTaskHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1069,7 +1083,7 @@ xQUEUE *pxQueue;
|
||||||
|
|
||||||
/* The data is not being removed, so reset the read
|
/* The data is not being removed, so reset the read
|
||||||
pointer. */
|
pointer. */
|
||||||
pxQueue->pcReadFrom = pcOriginalReadPosition;
|
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
|
||||||
|
|
||||||
/* The data is being left in the queue, so see if there are
|
/* The data is being left in the queue, so see if there are
|
||||||
any other tasks waiting for the data. */
|
any other tasks waiting for the data. */
|
||||||
|
@ -1319,11 +1333,11 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
|
memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
|
||||||
pxQueue->pcReadFrom -= pxQueue->uxItemSize;
|
pxQueue->u.pcReadFrom -= pxQueue->uxItemSize;
|
||||||
if( pxQueue->pcReadFrom < pxQueue->pcHead )
|
if( pxQueue->u.pcReadFrom < pxQueue->pcHead )
|
||||||
{
|
{
|
||||||
pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
|
pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1335,12 +1349,12 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
|
||||||
{
|
{
|
||||||
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
|
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
|
||||||
{
|
{
|
||||||
pxQueue->pcReadFrom += pxQueue->uxItemSize;
|
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
|
||||||
if( pxQueue->pcReadFrom >= pxQueue->pcTail )
|
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
|
||||||
{
|
{
|
||||||
pxQueue->pcReadFrom = pxQueue->pcHead;
|
pxQueue->u.pcReadFrom = pxQueue->pcHead;
|
||||||
}
|
}
|
||||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( size_t ) pxQueue->uxItemSize );
|
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -1633,13 +1647,13 @@ signed portBASE_TYPE xReturn;
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
{
|
{
|
||||||
/* Data is available from the queue. */
|
/* Data is available from the queue. */
|
||||||
pxQueue->pcReadFrom += pxQueue->uxItemSize;
|
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
|
||||||
if( pxQueue->pcReadFrom >= pxQueue->pcTail )
|
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
|
||||||
{
|
{
|
||||||
pxQueue->pcReadFrom = pxQueue->pcHead;
|
pxQueue->u.pcReadFrom = pxQueue->pcHead;
|
||||||
}
|
}
|
||||||
--( pxQueue->uxMessagesWaiting );
|
--( pxQueue->uxMessagesWaiting );
|
||||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
||||||
|
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
|
||||||
|
@ -1717,13 +1731,13 @@ signed portBASE_TYPE xReturn;
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
{
|
{
|
||||||
/* Copy the data from the queue. */
|
/* Copy the data from the queue. */
|
||||||
pxQueue->pcReadFrom += pxQueue->uxItemSize;
|
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
|
||||||
if( pxQueue->pcReadFrom >= pxQueue->pcTail )
|
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
|
||||||
{
|
{
|
||||||
pxQueue->pcReadFrom = pxQueue->pcHead;
|
pxQueue->u.pcReadFrom = pxQueue->pcHead;
|
||||||
}
|
}
|
||||||
--( pxQueue->uxMessagesWaiting );
|
--( pxQueue->uxMessagesWaiting );
|
||||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
|
||||||
|
|
||||||
if( ( *pxCoRoutineWoken ) == pdFALSE )
|
if( ( *pxCoRoutineWoken ) == pdFALSE )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue