From cab1e68e8b1ca8fc2bf1a7b8ffbc1dbf402d7af2 Mon Sep 17 00:00:00 2001 From: josesimoes Date: Fri, 5 Mar 2021 10:39:31 +0000 Subject: [PATCH] Fix bool timer implementation in WIN32 --- targets/win32/nanoCLR/nanoCLR.vcxproj | 2 +- targets/win32/nanoCLR/nanoCLR.vcxproj.filters | 8 +- .../{Events.cpp => targetPAL_Events.cpp} | 47 ++++++----- targets/win32/nanoCLR/targetPAL_Time.cpp | 79 ++----------------- 4 files changed, 33 insertions(+), 103 deletions(-) rename targets/win32/nanoCLR/{Events.cpp => targetPAL_Events.cpp} (72%) diff --git a/targets/win32/nanoCLR/nanoCLR.vcxproj b/targets/win32/nanoCLR/nanoCLR.vcxproj index 55b3f290aa..1b92cce0f1 100644 --- a/targets/win32/nanoCLR/nanoCLR.vcxproj +++ b/targets/win32/nanoCLR/nanoCLR.vcxproj @@ -179,7 +179,7 @@ - + diff --git a/targets/win32/nanoCLR/nanoCLR.vcxproj.filters b/targets/win32/nanoCLR/nanoCLR.vcxproj.filters index 03d8a93d15..767bc7cce3 100644 --- a/targets/win32/nanoCLR/nanoCLR.vcxproj.filters +++ b/targets/win32/nanoCLR/nanoCLR.vcxproj.filters @@ -53,9 +53,6 @@ Source Files - - Source Files - Source Files @@ -131,8 +128,11 @@ Source Files + + Source Files + - + \ No newline at end of file diff --git a/targets/win32/nanoCLR/Events.cpp b/targets/win32/nanoCLR/targetPAL_Events.cpp similarity index 72% rename from targets/win32/nanoCLR/Events.cpp rename to targets/win32/nanoCLR/targetPAL_Events.cpp index 2662a79ed1..d4ffff1968 100644 --- a/targets/win32/nanoCLR/Events.cpp +++ b/targets/win32/nanoCLR/targetPAL_Events.cpp @@ -3,46 +3,45 @@ // Portions Copyright (c) Microsoft Corporation. All rights reserved. // See LICENSE file in the project root for full license information. // + #include "stdafx.h" +#include -HAL_COMPLETION g_Events_BoolTimerCompletion; +static std::unique_ptr boolEventsTimer; +static bool *saveTimerCompleteFlag = 0; -static void local_Events_SetBoolTimer_Callback(void *arg) +void local_Events_SetBoolTimer_Callback() { NATIVE_PROFILE_PAL_EVENTS(); - bool *TimerCompleteFlag = (bool *)arg; - *TimerCompleteFlag = TRUE; + *saveTimerCompleteFlag = true; } -void Events_SetBoolTimer(bool *timerCompleteFlag, uint32_t millisecondsFromNow) +bool Events_Initialize_Platform() { - NATIVE_PROFILE_PAL_EVENTS(); - // we assume only 1 can be active, abort previous just in case - g_Events_BoolTimerCompletion.Abort(); + boolEventsTimer = NULL; - if (timerCompleteFlag) - { - g_Events_BoolTimerCompletion.InitializeForISR(local_Events_SetBoolTimer_Callback, timerCompleteFlag); - g_Events_BoolTimerCompletion.EnqueueDelta(millisecondsFromNow * 1000); - } + return true; } -void HAL_COMPLETION::EnqueueDelta64(UINT64 uSecFromNow) +void Events_SetBoolTimer(bool *timerCompleteFlag, uint32_t millisecondsFromNow) { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + NATIVE_PROFILE_PAL_EVENTS(); - // grab time first to be closest to now as possible from when this function was called - uint64_t now = HAL_Time_CurrentSysTicks(); - uint64_t eventTimeTicks = CPU_MicrosecondsToTicks(uSecFromNow); + // we assume only 1 can be active, abort previous just in case + if (boolEventsTimer != NULL) + { + boolEventsTimer.release(); + } - EnqueueTicks(now * CPU_TicksPerSecond() + eventTimeTicks); -} + if (timerCompleteFlag) + { + // As only one timer running at a time we will just save it + saveTimerCompleteFlag = timerCompleteFlag; -void HAL_COMPLETION::EnqueueDelta(UINT32 uSecFromNow) -{ - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - EnqueueDelta64((UINT64)uSecFromNow); + boolEventsTimer = + std::make_unique(millisecondsFromNow, local_Events_SetBoolTimer_Callback); + } } // mutex, condition variable and flags for CLR's global events state diff --git a/targets/win32/nanoCLR/targetPAL_Time.cpp b/targets/win32/nanoCLR/targetPAL_Time.cpp index f0a562dd26..e2bca56f9c 100644 --- a/targets/win32/nanoCLR/targetPAL_Time.cpp +++ b/targets/win32/nanoCLR/targetPAL_Time.cpp @@ -19,82 +19,13 @@ void Time_SetCompare(UINT64 CompareValue) // convert to milliseconds for OS timer auto compareMs = CompareValue / (CPU_TicksPerSecond() * (uint64_t)1000); ASSERT(compareMs < UINT32_MAX); + if (compareMs == 0) + { TimerCallback(); + } else + { pCompletionsTimer = std::make_unique((UINT32)compareMs, TimerCallback); + } } - -// -// -//// timer for next event -// static virtual_timer_t nextEventTimer; -// void* nextEventCallbackDummyArg = NULL; -// -// static void NextEventTimer_Callback( void* arg ) -//{ -// (void)arg; -// -// // this call also schedules the next one, if there is one -// HAL_COMPLETION::DequeueAndExec(); -//} -// -// HRESULT Time_Initialize() -//{ -// // need to setup the timer at boot, but stopped -// chVTSet(&nextEventTimer, TIME_INFINITE, NextEventTimer_Callback, nextEventCallbackDummyArg); -// -// return S_OK; -//} -// -// HRESULT Time_Uninitialize() -//{ -// chVTReset(&nextEventTimer); -// -// // nothing to do here has time management is handled by ChibiOS -// return S_OK; -//} -// -// void Time_SetCompare ( uint64_t compareValueTicks ) -//{ -// if(compareValueTicks == 0) -// { -// // compare value is 0 so dequeue and schedule immediately -// // can't call chVTSet with 'immediate delay value', so use value 1 to get it executed ASAP -// chVTSet(&nextEventTimer, 1, NextEventTimer_Callback, nextEventCallbackDummyArg); -// } -// else if(compareValueTicks == HAL_COMPLETION_IDLE_VALUE) -// { -// // wait for infinity, don't need to do anything here -// } -// else -// { -// if (HAL_Time_CurrentSysTicks() >= compareValueTicks) -// { -// // already missed the event, dequeue and execute immediately -// // can't call chVTSet with 'immediate delay value', so use value 1 to get it executed ASAP -// chVTSet(&nextEventTimer, 1, NextEventTimer_Callback, nextEventCallbackDummyArg); -// } -// else -// { -// // compareValueTicks is the time (in sys ticks) that is being requested to fire an -// HAL_COMPLETION::DequeueAndExec() -// // need to subtract the current system time to set when the timer will fire -// // compareValueTicks is in CMSIS ticks (which equals to ms), so we use TIME_MS2I only to round -// compareValueTicks -= HAL_Time_CurrentSysTicks(); -// uint64_t delay = TIME_MS2I(compareValueTicks); -// -// // make sure that chVTSet does not get called with zero delay -// if (delay == 0) -// { -// // compare value is 0 so dequeue and execute immediately -// // no need to call the timer -// HAL_COMPLETION::DequeueAndExec(); -// return; -// } -// -// // no need to stop the timer if it's running because the API does it anyway -// chVTSet(&nextEventTimer, delay, NextEventTimer_Callback, nextEventCallbackDummyArg); -// } -// } -//}