summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2014-03-31 02:12:17 +0000
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2014-03-31 02:12:17 +0000
commit26371a5b292773fbc7448d59ed6c13c9d92fd4e5 (patch)
tree026b8857d2f8ba9d9377ff62f1e176a6b9b0fca0
parenta41d0c972157017a015d36e34c81b57cef4eecec (diff)
downloadfreertos-26371a5b292773fbc7448d59ed6c13c9d92fd4e5.tar.gz
Add test and correct code for the unusual case of a task using an event group to synchronise only with itself.
Add critical sections around call to prvResetNextTaskUnblockTime() that can occur from within a task. git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@2233 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
-rw-r--r--FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c32
-rw-r--r--FreeRTOS/Source/event_groups.c2
-rw-r--r--FreeRTOS/Source/tasks.c12
3 files changed, 43 insertions, 3 deletions
diff --git a/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c b/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
index daf518950..4890fde4b 100644
--- a/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
+++ b/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
@@ -544,6 +544,38 @@ EventBits_t uxBits;
xError = pdTRUE;
}
+ /* Try a synch with no other tasks involved. First set all the bits other
+ than this task's bit. */
+ xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
+
+ /* Then wait on just one bit - the bit that is being set. */
+ uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
+ ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
+ ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */
+ portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */
+
+ /* A sync with a max delay should only exit when all the synchronise
+ bits are set...check that is the case. In this case there is only one
+ sync bit anyway. */
+ if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )
+ {
+ xError = pdTRUE;
+ }
+
+ /* ...but now the sync bits should be clear again, leaving all the other
+ bits set (as only one bit was being waited for). */
+ if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )
+ {
+ xError = pdTRUE;
+ }
+
+ /* Clear all the bits to zero again. */
+ xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
+ if( xEventGroupGetBits( xEventGroup ) != 0 )
+ {
+ xError = pdTRUE;
+ }
+
/* Unsuspend the other tasks then check they have executed up to the
synchronisation point. */
vTaskResume( xTestSlaveTaskHandle );
diff --git a/FreeRTOS/Source/event_groups.c b/FreeRTOS/Source/event_groups.c
index c7194016e..5b45f9cc7 100644
--- a/FreeRTOS/Source/event_groups.c
+++ b/FreeRTOS/Source/event_groups.c
@@ -179,7 +179,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
/* Rendezvous always clear the bits. They will have been cleared
already unless this is the only task in the rendezvous. */
- pxEventBits->uxEventBits &= uxBitsToWaitFor;
+ pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
xTicksToWait = 0;
}
diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c
index 8512e1bbc..c20aeed54 100644
--- a/FreeRTOS/Source/tasks.c
+++ b/FreeRTOS/Source/tasks.c
@@ -760,7 +760,11 @@ TCB_t * pxNewTCB;
{
/* Reset the next expected unblock time in case it referred to
the task that has just been deleted. */
- prvResetNextTaskUnblockTime();
+ taskENTER_CRITICAL();
+ {
+ prvResetNextTaskUnblockTime();
+ }
+ taskEXIT_CRITICAL();
}
}
}
@@ -1259,7 +1263,11 @@ TCB_t * pxNewTCB;
/* A task other than the currently running task was suspended,
reset the next expected unblock time in case it referred to the
task that is now in the Suspended state. */
- prvResetNextTaskUnblockTime();
+ taskENTER_CRITICAL();
+ {
+ prvResetNextTaskUnblockTime();
+ }
+ taskEXIT_CRITICAL();
}
else
{