]> git.sur5r.net Git - freertos/commitdiff
Add test and correct code for the unusual case of a task using an event group to...
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 31 Mar 2014 02:12:17 +0000 (02:12 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 31 Mar 2014 02:12:17 +0000 (02:12 +0000)
Add critical sections around call to prvResetNextTaskUnblockTime() that can occur from within a task.

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

FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
FreeRTOS/Source/event_groups.c
FreeRTOS/Source/tasks.c

index daf5189508ad8463030ca34a1e7deea95f14a8c7..4890fde4b359efed5f6995ba9ed308090dcd03ab 100644 (file)
@@ -544,6 +544,38 @@ EventBits_t uxBits;
                xError = pdTRUE;\r
        }\r
 \r
+       /* Try a synch with no other tasks involved.  First set all the bits other\r
+       than this task's bit. */\r
+       xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );\r
+\r
+       /* Then wait on just one bit - the bit that is being set. */\r
+       uxBits = xEventGroupSync( xEventGroup,                  /* The event group used for the synchronisation. */\r
+                                                       ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */\r
+                                                       ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */\r
+                                                       portMAX_DELAY );                /* The maximum time to wait for the sync condition to be met. */\r
+\r
+       /* A sync with a max delay should only exit when all the synchronise\r
+       bits are set...check that is the case.  In this case there is only one\r
+       sync bit anyway. */\r
+       if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )\r
+       {\r
+               xError = pdTRUE;\r
+       }\r
+\r
+       /* ...but now the sync bits should be clear again, leaving all the other\r
+       bits set (as only one bit was being waited for). */\r
+       if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )\r
+       {\r
+               xError = pdTRUE;\r
+       }\r
+\r
+       /* Clear all the bits to zero again. */\r
+       xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );\r
+       if( xEventGroupGetBits( xEventGroup ) != 0 )\r
+       {\r
+               xError = pdTRUE;\r
+       }\r
+\r
        /* Unsuspend the other tasks then check they have executed up to the\r
        synchronisation point. */\r
        vTaskResume( xTestSlaveTaskHandle );\r
index c7194016ec85fa4889ae5230856b7f49472b8fef..5b45f9cc783807abd2aaa34161aa7bf37387e613 100644 (file)
@@ -179,7 +179,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 \r
                        /* Rendezvous always clear the bits.  They will have been cleared\r
                        already unless this is the only task in the rendezvous. */\r
-                       pxEventBits->uxEventBits &= uxBitsToWaitFor;\r
+                       pxEventBits->uxEventBits &= ~uxBitsToWaitFor;\r
 \r
                        xTicksToWait = 0;\r
                }\r
index 8512e1bbc6ed75dea716716ba54ae24f557b9409..c20aeed54043a8aa8fcaeac21ce055970b33a1ba 100644 (file)
@@ -760,7 +760,11 @@ TCB_t * pxNewTCB;
                        {\r
                                /* Reset the next expected unblock time in case it referred to\r
                                the task that has just been deleted. */\r
-                               prvResetNextTaskUnblockTime();\r
+                               taskENTER_CRITICAL();\r
+                               {\r
+                                       prvResetNextTaskUnblockTime();\r
+                               }\r
+                               taskEXIT_CRITICAL();\r
                        }\r
                }\r
        }\r
@@ -1259,7 +1263,11 @@ TCB_t * pxNewTCB;
                                /* A task other than the currently running task was suspended,\r
                                reset the next expected unblock time in case it referred to the\r
                                task that is now in the Suspended state. */\r
-                               prvResetNextTaskUnblockTime();\r
+                               taskENTER_CRITICAL();\r
+                               {\r
+                                       prvResetNextTaskUnblockTime();\r
+                               }\r
+                               taskEXIT_CRITICAL();\r
                        }\r
                        else\r
                        {\r