[posix-app] update timer implementation to handle speedup (#3045)

This commit is contained in:
Abtin Keshavarzian
2018-09-10 14:42:20 -10:00
committed by Jonathan Hui
parent 42e44e34f9
commit b7c0c8ed99
+40 -40
View File
@@ -36,17 +36,19 @@
#include <openthread/platform/alarm-milli.h> #include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h> #include <openthread/platform/diag.h>
#include "code_utils.h"
#define MS_PER_S 1000 #define MS_PER_S 1000
#define US_PER_MS 1000 #define US_PER_MS 1000
#define US_PER_S 1000000 #define US_PER_S 1000000
#define DEFAULT_TIMEOUT 10 // seconds
static bool sIsMsRunning = false; static bool sIsMsRunning = false;
static uint32_t sMsAlarm = 0; static uint32_t sMsAlarm = 0;
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
static bool sIsUsRunning = false; static bool sIsUsRunning = false;
static uint32_t sUsAlarm = 0; static uint32_t sUsAlarm = 0;
#endif
static uint32_t sSpeedUpFactor = 1; static uint32_t sSpeedUpFactor = 1;
static struct timeval sStart; static struct timeval sStart;
@@ -57,15 +59,19 @@ void platformAlarmInit(uint32_t aSpeedUpFactor)
otSysGetTime(&sStart); otSysGetTime(&sStart);
} }
static uint64_t platformGetNow(void)
{
struct timeval now;
otSysGetTime(&now);
timersub(&now, &sStart, &now);
return (uint64_t)now.tv_sec * US_PER_S * sSpeedUpFactor + (uint64_t)now.tv_usec * sSpeedUpFactor;
}
uint32_t otPlatAlarmMilliGetNow(void) uint32_t otPlatAlarmMilliGetNow(void)
{ {
struct timeval tv; return (uint32_t)(platformGetNow() / US_PER_MS);
otSysGetTime(&tv);
timersub(&tv, &sStart, &tv);
return (uint32_t)(((uint64_t)tv.tv_sec * sSpeedUpFactor * MS_PER_S) +
((uint64_t)tv.tv_usec * sSpeedUpFactor / US_PER_MS));
} }
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
@@ -81,14 +87,10 @@ void otPlatAlarmMilliStop(otInstance *aInstance)
sIsMsRunning = false; sIsMsRunning = false;
} }
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
uint32_t otPlatAlarmMicroGetNow(void) uint32_t otPlatAlarmMicroGetNow(void)
{ {
struct timeval tv; return (uint32_t)(platformGetNow());
otSysGetTime(&tv);
timersub(&tv, &sStart, &tv);
return (uint32_t)(tv.tv_sec * US_PER_S + tv.tv_usec) * sSpeedUpFactor;
} }
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
@@ -103,45 +105,43 @@ void otPlatAlarmMicroStop(otInstance *aInstance)
(void)aInstance; (void)aInstance;
sIsUsRunning = false; sIsUsRunning = false;
} }
#endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
void platformAlarmUpdateTimeout(struct timeval *aTimeout) void platformAlarmUpdateTimeout(struct timeval *aTimeout)
{ {
int32_t usRemaining = INT32_MAX; int64_t remaining = INT32_MAX;
int32_t msRemaining = INT32_MAX; uint64_t now = platformGetNow();
if (aTimeout == NULL) assert(aTimeout != NULL);
{
return;
}
if (sIsUsRunning)
{
usRemaining = (int64_t)(sUsAlarm - otPlatAlarmMicroGetNow());
}
if (sIsMsRunning) if (sIsMsRunning)
{ {
struct timeval now; remaining = (int32_t)(sMsAlarm - (uint32_t)(now / US_PER_MS));
otEXPECT(remaining > 0);
otSysGetTime(&now); remaining *= US_PER_MS;
timersub(&now, &sStart, &now); remaining -= (now % US_PER_MS);
msRemaining = (int64_t)sMsAlarm * US_PER_MS - now.tv_sec * US_PER_S - now.tv_usec;
} }
if (usRemaining <= 0 || msRemaining <= 0) #if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
if (sIsUsRunning)
{
int32_t usRemaining = (int32_t)(sUsAlarm - (uint32_t)now);
if (usRemaining < remaining)
{
remaining = usRemaining;
}
}
#endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
exit:
if (remaining <= 0)
{ {
aTimeout->tv_sec = 0; aTimeout->tv_sec = 0;
aTimeout->tv_usec = 0; aTimeout->tv_usec = 0;
} }
else else
{ {
int64_t remaining = msRemaining;
if (usRemaining < remaining)
{
remaining = usRemaining;
}
remaining /= sSpeedUpFactor; remaining /= sSpeedUpFactor;
if (remaining == 0) if (remaining == 0)
@@ -149,7 +149,7 @@ void platformAlarmUpdateTimeout(struct timeval *aTimeout)
remaining = 1; remaining = 1;
} }
aTimeout->tv_sec = (time_t)remaining / US_PER_S; aTimeout->tv_sec = (time_t)(remaining / US_PER_S);
aTimeout->tv_usec = remaining % US_PER_S; aTimeout->tv_usec = remaining % US_PER_S;
} }
} }