*/
#include <time.h>
-#include <sys/time.h>
-#include <cmath>
#include "TypesInternal.h"
#include "TimeUtil.h"
+/* NOTE: CLOCK_BOOTTIME is defined in linux/time.h.
+ But if it is included, we encounters the redefinition error of timespec. */
+#define CLOCK_BOOTTIME 7
+
+#define DIFF(X, Y) ((X) > (Y) ? (X) - (Y) : (Y) - (X))
+#define SEC_TO_MSEC(X) ((uint64_t)(X) * 1000ull)
+#define USEC_TO_MSEC(X) ((uint64_t)(X) / 1000ull)
+#define NSEC_TO_MSEC(X) ((uint64_t)(X) / 1000000ull)
+#define EPSILON 3ull
+
using namespace ctx;
TimeUtil::TimeUtil()
uint64_t TimeUtil::getTime()
{
- struct timeval tv;
- double timestamp;
+ struct timespec ts;
+ uint64_t epochInMSec;
+
+ clock_gettime(CLOCK_REALTIME_COARSE, &ts);
+ epochInMSec = SEC_TO_MSEC(ts.tv_sec) + NSEC_TO_MSEC(ts.tv_nsec);
- gettimeofday(&tv, NULL);
- timestamp = tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
- return static_cast<uint64_t>(round(timestamp));
+ return epochInMSec;
}
-uint64_t TimeUtil::getTime(unsigned long long monotonic)
+uint64_t TimeUtil::getTime(unsigned long long sensorTimestamp)
{
- struct timespec ts;
- double timestamp;
- uint64_t currentTime = getTime();
+ uint64_t currentEpoch = getTime();
+ uint64_t sensorTimeMSec = USEC_TO_MSEC(sensorTimestamp);
+
+ bool isEpoch = DIFF(currentEpoch, sensorTimeMSec) < SEC_TO_MSEC(SECONDS_PER_DAY);
+
+ if (isEpoch)
+ return sensorTimeMSec;
- if (std::abs(currentTime / 1000 - monotonic / 1000000) < SECONDS_PER_DAY)
- return static_cast<uint64_t>(round(monotonic / 1000.0));
+ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
- timestamp = static_cast<double>(currentTime) - (ts.tv_sec * 1000000000.0 + ts.tv_nsec) / 1000000.0 + monotonic / 1000.0;
- return static_cast<uint64_t>(round(timestamp));
+
+ uint64_t currentMonotonic = SEC_TO_MSEC(ts.tv_sec) + NSEC_TO_MSEC(ts.tv_nsec);
+ bool isMonotonic = currentMonotonic + EPSILON > sensorTimeMSec;
+
+ if (isMonotonic)
+ return currentEpoch - currentMonotonic + sensorTimeMSec;
+
+
+ clock_gettime(CLOCK_BOOTTIME, &ts);
+ uint64_t currentBootTime = SEC_TO_MSEC(ts.tv_sec) + NSEC_TO_MSEC(ts.tv_nsec);
+
+ return currentEpoch - currentBootTime + sensorTimeMSec;
}