From 686d19079809c9975cc83b595e596b53f380357c Mon Sep 17 00:00:00 2001
From: Richard Barry <ribarry@amazon.com>
Date: Thu, 6 Jun 2013 15:46:40 +0000
Subject: [PATCH] Convert some ports to use xTaskIncrementTick() in place of
 vTaskIncrementTick(). Move DSB instructions to before WFI instructions in
 line with ARM recommendations.

---
 .../portable/BCC/16BitDOS/Flsh186/port.c      | 11 +++---
 .../Source/portable/BCC/16BitDOS/PC/port.c    | 11 +++---
 .../Source/portable/CCS/MSP430X/portext.asm   |  6 +--
 .../portable/CodeWarrior/ColdFire_V1/port.c   | 13 ++-----
 .../Source/portable/CodeWarrior/HCS12/port.c  | 11 +++---
 .../portable/GCC/ARM7_AT91FR40008/portISR.c   |  8 ++--
 .../portable/GCC/ARM7_AT91SAM7S/portISR.c     | 11 +++---
 .../portable/GCC/ARM7_LPC2000/portISR.c       |  2 +-
 .../portable/GCC/ARM7_LPC23xx/portISR.c       |  4 +-
 FreeRTOS/Source/portable/GCC/ARM_CM0/port.c   | 12 +++---
 FreeRTOS/Source/portable/GCC/ARM_CM3/port.c   | 18 +++++----
 .../Source/portable/GCC/ARM_CM3_MPU/port.c    | 12 +++---
 FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c  | 14 +++----
 FreeRTOS/Source/portable/GCC/ATMega323/port.c |  8 ++--
 FreeRTOS/Source/portable/GCC/AVR32_UC3/port.c |  2 +-
 .../Source/portable/GCC/CORTUS_APS3/port.c    |  9 ++---
 FreeRTOS/Source/portable/GCC/H8S2329/port.c   |  8 ++--
 FreeRTOS/Source/portable/GCC/HCS12/port.c     | 12 +++---
 FreeRTOS/Source/portable/GCC/MCF5235/port.c   |  8 ++--
 .../Source/portable/GCC/MicroBlaze/port.c     | 11 ++----
 .../Source/portable/GCC/MicroBlazeV8/port.c   | 10 ++---
 FreeRTOS/Source/portable/IAR/ARM_CM3/port.c   | 12 +++---
 FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c  |  2 +-
 FreeRTOS/Source/portable/IAR/RX600/port.c     | 38 +++++++++----------
 FreeRTOS/Source/portable/MSVC-MingW/port.c    | 13 +------
 FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c  |  2 +-
 FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c |  2 +-
 27 files changed, 128 insertions(+), 142 deletions(-)

diff --git a/FreeRTOS/Source/portable/BCC/16BitDOS/Flsh186/port.c b/FreeRTOS/Source/portable/BCC/16BitDOS/Flsh186/port.c
index 52b9bdeb40..6d7effbfcf 100644
--- a/FreeRTOS/Source/portable/BCC/16BitDOS/Flsh186/port.c
+++ b/FreeRTOS/Source/portable/BCC/16BitDOS/Flsh186/port.c
@@ -195,10 +195,11 @@ is being used. */
 	static void __interrupt __far prvPreemptiveTick( void )
 	{
 		/* Get the scheduler to update the task states following the tick. */
-		vTaskIncrementTick();
-
-		/* Switch in the context of the next task to be run. */
-		portSWITCH_CONTEXT();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Switch in the context of the next task to be run. */
+			portSWITCH_CONTEXT();
+		}
 
 		/* Reset the PIC ready for the next time. */
 		portRESET_PIC();
@@ -208,7 +209,7 @@ is being used. */
 	{
 		/* Same as preemptive tick, but the cooperative scheduler is being used
 		so we don't have to switch in the context of the next task. */
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 		portRESET_PIC();
 	}
 #endif
diff --git a/FreeRTOS/Source/portable/BCC/16BitDOS/PC/port.c b/FreeRTOS/Source/portable/BCC/16BitDOS/PC/port.c
index a5874f9997..4e9f8650f4 100644
--- a/FreeRTOS/Source/portable/BCC/16BitDOS/PC/port.c
+++ b/FreeRTOS/Source/portable/BCC/16BitDOS/PC/port.c
@@ -216,10 +216,11 @@ scheduler is being used. */
 	static void __interrupt __far prvPreemptiveTick( void )
 	{
 		/* Get the scheduler to update the task states following the tick. */
-		vTaskIncrementTick();
-
-		/* Switch in the context of the next task to be run. */
-		portSWITCH_CONTEXT();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Switch in the context of the next task to be run. */
+			portSWITCH_CONTEXT();
+		}
 
 		/* Reset the PIC ready for the next time. */
 		prvPortResetPIC();
@@ -229,7 +230,7 @@ scheduler is being used. */
 	{
 		/* Same as preemptive tick, but the cooperative scheduler is being used
 		so we don't have to switch in the context of the next task. */
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 		prvPortResetPIC();
 	}
 #endif
diff --git a/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm b/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm
index 8e89f9b678..1d5d79e1d4 100644
--- a/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm
+++ b/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm
@@ -57,7 +57,7 @@
 
 	.include data_model.h
 
-	.global vTaskIncrementTick
+	.global xTaskIncrementTick
 	.global vTaskSwitchContext
 	.global vPortSetupTimerInterrupt
 	.global pxCurrentTCB
@@ -112,7 +112,7 @@ vPortPreemptiveTickISR: .asmfunc
 	push.w sr
 	portSAVE_CONTEXT
 				
-	call_x	#vTaskIncrementTick
+	call_x	#xTaskIncrementTick
 	call_x	#vTaskSwitchContext
 		
 	portRESTORE_CONTEXT
@@ -128,7 +128,7 @@ vPortCooperativeTickISR: .asmfunc
 	push.w sr
 	portSAVE_CONTEXT
 				
-	call_x	#vTaskIncrementTick
+	call_x	#xTaskIncrementTick
 		
 	portRESTORE_CONTEXT
 	
diff --git a/FreeRTOS/Source/portable/CodeWarrior/ColdFire_V1/port.c b/FreeRTOS/Source/portable/CodeWarrior/ColdFire_V1/port.c
index 2f4ae0fd6b..b048b53e8d 100644
--- a/FreeRTOS/Source/portable/CodeWarrior/ColdFire_V1/port.c
+++ b/FreeRTOS/Source/portable/CodeWarrior/ColdFire_V1/port.c
@@ -220,16 +220,11 @@ unsigned long ulSavedInterruptMask;
 	/* Increment the RTOS tick. */
 	ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
 	{
-		vTaskIncrementTick();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			taskYIELD();
+		}
 	}
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
-
-	/* If we are using the pre-emptive scheduler then also request a
-	context switch as incrementing the tick could have unblocked a task. */
-	#if configUSE_PREEMPTION == 1
-	{
-		taskYIELD();
-	}
-	#endif
 }
 
diff --git a/FreeRTOS/Source/portable/CodeWarrior/HCS12/port.c b/FreeRTOS/Source/portable/CodeWarrior/HCS12/port.c
index e1bbe7ae7d..5dd8a8ec04 100644
--- a/FreeRTOS/Source/portable/CodeWarrior/HCS12/port.c
+++ b/FreeRTOS/Source/portable/CodeWarrior/HCS12/port.c
@@ -260,11 +260,10 @@ void interrupt vPortTickInterrupt( void )
 		portSAVE_CONTEXT();
 
 		/* Increment the tick ... */
-		vTaskIncrementTick();
-
-		/* ... then see if the new tick value has necessitated a
-		context switch. */
-		vTaskSwitchContext();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			vTaskSwitchContext();
+		}
 
 		TFLG1 = 1;								   
 
@@ -274,7 +273,7 @@ void interrupt vPortTickInterrupt( void )
 	}
 	#else
 	{
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 		TFLG1 = 1;
 	}
 	#endif
diff --git a/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008/portISR.c b/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008/portISR.c
index 60a0d214ac..ef503e61c7 100644
--- a/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008/portISR.c
+++ b/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008/portISR.c
@@ -161,7 +161,7 @@ void vPortYieldProcessor( void )
 		/* Clear tick timer interrupt indication. */
 		ulDummy = portTIMER_REG_BASE_PTR->TC_SR;  
 
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 
 		/* Acknowledge the interrupt at AIC level... */
 		AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
@@ -186,8 +186,10 @@ void vPortYieldProcessor( void )
 
 		/* Increment the RTOS tick count, then look for the highest priority 
 		task that is ready to run. */
-		vTaskIncrementTick();
-		vTaskSwitchContext();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			vTaskSwitchContext();
+		}
 
 		/* Acknowledge the interrupt at AIC level... */
 		AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
diff --git a/FreeRTOS/Source/portable/GCC/ARM7_AT91SAM7S/portISR.c b/FreeRTOS/Source/portable/GCC/ARM7_AT91SAM7S/portISR.c
index ac40e1dedd..7eed8348ce 100644
--- a/FreeRTOS/Source/portable/GCC/ARM7_AT91SAM7S/portISR.c
+++ b/FreeRTOS/Source/portable/GCC/ARM7_AT91SAM7S/portISR.c
@@ -163,7 +163,7 @@ void vPortYieldProcessor( void )
 		/* Increment the tick count - which may wake some tasks but as the
 		preemptive scheduler is not being used any woken task is not given
 		processor time no matter what its priority. */
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 		
 		/* Clear the PIT interrupt. */
 		ulDummy = AT91C_BASE_PITC->PITC_PIVR;
@@ -183,10 +183,11 @@ void vPortYieldProcessor( void )
 		portSAVE_CONTEXT();			
 
 		/* Increment the tick count - this may wake a task. */
-		vTaskIncrementTick();
-
-		/* Find the highest priority task that is ready to run. */
-		vTaskSwitchContext();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Find the highest priority task that is ready to run. */
+			vTaskSwitchContext();
+		}
 		
 		/* End the interrupt in the AIC. */
 		AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;;
diff --git a/FreeRTOS/Source/portable/GCC/ARM7_LPC2000/portISR.c b/FreeRTOS/Source/portable/GCC/ARM7_LPC2000/portISR.c
index f4b15b1761..02dbf8eee9 100644
--- a/FreeRTOS/Source/portable/GCC/ARM7_LPC2000/portISR.c
+++ b/FreeRTOS/Source/portable/GCC/ARM7_LPC2000/portISR.c
@@ -166,7 +166,7 @@ void vTickISR( void )
 
 	/* Increment the RTOS tick count, then look for the highest priority 
 	task that is ready to run. */
-	__asm volatile( "bl vTaskIncrementTick" );
+	__asm volatile( "bl xTaskIncrementTick" );
 
 	#if configUSE_PREEMPTION == 1
 		__asm volatile( "bl vTaskSwitchContext" );
diff --git a/FreeRTOS/Source/portable/GCC/ARM7_LPC23xx/portISR.c b/FreeRTOS/Source/portable/GCC/ARM7_LPC23xx/portISR.c
index 3f89bd5c53..e39026f1ca 100644
--- a/FreeRTOS/Source/portable/GCC/ARM7_LPC23xx/portISR.c
+++ b/FreeRTOS/Source/portable/GCC/ARM7_LPC23xx/portISR.c
@@ -150,7 +150,7 @@ void vPortYieldProcessor( void )
 	void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
 	void vNonPreemptiveTick( void )
 	{	
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 		T0IR = 2;
 		VICVectAddr = portCLEAR_VIC_INTERRUPT;
 	}
@@ -167,7 +167,7 @@ void vPortYieldProcessor( void )
 
 		/* Increment the RTOS tick count, then look for the highest priority 
 		task that is ready to run. */
-		__asm volatile( "bl vTaskIncrementTick" );
+		__asm volatile( "bl xTaskIncrementTick" );
 		__asm volatile( "bl vTaskSwitchContext" );
 
 		/* Ready for the next interrupt. */
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
index 6b8a8a84f9..d0540db2ff 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
@@ -293,14 +293,14 @@ void xPortSysTickHandler( void )
 {
 unsigned long ulDummy;
 
-	/* If using preemption, also force a context switch. */
-	#if configUSE_PREEMPTION == 1
-		*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
-	#endif
-
 	ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
 	{
-		vTaskIncrementTick();
+		/* Increment the RTOS tick. */
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Pend a context switch. */
+			*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+		}
 	}
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
 }
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c
index a0bfe1d39c..8acc0a53f9 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c
@@ -354,11 +354,6 @@ void xPortPendSVHandler( void )
 
 void xPortSysTickHandler( void )
 {
-	/* If using preemption, also force a context switch. */
-	#if configUSE_PREEMPTION == 1
-		portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
-	#endif
-
 	/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
 	1.  If it is set to 0 tickless idle is not being used.  If it is set to a
 	value other than 0 or 1 then a timer other than the SysTick is being used
@@ -367,9 +362,18 @@ void xPortSysTickHandler( void )
 		portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;
 	#endif
 
+	/* The SysTick runs at the lowest interrupt priority, so when this interrupt
+	executes all interrupts must be unmasked.  There is therefore no need to
+	save and then restore the interrupt mask value as its value is already
+	known. */
 	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
 	{
-		vTaskIncrementTick();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* A context switch is required.  Context switching is performed in
+			the PendSV interrupt.  Pend the PendSV interrupt. */
+			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
+		}
 	}
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
 }
@@ -444,8 +448,8 @@ void xPortSysTickHandler( void )
 			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 			if( xModifiableIdleTime > 0 )
 			{
-				__asm volatile( "wfi" );
 				__asm volatile( "dsb" );
+				__asm volatile( "wfi" );
 				__asm volatile( "isb" );
 			}
 			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
index 4d4870136c..ffc58598ac 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
@@ -452,14 +452,14 @@ void xPortSysTickHandler( void )
 {
 unsigned long ulDummy;
 
-	/* If using preemption, also force a context switch. */
-	#if configUSE_PREEMPTION == 1
-		*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
-	#endif
-
 	ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
 	{
-		vTaskIncrementTick();
+		/* Increment the RTOS tick. */
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Pend a context switch. */
+			*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+		}
 	}
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
 }
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
index 56ec249bb9..23e194bbe1 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
@@ -387,11 +387,6 @@ void xPortPendSVHandler( void )
 
 void xPortSysTickHandler( void )
 {
-	/* If using preemption, also force a context switch. */
-	#if configUSE_PREEMPTION == 1
-		portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
-	#endif
-
 	/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
 	1.  If it is set to 0 tickless idle is not being used.  If it is set to a
 	value other than 0 or 1 then a timer other than the SysTick is being used
@@ -402,7 +397,12 @@ void xPortSysTickHandler( void )
 
 	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
 	{
-		vTaskIncrementTick();
+		/* Increment the RTOS tick count. */
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Pend a context switch. */
+			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
+		}
 	}
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
 }
@@ -477,8 +477,8 @@ void xPortSysTickHandler( void )
 			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 			if( xModifiableIdleTime > 0 )
 			{
-				__asm volatile( "wfi" );
 				__asm volatile( "dsb" );
+				__asm volatile( "wfi" );
 				__asm volatile( "isb" );
 			}
 			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
diff --git a/FreeRTOS/Source/portable/GCC/ATMega323/port.c b/FreeRTOS/Source/portable/GCC/ATMega323/port.c
index d53607a67d..29f40d4c20 100644
--- a/FreeRTOS/Source/portable/GCC/ATMega323/port.c
+++ b/FreeRTOS/Source/portable/GCC/ATMega323/port.c
@@ -393,8 +393,10 @@ void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
 void vPortYieldFromTick( void )
 {
 	portSAVE_CONTEXT();
-	vTaskIncrementTick();
-	vTaskSwitchContext();
+	if( xTaskIncrementTick() != pdFALSE )
+	{
+		vTaskSwitchContext();
+	}
 	portRESTORE_CONTEXT();
 
 	asm volatile ( "ret" );
@@ -463,7 +465,7 @@ unsigned char ucHighByte, ucLowByte;
 	void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );
 	void SIG_OUTPUT_COMPARE1A( void )
 	{
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 	}
 #endif
 
diff --git a/FreeRTOS/Source/portable/GCC/AVR32_UC3/port.c b/FreeRTOS/Source/portable/GCC/AVR32_UC3/port.c
index 691b712018..43cbc4b4c1 100644
--- a/FreeRTOS/Source/portable/GCC/AVR32_UC3/port.c
+++ b/FreeRTOS/Source/portable/GCC/AVR32_UC3/port.c
@@ -254,7 +254,7 @@ __attribute__((__naked__)) static void vTick( void )
 	/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
 	calls in a critical section . */
 	portENTER_CRITICAL();
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 	portEXIT_CRITICAL();
 
 	/* Restore the context of the "elected task". */
diff --git a/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c b/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c
index 9e5b31564e..bfed6932f7 100644
--- a/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c
+++ b/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c
@@ -170,12 +170,11 @@ void interrupt31_handler( void )
 static void prvProcessTick( void ) __attribute__((noinline));
 static void prvProcessTick( void )
 {
-	vTaskIncrementTick();
-
-	#if configUSE_PREEMPTION == 1
+	if( xTaskIncrementTick() != pdFALSE )
+	{
 		vTaskSwitchContext();
-	#endif
-
+	}
+		
 	/* Clear the Tick Interrupt. */
 	counter1->expired = 0;
 }
diff --git a/FreeRTOS/Source/portable/GCC/H8S2329/port.c b/FreeRTOS/Source/portable/GCC/H8S2329/port.c
index ce1e53abc0..d304992317 100644
--- a/FreeRTOS/Source/portable/GCC/H8S2329/port.c
+++ b/FreeRTOS/Source/portable/GCC/H8S2329/port.c
@@ -293,8 +293,10 @@ void vPortYield( void )
 	{
 		portSAVE_STACK_POINTER();
 		
-		vTaskIncrementTick();
-		vTaskSwitchContext();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			vTaskSwitchContext();
+		}
 
 		/* Clear the interrupt. */
 		TSR1 &= ~0x01;
@@ -312,7 +314,7 @@ void vPortYield( void )
 	void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );
 	void vTickISR( void )
 	{
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 
 		/* Clear the interrupt. */
 		TSR1 &= ~0x01;
diff --git a/FreeRTOS/Source/portable/GCC/HCS12/port.c b/FreeRTOS/Source/portable/GCC/HCS12/port.c
index 8835eb118a..c551de1bfe 100644
--- a/FreeRTOS/Source/portable/GCC/HCS12/port.c
+++ b/FreeRTOS/Source/portable/GCC/HCS12/port.c
@@ -263,11 +263,11 @@ void vPortTickInterrupt( void )
 		portSAVE_CONTEXT();
 
 		/* Increment the tick ... */
-		vTaskIncrementTick();
-
-		/* ... then see if the new tick value has necessitated a
-		context switch. */
-		vTaskSwitchContext();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* A context switch is necessary. */
+			vTaskSwitchContext();
+		}
 
 		/* Restore the context of a task - which may be a different task
 		to that interrupted. */
@@ -275,7 +275,7 @@ void vPortTickInterrupt( void )
 	}
 	#else
 	{
-		vTaskIncrementTick();
+		xTaskIncrementTick();
 	}
 	#endif
 
diff --git a/FreeRTOS/Source/portable/GCC/MCF5235/port.c b/FreeRTOS/Source/portable/GCC/MCF5235/port.c
index 837ad44bb2..f5b6e4f68e 100644
--- a/FreeRTOS/Source/portable/GCC/MCF5235/port.c
+++ b/FreeRTOS/Source/portable/GCC/MCF5235/port.c
@@ -194,7 +194,7 @@ prvPortPreemptiveTick ( void )
      * simply increment the system tick.
      */
 
-    vTaskIncrementTick(  );
+    xTaskIncrementTick();
     MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
 }
 
@@ -209,8 +209,10 @@ prvPortPreemptiveTick( void )
 #endif
     portSAVE_CONTEXT(  );
     MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
-    vTaskIncrementTick(  );
-    vTaskSwitchContext(  );
+    if( xTaskIncrementTick() != pdFALSE )
+	{
+		vTaskSwitchContext(  );
+	}
     portRESTORE_CONTEXT(  );
 }
 #endif
diff --git a/FreeRTOS/Source/portable/GCC/MicroBlaze/port.c b/FreeRTOS/Source/portable/GCC/MicroBlaze/port.c
index d2c5529059..4d796f741d 100644
--- a/FreeRTOS/Source/portable/GCC/MicroBlaze/port.c
+++ b/FreeRTOS/Source/portable/GCC/MicroBlaze/port.c
@@ -359,17 +359,14 @@ void vTickISR( void *pvBaseAddress )
 unsigned long ulCSR;
 
 	/* Increment the RTOS tick - this might cause a task to unblock. */
-	vTaskIncrementTick();
+	if( xTaskIncrementTick() != pdFALSE )
+	{
+		vTaskSwitchContext();
+	}
 
 	/* Clear the timer interrupt */
 	ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);	
 	XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
-
-	/* If we are using the preemptive scheduler then we also need to determine
-	if this tick should cause a context switch. */
-	#if configUSE_PREEMPTION == 1
-		vTaskSwitchContext();
-	#endif
 }
 /*-----------------------------------------------------------*/
 
diff --git a/FreeRTOS/Source/portable/GCC/MicroBlazeV8/port.c b/FreeRTOS/Source/portable/GCC/MicroBlazeV8/port.c
index f3f5a95a06..d85a428fc3 100644
--- a/FreeRTOS/Source/portable/GCC/MicroBlazeV8/port.c
+++ b/FreeRTOS/Source/portable/GCC/MicroBlazeV8/port.c
@@ -433,15 +433,11 @@ extern void vApplicationClearTimerInterrupt( void );
 	vApplicationClearTimerInterrupt();
 
 	/* Increment the RTOS tick - this might cause a task to unblock. */
-	vTaskIncrementTick();
-
-	/* If the preemptive scheduler is being used then a context switch should be
-	requested in case incrementing the tick unblocked a task, or a time slice
-	should cause another task to enter the Running state. */
-	#if configUSE_PREEMPTION == 1
+	if( xTaskIncrementTick() != pdFALSE )
+	{
 		/* Force vTaskSwitchContext() to be called as the interrupt exits. */
 		ulTaskSwitchRequested = 1;
-	#endif
+	}
 }
 /*-----------------------------------------------------------*/
 
diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c
index c8104c6bee..d2ea44745b 100644
--- a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c
+++ b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c
@@ -250,11 +250,6 @@ void vPortExitCritical( void )
 
 void xPortSysTickHandler( void )
 {
-	/* If using preemption, also force a context switch. */
-	#if configUSE_PREEMPTION == 1
-		portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
-	#endif
-
 	/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
 	1.  If it is set to 0 tickless idle is not being used.  If it is set to a
 	value other than 0 or 1 then a timer other than the SysTick is being used
@@ -265,7 +260,10 @@ void xPortSysTickHandler( void )
 
 	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
 	{
-		vTaskIncrementTick();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
+		}
 	}
 	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
 }
@@ -340,8 +338,8 @@ void xPortSysTickHandler( void )
 			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 			if( xModifiableIdleTime > 0 )
 			{
-				__WFI();
 				__DSB();
+				__WFI();
 				__ISB();
 			}
 			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c
index 3d55afae49..a9264f3fcf 100644
--- a/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c
+++ b/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c
@@ -365,8 +365,8 @@ void xPortSysTickHandler( void )
 			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 			if( xModifiableIdleTime > 0 )
 			{
-				__WFI();
 				__DSB();
+				__WFI();
 				__ISB();
 			}
 			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
diff --git a/FreeRTOS/Source/portable/IAR/RX600/port.c b/FreeRTOS/Source/portable/IAR/RX600/port.c
index 86bfbd4369..0306bb7de4 100644
--- a/FreeRTOS/Source/portable/IAR/RX600/port.c
+++ b/FreeRTOS/Source/portable/IAR/RX600/port.c
@@ -56,19 +56,19 @@
     ***************************************************************************
 
 
-    http://www.FreeRTOS.org - Documentation, books, training, latest versions, 
+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
     license and Real Time Engineers Ltd. contact details.
 
     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
     including FreeRTOS+Trace - an indispensable productivity tool, and our new
     fully thread aware and reentrant UDP/IP stack.
 
-    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High 
-    Integrity Systems, who sell the code with commercial support, 
+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
+    Integrity Systems, who sell the code with commercial support,
     indemnification and middleware, under the OpenRTOS brand.
-    
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety 
-    engineered and independently SIL3 certified version for use in safety and 
+
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+    engineered and independently SIL3 certified version for use in safety and
     mission critical applications that require provable dependability.
 */
 
@@ -119,13 +119,13 @@ extern void *pxCurrentTCB;
 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
 {
 	/* R0 is not included as it is the stack pointer. */
-	
+
 	*pxTopOfStack = 0x00;
 	pxTopOfStack--;
  	*pxTopOfStack = portINITIAL_PSW;
 	pxTopOfStack--;
 	*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
-	
+
 	/* When debugging it can be useful if every register is set to a known
 	value.  Otherwise code space can be saved by just setting the registers
 	that need to be set. */
@@ -166,9 +166,9 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
 		pxTopOfStack -= 15;
 	}
 	#endif
-	
+
 	*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R1 */
-	pxTopOfStack--;				
+	pxTopOfStack--;
 	*pxTopOfStack = portINITIAL_FPSW;
 	pxTopOfStack--;
 	*pxTopOfStack = 0x12345678; /* Accumulator. */
@@ -191,12 +191,12 @@ extern void vApplicationSetupTimerInterrupt( void );
 		use.  A demo application is provided to show a suitable example. */
 		vApplicationSetupTimerInterrupt();
 
-		/* Enable the software interrupt. */		
+		/* Enable the software interrupt. */
 		_IEN( _ICU_SWINT ) = 1;
-		
+
 		/* Ensure the software interrupt is clear. */
 		_IR( _ICU_SWINT ) = 0;
-		
+
 		/* Ensure the software interrupt is set to the kernel priority. */
 		_IPR( _ICU_SWINT ) = configKERNEL_INTERRUPT_PRIORITY;
 
@@ -214,19 +214,17 @@ __interrupt void vTickISR( void )
 {
 	/* Re-enable interrupts. */
 	__enable_interrupt();
-	
+
 	/* Increment the tick, and perform any processing the new tick value
 	necessitates. */
 	__set_interrupt_level( configMAX_SYSCALL_INTERRUPT_PRIORITY );
 	{
-		vTaskIncrementTick();
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			taskYIELD();
+		}
 	}
 	__set_interrupt_level( configKERNEL_INTERRUPT_PRIORITY );
-	
-	/* Only select a new task if the preemptive scheduler is being used. */
-	#if( configUSE_PREEMPTION == 1 )
-		taskYIELD();
-	#endif
 }
 /*-----------------------------------------------------------*/
 
diff --git a/FreeRTOS/Source/portable/MSVC-MingW/port.c b/FreeRTOS/Source/portable/MSVC-MingW/port.c
index 8b82a8c967..a19858de50 100644
--- a/FreeRTOS/Source/portable/MSVC-MingW/port.c
+++ b/FreeRTOS/Source/portable/MSVC-MingW/port.c
@@ -301,18 +301,7 @@ static unsigned long prvProcessTickInterrupt( void )
 unsigned long ulSwitchRequired;
 
 	/* Process the tick itself. */
-	vTaskIncrementTick();
-	#if( configUSE_PREEMPTION != 0 )
-	{
-		/* A context switch is only automatically performed from the tick
-		interrupt if the pre-emptive scheduler is being used. */
-		ulSwitchRequired = pdTRUE;
-	}
-	#else
-	{
-		ulSwitchRequired = pdFALSE;
-	}
-	#endif
+	ulSwitchRequired = ( unsigned long ) xTaskIncrementTick();
 
 	return ulSwitchRequired;
 }
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c
index f1a982acab..c721f1fe35 100644
--- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c
+++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c
@@ -417,8 +417,8 @@ void xPortSysTickHandler( void )
 			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 			if( xModifiableIdleTime > 0 )
 			{
-				__wfi();
 				__dsb( portSY_FULL_READ_WRITE );
+				__wfi();
 				__isb( portSY_FULL_READ_WRITE );
 			}
 			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c
index d935dedfc1..345f386bfc 100644
--- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c
+++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c
@@ -480,8 +480,8 @@ void xPortSysTickHandler( void )
 			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 			if( xModifiableIdleTime > 0 )
 			{
-				__wfi();
 				__dsb( portSY_FULL_READ_WRITE );
+				__wfi();
 				__isb( portSY_FULL_READ_WRITE );
 			}
 			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );