]> git.sur5r.net Git - freertos/commitdiff
Fix bug when xQueueOverwrite() and xQueueOverwrite() from ISR are used to overwrite...
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 3 Dec 2019 01:50:07 +0000 (01:50 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 3 Dec 2019 01:50:07 +0000 (01:50 +0000)
Minor queue optimisations.

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2758 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Source/queue.c

index 6f79c9211f87b60cae1b794ac3492acd61ef94b8..103718dba86addb6d240b17a2a96dc7e95c4f4ea 100644 (file)
@@ -203,7 +203,7 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer
         * Checks to see if a queue is a member of a queue set, and if so, notifies\r
         * the queue set that the queue contains data.\r
         */\r
-       static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;\r
+       static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;\r
 #endif\r
 \r
 /*\r
@@ -373,17 +373,10 @@ Queue_t * const pxQueue = xQueue;
 \r
                configASSERT( uxQueueLength > ( UBaseType_t ) 0 );\r
 \r
-               if( uxItemSize == ( UBaseType_t ) 0 )\r
-               {\r
-                       /* There is not going to be a queue storage area. */\r
-                       xQueueSizeInBytes = ( size_t ) 0;\r
-               }\r
-               else\r
-               {\r
-                       /* Allocate enough space to hold the maximum number of items that\r
-                       can be in the queue at any time. */\r
-                       xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
-               }\r
+               /* Allocate enough space to hold the maximum number of items that\r
+               can be in the queue at any time.  It is valid for uxItemSize to be\r
+               zero in the case the queue is used as a semaphore. */\r
+               xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
 \r
                /* Allocate the queue and storage area.  Justification for MISRA\r
                deviation as follows:  pvPortMalloc() always ensures returned memory\r
@@ -777,7 +770,7 @@ Queue_t * const pxQueue = xQueue;
 \r
                                #if ( configUSE_QUEUE_SETS == 1 )\r
                                {\r
-                               UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;\r
+                               const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;\r
 \r
                                        xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
 \r
@@ -790,7 +783,7 @@ Queue_t * const pxQueue = xQueue;
                                                        in the queue has not changed. */\r
                                                        mtCOVERAGE_TEST_MARKER();\r
                                                }\r
-                                               else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )\r
+                                               else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
                                                {\r
                                                        /* The queue is a member of a queue set, and posting\r
                                                        to the queue set caused a higher priority task to\r
@@ -993,22 +986,31 @@ Queue_t * const pxQueue = xQueue;
 \r
                        traceQUEUE_SEND_FROM_ISR( pxQueue );\r
 \r
-                       /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
-                       semaphore or mutex.  That means prvCopyDataToQueue() cannot result\r
-                       in a task disinheriting a priority and prvCopyDataToQueue() can be\r
-                       called here even though the disinherit function does not check if\r
-                       the scheduler is suspended before accessing the ready lists. */\r
-                       ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-\r
                        /* The event list is not altered if the queue is locked.  This will\r
                        be done when the queue is unlocked later. */\r
                        if( cTxLock == queueUNLOCKED )\r
                        {\r
                                #if ( configUSE_QUEUE_SETS == 1 )\r
                                {\r
+                                       const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;\r
+\r
+                                       /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
+                                       semaphore or mutex.  That means prvCopyDataToQueue() cannot result\r
+                                       in a task disinheriting a priority and prvCopyDataToQueue() can be\r
+                                       called here even though the disinherit function does not check if\r
+                                       the scheduler is suspended before accessing the ready lists. */\r
+                                       ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
                                        if( pxQueue->pxQueueSetContainer != NULL )\r
                                        {\r
-                                               if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )\r
+                                               if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) )\r
+                                               {\r
+                                                       /* Do not notify the queue set as an existing item\r
+                                                       was overwritten in the queue so the number of items\r
+                                                       in the queue has not changed. */\r
+                                                       mtCOVERAGE_TEST_MARKER();\r
+                                               }\r
+                                               else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
                                                {\r
                                                        /* The queue is a member of a queue set, and posting\r
                                                        to the queue set caused a higher priority task to\r
@@ -1057,6 +1059,13 @@ Queue_t * const pxQueue = xQueue;
                                }\r
                                #else /* configUSE_QUEUE_SETS */\r
                                {\r
+                                       /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
+                                       semaphore or mutex.  That means prvCopyDataToQueue() cannot result\r
+                                       in a task disinheriting a priority and prvCopyDataToQueue() can be\r
+                                       called here even though the disinherit function does not check if\r
+                                       the scheduler is suspended before accessing the ready lists. */\r
+                                       ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
                                        if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
                                        {\r
                                                if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
@@ -1173,7 +1182,7 @@ Queue_t * const pxQueue = xQueue;
                                {\r
                                        if( pxQueue->pxQueueSetContainer != NULL )\r
                                        {\r
-                                               if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE )\r
+                                               if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
                                                {\r
                                                        /* The semaphore is a member of a queue set, and\r
                                                        posting to the queue set caused a higher priority\r
@@ -2185,7 +2194,7 @@ static void prvUnlockQueue( Queue_t * const pxQueue )
                        {\r
                                if( pxQueue->pxQueueSetContainer != NULL )\r
                                {\r
-                                       if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE )\r
+                                       if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )\r
                                        {\r
                                                /* The queue is a member of a queue set, and posting to\r
                                                the queue set caused a higher priority task to unblock.\r
@@ -2875,7 +2884,7 @@ Queue_t * const pxQueue = xQueue;
 \r
 #if ( configUSE_QUEUE_SETS == 1 )\r
 \r
-       static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition )\r
+       static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue )\r
        {\r
        Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer;\r
        BaseType_t xReturn = pdFALSE;\r
@@ -2892,7 +2901,7 @@ Queue_t * const pxQueue = xQueue;
                        traceQUEUE_SEND( pxQueueSetContainer );\r
 \r
                        /* The data copied is the handle of the queue that contains data. */\r
-                       xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
+                       xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, queueSEND_TO_BACK );\r
 \r
                        if( cTxLock == queueUNLOCKED )\r
                        {\r