]> git.sur5r.net Git - freertos/blobdiff - Source/queue.c
Ensure the first task starts with interrupts enabled.
[freertos] / Source / queue.c
index 57f1e91cb8b888be01c37b763f620b29ab1e6424..d043f95ecc2b48e2c0bbecd53cd2d9c70b737f77 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry.\r
+       FreeRTOS.org V4.8.0 - Copyright (C) 2003-2008 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
        of http://www.FreeRTOS.org for full details of how and when the exception\r
        can be applied.\r
 \r
-       ***************************************************************************\r
+    ***************************************************************************\r
+    ***************************************************************************\r
+    *                                                                         *\r
+    * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
+    * and even write all or part of your application on your behalf.          *\r
+    * See http://www.OpenRTOS.com for details of the services we provide to   *\r
+    * expedite your project.                                                  *\r
+    *                                                                         *\r
+    ***************************************************************************\r
+    ***************************************************************************\r
 \r
        Please ensure to read the configuration and relevant port sections of the\r
        online documentation.\r
 \r
-       +++ http://www.FreeRTOS.org +++\r
-       Documentation, latest information, license and contact details.\r
+       http://www.FreeRTOS.org - Documentation, latest information, license and \r
+       contact details.\r
 \r
-       +++ http://www.SafeRTOS.com +++\r
-       A version that is certified for use in safety critical systems.\r
+       http://www.SafeRTOS.com - A version that is certified for use in safety \r
+       critical systems.\r
 \r
-       +++ http://www.OpenRTOS.com +++\r
-       Commercial support, development, porting, licensing and training services.\r
-\r
-       ***************************************************************************\r
+       http://www.OpenRTOS.com - Commercial support, development, porting, \r
+       licensing and training services.\r
 */\r
 \r
 #include <stdlib.h>\r
@@ -51,7 +58,9 @@
  *----------------------------------------------------------*/\r
 \r
 /* Constants used with the cRxLock and cTxLock structure members. */\r
-#define queueUNLOCKED  ( ( signed portBASE_TYPE ) -1 )\r
+#define queueUNLOCKED                                                  ( ( signed portBASE_TYPE ) -1 )\r
+#define queueLOCKED_UNMODIFIED                                 ( ( signed portBASE_TYPE ) 0 )\r
+\r
 #define queueERRONEOUS_UNBLOCK                                 ( -1 )\r
 \r
 /* For internal use only. */\r
@@ -118,8 +127,8 @@ portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlock
 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );\r
 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
-portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );\r
-portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );\r
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );\r
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );\r
 unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );\r
 \r
 \r
@@ -170,12 +179,20 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
  * Macro to mark a queue as locked.  Locking a queue prevents an ISR from\r
  * accessing the queue event lists.\r
  */\r
-#define prvLockQueue( pxQueue )                        \\r
-{                                                                              \\r
-       taskENTER_CRITICAL();                           \\r
-               ++( pxQueue->xRxLock );                 \\r
-               ++( pxQueue->xTxLock );                 \\r
-       taskEXIT_CRITICAL();                            \\r
+#define prvLockQueue( pxQueue )                                                        \\r
+{                                                                                                              \\r
+       taskENTER_CRITICAL();                                                           \\r
+       {                                                                                                       \\r
+               if( pxQueue->xRxLock == queueUNLOCKED )                 \\r
+               {                                                                                               \\r
+                       pxQueue->xRxLock = queueLOCKED_UNMODIFIED;      \\r
+               }                                                                                               \\r
+               if( pxQueue->xTxLock == queueUNLOCKED )                 \\r
+               {                                                                                               \\r
+                       pxQueue->xTxLock = queueLOCKED_UNMODIFIED;      \\r
+               }                                                                                               \\r
+       }                                                                                                       \\r
+       taskEXIT_CRITICAL();                                                            \\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -297,6 +314,8 @@ size_t xQueueSizeInBytes;
                mutual exclusion is required to test the pxMutexHolder variable. */\r
                if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
                {\r
+                       traceGIVE_MUTEX_RECURSIVE( pxMutex );\r
+\r
                        /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to\r
                        the task handle, therefore no underflow check is required.  Also,\r
                        uxRecursiveCallCount is only modified by the mutex holder, and as\r
@@ -312,9 +331,7 @@ size_t xQueueSizeInBytes;
                 xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
                        }\r
 \r
-                       xReturn = pdPASS;\r
-\r
-                       traceGIVE_MUTEX_RECURSIVE( pxMutex );\r
+                       xReturn = pdPASS;                       \r
                }\r
                else\r
                {\r
@@ -339,6 +356,8 @@ size_t xQueueSizeInBytes;
                /* Comments regarding mutual exclusion as per those within\r
                xQueueGiveMutexRecursive(). */\r
 \r
+               traceTAKE_MUTEX_RECURSIVE( pxMutex );\r
+\r
                if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
                {\r
                        ( pxMutex->uxRecursiveCallCount )++;\r
@@ -354,9 +373,7 @@ size_t xQueueSizeInBytes;
                        {\r
                                ( pxMutex->uxRecursiveCallCount )++;\r
                        }\r
-               }\r
-\r
-               traceTAKE_MUTEX_RECURSIVE( pxMutex );\r
+               }               \r
 \r
                return xReturn;\r
        }\r
@@ -493,7 +510,7 @@ xTimeOutType xTimeOut;
 \r
                if( xReturn == errQUEUE_FULL )\r
                {\r
-                       if( xTicksToWait > 0 )\r
+                       if( xTicksToWait > ( portTickType ) 0 )\r
                        {\r
                                if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                {\r
@@ -605,7 +622,7 @@ xTimeOutType xTimeOut;
 \r
                        if( xReturn == errQUEUE_FULL )\r
                        {\r
-                               if( xTicksToWait > 0 )\r
+                               if( xTicksToWait > ( portTickType ) 0 )\r
                                {\r
                                        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                        {\r
@@ -757,7 +774,7 @@ xTimeOutType xTimeOut;
 \r
                        if( xReturn == errQUEUE_EMPTY )\r
                        {\r
-                               if( xTicksToWait > 0 )\r
+                               if( xTicksToWait > ( portTickType ) 0 )\r
                                {\r
                                        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                        {\r
@@ -1127,13 +1144,9 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
        updated. */\r
        taskENTER_CRITICAL();\r
        {\r
-               --( pxQueue->xTxLock );\r
-\r
                /* See if data was added to the queue while it was locked. */\r
-               if( pxQueue->xTxLock > queueUNLOCKED )\r
+               while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )\r
                {\r
-                       pxQueue->xTxLock = queueUNLOCKED;\r
-\r
                        /* Data was posted while the queue was locked.  Are any tasks\r
                        blocked waiting for data to become available? */\r
                        if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
@@ -1146,28 +1159,40 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
                                        context switch is required. */\r
                                        vTaskMissedYield();\r
                                }\r
-                       }                       \r
+\r
+                               --( pxQueue->xTxLock );\r
+                       }\r
+                       else\r
+                       {\r
+                               break;\r
+                       }\r
                }\r
+\r
+               pxQueue->xTxLock = queueUNLOCKED;\r
        }\r
        taskEXIT_CRITICAL();\r
 \r
        /* Do the same for the Rx lock. */\r
        taskENTER_CRITICAL();\r
        {\r
-               --( pxQueue->xRxLock );\r
-\r
-               if( pxQueue->xRxLock > queueUNLOCKED )\r
+               while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )\r
                {\r
-                       pxQueue->xRxLock = queueUNLOCKED;\r
-\r
                        if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
                        {\r
                                if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
                                {\r
                                        vTaskMissedYield();\r
                                }\r
-                       }                       \r
+\r
+                               --( pxQueue->xRxLock );\r
+                       }\r
+                       else\r
+                       {\r
+                               break;\r
+                       }\r
                }\r
+\r
+               pxQueue->xRxLock = queueUNLOCKED;\r
        }\r
        taskEXIT_CRITICAL();\r
 }\r