Reinstate "Fix inaccurate ticks in windows port" (#1198)
Reinstates PR https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/142 that was reverted in https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/143
Co-authored-by: Ben Nicholls <benn@smartbadge.com.au>
diff --git a/portable/MSVC-MingW/port.c b/portable/MSVC-MingW/port.c
index c6ee941..9ce0c1b 100644
--- a/portable/MSVC-MingW/port.c
+++ b/portable/MSVC-MingW/port.c
@@ -141,6 +141,9 @@
{
TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps;
+ TickType_t xWaitTimeBetweenTicks = portTICK_PERIOD_MS;
+ HANDLE hTimer = NULL;
+ LARGE_INTEGER liDueTime;
/* Set the timer resolution to the maximum possible. */
if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
@@ -160,22 +163,33 @@
/* Just to prevent compiler warnings. */
( void ) lpParameter;
+ /* Tick time for the timer is adjusted with the maximum available
+ resolution. */
+ if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
+ {
+ xWaitTimeBetweenTicks = xMinimumWindowsBlockTime;
+ }
+
+ /* Convert the tick time in milliseconds to nanoseconds resolution
+ for the Waitable Timer. */
+ liDueTime.u.LowPart = xWaitTimeBetweenTicks * 1000 * 1000;
+ liDueTime.u.HighPart = 0;
+
+ /* Create a synchronization Waitable Timer.*/
+ hTimer = CreateWaitableTimer( NULL, FALSE, NULL );
+
+ configASSERT( hTimer != NULL );
+
+ /* Set the Waitable Timer. The timer is set to run periodically at every
+ xWaitTimeBetweenTicks milliseconds. */
+ configASSERT( SetWaitableTimer( hTimer, &liDueTime, xWaitTimeBetweenTicks, NULL, NULL, 0 ) );
+
while( xPortRunning == pdTRUE )
{
/* Wait until the timer expires and we can access the simulated interrupt
- * variables. *NOTE* this is not a 'real time' way of generating tick
- * events as the next wake time should be relative to the previous wake
- * time, not the time that Sleep() is called. It is done this way to
- * prevent overruns in this very non real time simulated/emulated
- * environment. */
- if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
- {
- Sleep( xMinimumWindowsBlockTime );
- }
- else
- {
- Sleep( portTICK_PERIOD_MS );
- }
+ * variables. */
+
+ WaitForSingleObject( hTimer, INFINITE );
vPortGenerateSimulatedInterruptFromWindowsThread( portINTERRUPT_TICK );
}