[posix-app] fix alarm issue when time changed (#3728)

Current posix app uses gettimeofday() to get time, which will be affected
by system time changes, and results in alarm not fired. This commit uses
clock_gettime() instead to avoid this issue.
This commit is contained in:
Yakun Xu
2019-04-02 14:59:17 -07:00
committed by Jonathan Hui
parent c862afc6b3
commit 8c0fed1c22
6 changed files with 52 additions and 69 deletions
+1 -10
View File
@@ -64,18 +64,9 @@ cd /tmp || die
}
[ $BUILD_TARGET != posix-app-pty ] || {
sudo apt-get install socat expect libdbus-1-dev autoconf-archive || die
sudo apt-get install socat expect || die
JOBS=$(getconf _NPROCESSORS_ONLN)
(
WPANTUND_TMPDIR=/tmp/wpantund
git clone --depth 1 https://github.com/openthread/wpantund.git $WPANTUND_TMPDIR
cd $WPANTUND_TMPDIR
./bootstrap.sh
./configure --prefix= --exec-prefix=/usr --disable-ncp-dummy --enable-static-link-ncp-plugin=spinel
make -j $JOBS
sudo make install
) || die
(
LIBCOAP_TMPDIR=/tmp/libcoap
mkdir $LIBCOAP_TMPDIR
cd $LIBCOAP_TMPDIR
+21 -20
View File
@@ -33,6 +33,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openthread/platform/alarm-micro.h>
#include <openthread/platform/alarm-milli.h>
@@ -40,10 +41,6 @@
#include "code_utils.h"
#define MS_PER_S 1000
#define US_PER_MS 1000
#define US_PER_S 1000000
static bool sIsMsRunning = false;
static uint32_t sMsAlarm = 0;
@@ -52,28 +49,32 @@ static bool sIsUsRunning = false;
static uint32_t sUsAlarm = 0;
#endif
static uint32_t sSpeedUpFactor = 1;
static struct timeval sStart;
static uint32_t sSpeedUpFactor = 1;
#if !OPENTHREAD_POSIX_VIRTUAL_TIME
uint64_t otSysGetTime(void)
{
struct timespec now;
VerifyOrDie(clock_gettime(CLOCK_MONOTONIC, &now) == 0, OT_EXIT_FAILURE);
return (uint64_t)now.tv_sec * US_PER_S + (uint64_t)now.tv_nsec / NS_PER_US;
}
#endif // !OPENTHREAD_POSIX_VIRTUAL_TIME
static uint64_t platformAlarmGetNow(void)
{
return otSysGetTime() * sSpeedUpFactor;
}
void platformAlarmInit(uint32_t aSpeedUpFactor)
{
sSpeedUpFactor = aSpeedUpFactor;
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)
{
return (uint32_t)(platformGetNow() / US_PER_MS);
return (uint32_t)(platformAlarmGetNow() / US_PER_MS);
}
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
@@ -94,7 +95,7 @@ void otPlatAlarmMilliStop(otInstance *aInstance)
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
uint32_t otPlatAlarmMicroGetNow(void)
{
return (uint32_t)(platformGetNow());
return (uint32_t)(otSysGetTime());
}
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
@@ -116,7 +117,7 @@ void otPlatAlarmMicroStop(otInstance *aInstance)
void platformAlarmUpdateTimeout(struct timeval *aTimeout)
{
int64_t remaining = INT32_MAX;
uint64_t now = platformGetNow();
uint64_t now = platformAlarmGetNow();
assert(aTimeout != NULL);
+8 -8
View File
@@ -256,15 +256,12 @@ otError HdlcInterface::WaitForWritable(void)
{
otError error = OT_ERROR_NONE;
struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
struct timeval end;
struct timeval now;
uint64_t now = otSysGetTime();
uint64_t end = now + kMaxWaitTime * US_PER_MS;
fd_set writeFds;
fd_set errorFds;
int rval;
otSysGetTime(&now);
timeradd(&now, &timeout, &end);
while (true)
{
FD_ZERO(&writeFds);
@@ -297,11 +294,14 @@ otError HdlcInterface::WaitForWritable(void)
exit(OT_EXIT_FAILURE);
}
otSysGetTime(&now);
now = otSysGetTime();
if (timercmp(&end, &now, >))
if (end > now)
{
timersub(&end, &now, &timeout);
uint64_t remain = end - now;
timeout.tv_sec = remain / US_PER_S;
timeout.tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
}
else
{
+11 -20
View File
@@ -138,13 +138,10 @@ void platformAlarmProcess(otInstance *aInstance);
*/
int32_t platformAlarmGetNext(void);
/**
* This function returns the current alarm time.
*
* @returns The current alarm time.
*
*/
uint64_t platformAlarmGetNow(void);
#define MS_PER_S 1000
#define US_PER_MS 1000
#define US_PER_S 1000000
#define NS_PER_US 1000
/**
* This function advances the alarm time by @p aDelta.
@@ -275,14 +272,6 @@ void otSimInit(void);
*/
void otSimDeinit(void);
/**
* This function gets simulation time.
*
* @param[in] aTime A pointer to a timeval receiving the current time.
*
*/
void otSimGetTime(struct timeval *aTime);
/**
* This function performs simulation processing.
*
@@ -354,11 +343,13 @@ void otSimRadioSpinelUpdate(struct timeval *atimeout);
*/
void otSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent);
#if OPENTHREAD_POSIX_VIRTUAL_TIME
#define otSysGetTime(aTime) otSimGetTime(aTime)
#else
#define otSysGetTime(aTime) gettimeofday(aTime, NULL)
#endif
/**
* This function gets system time in microseconds without applying speed up factor.
*
* @returns System time in microseconds.
*
*/
uint64_t otSysGetTime(void);
/**
* This function initializes platform UDP driver.
+9 -8
View File
@@ -923,13 +923,10 @@ otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *aFormat, ...)
otError RadioSpinel::WaitResponse(void)
{
struct timeval end;
struct timeval now;
uint64_t now = otSysGetTime();
uint64_t end = now + kMaxWaitTime * US_PER_MS;
struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
otSysGetTime(&now);
timeradd(&now, &timeout, &end);
do
{
#if OPENTHREAD_POSIX_VIRTUAL_TIME
@@ -997,10 +994,14 @@ otError RadioSpinel::WaitResponse(void)
}
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
otSysGetTime(&now);
if (timercmp(&end, &now, >))
now = otSysGetTime();
if (end > now)
{
timersub(&end, &now, &timeout);
uint64_t remain = end - now;
timeout.tv_sec = remain / US_PER_S;
timeout.tv_usec = static_cast<suseconds_t>(remain % US_PER_S);
}
else
{
+2 -3
View File
@@ -198,10 +198,9 @@ void otSimProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set
otSimRadioSpinelProcess(aInstance, &event);
}
void otSimGetTime(struct timeval *aTime)
uint64_t otSysGetTime(void)
{
aTime->tv_sec = (time_t)sNow / kUsPerSecond;
aTime->tv_usec = sNow % kUsPerSecond;
return sNow;
}
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME