mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:32:42 -05:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									ef7f3c5320
								
							
						
					
					
						commit
						82207ebffa
					
				
					 3 changed files with 43 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -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 );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -760,8 +760,12 @@ TCB_t * pxNewTCB;
 | 
			
		|||
			{
 | 
			
		||||
				/* Reset the next expected unblock time in case it referred to
 | 
			
		||||
				the task that has just been deleted. */
 | 
			
		||||
				taskENTER_CRITICAL();
 | 
			
		||||
				{
 | 
			
		||||
					prvResetNextTaskUnblockTime();
 | 
			
		||||
				}
 | 
			
		||||
				taskEXIT_CRITICAL();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1259,8 +1263,12 @@ 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. */
 | 
			
		||||
				taskENTER_CRITICAL();
 | 
			
		||||
				{
 | 
			
		||||
					prvResetNextTaskUnblockTime();
 | 
			
		||||
				}
 | 
			
		||||
				taskEXIT_CRITICAL();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue