From d63dac0320316fe803ab0110edeb1dcf748ad21d Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 23 Sep 2016 17:43:52 +0800 Subject: [PATCH] Remove all references to prvLockQueue / prvUnlockQueue --- components/esp32/lib | 2 +- components/freertos/queue.c | 389 ++++++++---------------------------- 2 files changed, 87 insertions(+), 304 deletions(-) diff --git a/components/esp32/lib b/components/esp32/lib index f6d558367..1303c92c1 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit f6d558367a08b6c9b18c2de515bd0a6740d2c45c +Subproject commit 1303c92c1056b7f59b95360b58e70a21cb4a93e1 diff --git a/components/freertos/queue.c b/components/freertos/queue.c index 248ae7c00..1fb0552d4 100644 --- a/components/freertos/queue.c +++ b/components/freertos/queue.c @@ -100,11 +100,6 @@ header files above, but not in this file, in order to generate the correct privileged Vs unprivileged linkage and placement. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ - -/* Constants used with the xRxLock and xTxLock structure members. */ -#define queueUNLOCKED ( ( BaseType_t ) -1 ) -#define queueLOCKED_UNMODIFIED ( ( BaseType_t ) 0 ) - /* When the Queue_t structure is used to represent a base queue its pcHead and pcTail members are used as pointers into the queue storage area. When the Queue_t structure is used to represent a mutex pcHead and pcTail pointers are @@ -163,9 +158,6 @@ typedef struct QueueDefinition UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ - volatile BaseType_t xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ - volatile BaseType_t xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ - #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxQueueNumber; uint8_t ucQueueType; @@ -212,15 +204,6 @@ typedef xQUEUE Queue_t; #endif /* configQUEUE_REGISTRY_SIZE */ -/* - * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not - * prevent an ISR from adding or removing items to the queue, but does prevent - * an ISR from removing tasks from the queue event lists. If an ISR finds a - * queue is locked it will instead increment the appropriate queue lock count - * to indicate that a task may require unblocking. When the queue in unlocked - * these lock counts are inspected, and the appropriate action taken. - */ -static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; /* * Uses a critical section to determine if there is any data in a queue. @@ -255,27 +238,6 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; #endif -/*-----------------------------------------------------------*/ - -/* - * Macro to mark a queue as locked. Locking a queue prevents an ISR from - * accessing the queue event lists. - */ -#define prvLockQueue( pxQueue ) \ - taskENTER_CRITICAL(&pxQueue->mux); \ - { \ - if( ( pxQueue )->xRxLock == queueUNLOCKED ) \ - { \ - ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \ - } \ - if( ( pxQueue )->xTxLock == queueUNLOCKED ) \ - { \ - ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \ - } \ - } \ - taskEXIT_CRITICAL(&pxQueue->mux) -/*-----------------------------------------------------------*/ - BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) { Queue_t * const pxQueue = ( Queue_t * ) xQueue; @@ -292,8 +254,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; pxQueue->pcWriteTo = pxQueue->pcHead; pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize ); - pxQueue->xRxLock = queueUNLOCKED; - pxQueue->xTxLock = queueUNLOCKED; if( xNewQueue == pdFALSE ) { @@ -441,8 +401,6 @@ int8_t *pcAllocatedBuffer; pxNewQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; pxNewQueue->uxLength = ( UBaseType_t ) 1U; pxNewQueue->uxItemSize = ( UBaseType_t ) 0U; - pxNewQueue->xRxLock = queueUNLOCKED; - pxNewQueue->xTxLock = queueUNLOCKED; #if ( configUSE_TRACE_FACILITY == 1 ) { @@ -787,7 +745,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; now the critical section has been exited. */ taskENTER_CRITICAL(&pxQueue->mux); -// prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) @@ -797,13 +754,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; traceBLOCKING_ON_QUEUE_SEND( pxQueue ); vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); - /* Unlocking the queue means queue events can effect the - event list. It is possible that interrupts occurring now - remove this task from the event list again - but as the - scheduler is suspended the task will go onto the pending - ready last instead of the actual ready list. */ -// prvUnlockQueue( pxQueue ); - /* Resuming the scheduler will move tasks from the pending ready list into the ready list - so it is feasible that this @@ -816,14 +766,12 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; else { /* Try again. */ -// prvUnlockQueue( pxQueue ); taskEXIT_CRITICAL(&pxQueue->mux); } } else { /* The timeout has expired. */ -// prvUnlockQueue( pxQueue ); taskEXIT_CRITICAL(&pxQueue->mux); /* Return to the original privilege level before exiting the @@ -1129,27 +1077,18 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; disinheritance here or to clear the mutex holder TCB member. */ ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); - /* The event list is not altered if the queue is locked. This will - be done when the queue is unlocked later. */ - if( pxQueue->xTxLock == queueUNLOCKED ) + #if ( configUSE_QUEUE_SETS == 1 ) { - #if ( configUSE_QUEUE_SETS == 1 ) + if( pxQueue->pxQueueSetContainer != NULL ) { - if( pxQueue->pxQueueSetContainer != NULL ) + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) { - if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) { - /* The queue is a member of a queue set, and posting - to the queue set caused a higher priority task to - unblock. A context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + *pxHigherPriorityTaskWoken = pdTRUE; } else { @@ -1158,40 +1097,17 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; } else { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so - record that a context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + mtCOVERAGE_TEST_MARKER(); } } - #else /* configUSE_QUEUE_SETS */ + else { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { - /* The task waiting has a higher priority so record that a - context switch is required. */ + /* The task waiting has a higher priority so + record that a context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; @@ -1211,16 +1127,35 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; mtCOVERAGE_TEST_MARKER(); } } - #endif /* configUSE_QUEUE_SETS */ } - else + #else /* configUSE_QUEUE_SETS */ { - /* Increment the lock count so the task that unlocks the queue - knows that data was posted while it was locked. */ - ++( pxQueue->xTxLock ); + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } - - xReturn = pdPASS; + #endif /* configUSE_QUEUE_SETS */ } else { @@ -1285,27 +1220,18 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; ++( pxQueue->uxMessagesWaiting ); - /* The event list is not altered if the queue is locked. This will - be done when the queue is unlocked later. */ - if( pxQueue->xTxLock == queueUNLOCKED ) + #if ( configUSE_QUEUE_SETS == 1 ) { - #if ( configUSE_QUEUE_SETS == 1 ) + if( pxQueue->pxQueueSetContainer != NULL ) { - if( pxQueue->pxQueueSetContainer != NULL ) + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE ) { - if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE ) + /* The semaphore is a member of a queue set, and + posting to the queue set caused a higher priority + task to unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) { - /* The semaphore is a member of a queue set, and - posting to the queue set caused a higher priority - task to unblock. A context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + *pxHigherPriorityTaskWoken = pdTRUE; } else { @@ -1314,40 +1240,17 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; } else { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so - record that a context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + mtCOVERAGE_TEST_MARKER(); } } - #else /* configUSE_QUEUE_SETS */ + else { if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) { - /* The task waiting has a higher priority so record that a - context switch is required. */ + /* The task waiting has a higher priority so + record that a context switch is required. */ if( pxHigherPriorityTaskWoken != NULL ) { *pxHigherPriorityTaskWoken = pdTRUE; @@ -1367,14 +1270,35 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; mtCOVERAGE_TEST_MARKER(); } } - #endif /* configUSE_QUEUE_SETS */ } - else + #else /* configUSE_QUEUE_SETS */ { - /* Increment the lock count so the task that unlocks the queue - knows that data was posted while it was locked. */ - ++( pxQueue->xTxLock ); + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } + #endif /* configUSE_QUEUE_SETS */ xReturn = pdPASS; } @@ -1525,7 +1449,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; now the critical section has been exited. */ taskENTER_CRITICAL(&pxQueue->mux); -// prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) @@ -1548,20 +1471,17 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; #endif vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); -// prvUnlockQueue( pxQueue ); taskEXIT_CRITICAL(&pxQueue->mux); portYIELD_WITHIN_API(); } else { /* Try again. */ -// prvUnlockQueue( pxQueue ); taskEXIT_CRITICAL(&pxQueue->mux); } } else { -// prvUnlockQueue( pxQueue ); taskEXIT_CRITICAL(&pxQueue->mux); traceQUEUE_RECEIVE_FAILED( pxQueue ); return errQUEUE_EMPTY; @@ -1606,26 +1526,15 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; prvCopyDataFromQueue( pxQueue, pvBuffer ); --( pxQueue->uxMessagesWaiting ); - /* If the queue is locked the event list will not be modified. - Instead update the lock count so the task that unlocks the queue - will know that an ISR has removed data while the queue was - locked. */ - if( pxQueue->xRxLock == queueUNLOCKED ) + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) { - /* The task waiting has a higher priority than us so - force a context switch. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + *pxHigherPriorityTaskWoken = pdTRUE; } else { @@ -1639,9 +1548,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; } else { - /* Increment the lock count so the task that unlocks the queue - knows that data was removed while it was locked. */ - ++( pxQueue->xRxLock ); + mtCOVERAGE_TEST_MARKER(); } xReturn = pdPASS; @@ -1902,129 +1809,7 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */ } } -/*-----------------------------------------------------------*/ -static void prvUnlockQueue( Queue_t * const pxQueue ) -{ - /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ - - /* The lock counts contains the number of extra data items placed or - removed from the queue while the queue was locked. When a queue is - locked items can be added or removed, but the event lists cannot be - updated. */ - taskENTER_CRITICAL(&pxQueue->mux); - { - /* See if data was added to the queue while it was locked. */ - while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) - { - /* Data was posted while the queue was locked. Are any tasks - blocked waiting for data to become available? */ - #if ( configUSE_QUEUE_SETS == 1 ) - { - if( pxQueue->pxQueueSetContainer != NULL ) - { - if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE ) - { - /* The queue is a member of a queue set, and posting to - the queue set caused a higher priority task to unblock. - A context switch is required. */ - taskEXIT_CRITICAL(&pxQueue->mux); //ToDo: Is aquire/release needed around any of the bTaskMissedYield calls? - vTaskMissedYield(); - taskENTER_CRITICAL(&pxQueue->mux); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - /* Tasks that are removed from the event list will get added to - the pending ready list as the scheduler is still suspended. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so record that a - context switch is required. */ - taskEXIT_CRITICAL(&pxQueue->mux); - vTaskMissedYield(); - taskENTER_CRITICAL(&pxQueue->mux); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - break; - } - } - } - #else /* configUSE_QUEUE_SETS */ - { - /* Tasks that are removed from the event list will get added to - the pending ready list as the scheduler is still suspended. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so record that a - context switch is required. */ - taskEXIT_CRITICAL(&pxQueue->mux); - vTaskMissedYield(); - taskENTER_CRITICAL(&pxQueue->mux); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - break; - } - } - #endif /* configUSE_QUEUE_SETS */ - - --( pxQueue->xTxLock ); - } - - pxQueue->xTxLock = queueUNLOCKED; - } - taskEXIT_CRITICAL(&pxQueue->mux); - - /* Do the same for the Rx lock. */ - taskENTER_CRITICAL(&pxQueue->mux); - { - while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - taskEXIT_CRITICAL(&pxQueue->mux); - vTaskMissedYield(); - taskENTER_CRITICAL(&pxQueue->mux); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - --( pxQueue->xRxLock ); - } - else - { - break; - } - } - - pxQueue->xRxLock = queueUNLOCKED; - } - taskEXIT_CRITICAL(&pxQueue->mux); -} /*-----------------------------------------------------------*/ static BaseType_t prvIsQueueEmpty( Queue_t *pxQueue ) @@ -2458,10 +2243,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; /* Only do anything if there are no messages in the queue. This function will not actually cause the task to block, just place it on a blocked list. It will not block until the scheduler is unlocked - at which - time a yield will be performed. If an item is added to the queue while - the queue is locked, and the calling task blocks on the queue, then the - calling task will be immediately unblocked when the queue is unlocked. */ -// prvLockQueue( pxQueue ); + time a yield will be performed. */ + taskENTER_CRITICAL(&pxQueue->mux); if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) { /* There is nothing in the queue, block for the specified period. */ @@ -2471,7 +2254,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; { mtCOVERAGE_TEST_MARKER(); } -// prvUnlockQueue( pxQueue ); + taskEXIT_CRITICAL(&pxQueue->mux); } #endif /* configUSE_TIMERS */