[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 ] || { [ $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) 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 LIBCOAP_TMPDIR=/tmp/libcoap
mkdir $LIBCOAP_TMPDIR mkdir $LIBCOAP_TMPDIR
cd $LIBCOAP_TMPDIR cd $LIBCOAP_TMPDIR
+21 -20
View File
@@ -33,6 +33,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <openthread/platform/alarm-micro.h> #include <openthread/platform/alarm-micro.h>
#include <openthread/platform/alarm-milli.h> #include <openthread/platform/alarm-milli.h>
@@ -40,10 +41,6 @@
#include "code_utils.h" #include "code_utils.h"
#define MS_PER_S 1000
#define US_PER_MS 1000
#define US_PER_S 1000000
static bool sIsMsRunning = false; static bool sIsMsRunning = false;
static uint32_t sMsAlarm = 0; static uint32_t sMsAlarm = 0;
@@ -52,28 +49,32 @@ static bool sIsUsRunning = false;
static uint32_t sUsAlarm = 0; static uint32_t sUsAlarm = 0;
#endif #endif
static uint32_t sSpeedUpFactor = 1; static uint32_t sSpeedUpFactor = 1;
static struct timeval sStart;
#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) void platformAlarmInit(uint32_t aSpeedUpFactor)
{ {
sSpeedUpFactor = 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) 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) 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 #if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
uint32_t otPlatAlarmMicroGetNow(void) uint32_t otPlatAlarmMicroGetNow(void)
{ {
return (uint32_t)(platformGetNow()); return (uint32_t)(otSysGetTime());
} }
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
@@ -116,7 +117,7 @@ void otPlatAlarmMicroStop(otInstance *aInstance)
void platformAlarmUpdateTimeout(struct timeval *aTimeout) void platformAlarmUpdateTimeout(struct timeval *aTimeout)
{ {
int64_t remaining = INT32_MAX; int64_t remaining = INT32_MAX;
uint64_t now = platformGetNow(); uint64_t now = platformAlarmGetNow();
assert(aTimeout != NULL); assert(aTimeout != NULL);
+8 -8
View File
@@ -256,15 +256,12 @@ otError HdlcInterface::WaitForWritable(void)
{ {
otError error = OT_ERROR_NONE; otError error = OT_ERROR_NONE;
struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000}; struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
struct timeval end; uint64_t now = otSysGetTime();
struct timeval now; uint64_t end = now + kMaxWaitTime * US_PER_MS;
fd_set writeFds; fd_set writeFds;
fd_set errorFds; fd_set errorFds;
int rval; int rval;
otSysGetTime(&now);
timeradd(&now, &timeout, &end);
while (true) while (true)
{ {
FD_ZERO(&writeFds); FD_ZERO(&writeFds);
@@ -297,11 +294,14 @@ otError HdlcInterface::WaitForWritable(void)
exit(OT_EXIT_FAILURE); 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 else
{ {
+11 -20
View File
@@ -138,13 +138,10 @@ void platformAlarmProcess(otInstance *aInstance);
*/ */
int32_t platformAlarmGetNext(void); int32_t platformAlarmGetNext(void);
/** #define MS_PER_S 1000
* This function returns the current alarm time. #define US_PER_MS 1000
* #define US_PER_S 1000000
* @returns The current alarm time. #define NS_PER_US 1000
*
*/
uint64_t platformAlarmGetNow(void);
/** /**
* This function advances the alarm time by @p aDelta. * This function advances the alarm time by @p aDelta.
@@ -275,14 +272,6 @@ void otSimInit(void);
*/ */
void otSimDeinit(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. * This function performs simulation processing.
* *
@@ -354,11 +343,13 @@ void otSimRadioSpinelUpdate(struct timeval *atimeout);
*/ */
void otSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent); void otSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent);
#if OPENTHREAD_POSIX_VIRTUAL_TIME /**
#define otSysGetTime(aTime) otSimGetTime(aTime) * This function gets system time in microseconds without applying speed up factor.
#else *
#define otSysGetTime(aTime) gettimeofday(aTime, NULL) * @returns System time in microseconds.
#endif *
*/
uint64_t otSysGetTime(void);
/** /**
* This function initializes platform UDP driver. * 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) otError RadioSpinel::WaitResponse(void)
{ {
struct timeval end; uint64_t now = otSysGetTime();
struct timeval now; uint64_t end = now + kMaxWaitTime * US_PER_MS;
struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000}; struct timeval timeout = {kMaxWaitTime / 1000, (kMaxWaitTime % 1000) * 1000};
otSysGetTime(&now);
timeradd(&now, &timeout, &end);
do do
{ {
#if OPENTHREAD_POSIX_VIRTUAL_TIME #if OPENTHREAD_POSIX_VIRTUAL_TIME
@@ -997,10 +994,14 @@ otError RadioSpinel::WaitResponse(void)
} }
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME #endif // OPENTHREAD_POSIX_VIRTUAL_TIME
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 else
{ {
+2 -3
View File
@@ -198,10 +198,9 @@ void otSimProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set
otSimRadioSpinelProcess(aInstance, &event); otSimRadioSpinelProcess(aInstance, &event);
} }
void otSimGetTime(struct timeval *aTime) uint64_t otSysGetTime(void)
{ {
aTime->tv_sec = (time_t)sNow / kUsPerSecond; return sNow;
aTime->tv_usec = sNow % kUsPerSecond;
} }
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME #endif // OPENTHREAD_POSIX_VIRTUAL_TIME