[simulation] fix handling of overflow in virtual-time simulation (#6969)

This commit updates `platformAlarmGetNext()` in `alarm-sim` in
virtual-time simulation platform to return the remaining duration
to the next alarm as `uint64_t` (in microseconds). This fixes the
issue with potential overflow in calculating the next alarm time.
This commit is contained in:
Abtin Keshavarzian
2021-08-30 11:57:14 -07:00
committed by GitHub
parent a935fc51f7
commit 3c10ded88d
3 changed files with 20 additions and 15 deletions
@@ -113,12 +113,12 @@ void platformAlarmUpdateTimeout(struct timeval *aTimeout);
void platformAlarmProcess(otInstance *aInstance); void platformAlarmProcess(otInstance *aInstance);
/** /**
* This function returns the next alarm event time. * This function returns the duration to the next alarm event time (in micro seconds)
* *
* @returns The next alarm fire time. * @returns The duration (in micro seconds) to the next alarm event.
* *
*/ */
int32_t platformAlarmGetNext(void); uint64_t platformAlarmGetNext(void);
/** /**
* This function returns the current alarm time. * This function returns the current alarm time.
@@ -105,35 +105,40 @@ void otPlatAlarmMicroStop(otInstance *aInstance)
sIsUsRunning = false; sIsUsRunning = false;
} }
int32_t platformAlarmGetNext(void) uint64_t platformAlarmGetNext(void)
{ {
int32_t remaining = INT32_MAX; uint64_t remaining = INT64_MAX;
if (sIsMsRunning) if (sIsMsRunning)
{ {
int32_t milli = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow()); int32_t milli = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
remaining = milli * US_PER_MS; if (milli < 0)
if (remaining < 0 && milli > 0)
{ {
remaining = INT32_MAX; remaining = 0;
}
else
{
remaining = (uint64_t)milli;
remaining *= US_PER_MS;
} }
} }
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
if (sIsUsRunning) if (sIsUsRunning)
{ {
int32_t micro = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow()); int32_t micro = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
if (remaining > micro) if (micro < 0)
{ {
remaining = micro; remaining = 0;
}
else if (remaining > ((uint64_t)micro))
{
remaining = (uint64_t)micro;
} }
} }
#endif
#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
return remaining; return remaining;
} }
@@ -127,7 +127,7 @@ static void platformSendSleepEvent(void)
assert(platformAlarmGetNext() > 0); assert(platformAlarmGetNext() > 0);
event.mDelay = (uint64_t)platformAlarmGetNext(); event.mDelay = platformAlarmGetNext();
event.mEvent = OT_SIM_EVENT_ALARM_FIRED; event.mEvent = OT_SIM_EVENT_ALARM_FIRED;
event.mDataLength = 0; event.mDataLength = 0;