MRPT  2.0.2
Clock.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "core-precomp.h" // Precompiled headers
11 
12 #include <mrpt/core/Clock.h>
13 #include <mrpt/core/exceptions.h>
14 
15 #ifdef _WIN32
16 #include <windows.h>
17 #else
18 #include <sys/time.h> // timeval
19 #endif
20 
21 #include <ctime> // clock_gettime
22 #include <iostream>
23 
24 static mrpt::Clock::Source selectedClock = mrpt::Clock::Source::Realtime;
25 
26 #if !defined(_WIN32)
27 inline uint64_t as_nanoseconds(const struct timespec& ts)
28 {
29  return ts.tv_sec * static_cast<uint64_t>(1000000000L) + ts.tv_nsec;
30 }
31 inline void from_nanoseconds(const uint64_t ns, struct timespec& ts)
32 {
33  ts.tv_sec = (ns / static_cast<uint64_t>(1000000000L));
34  ts.tv_nsec = (ns % static_cast<uint64_t>(1000000000L));
35 }
36 #endif
38 {
39  uint64_t monotonic_ns = 0;
40  uint64_t realtime_ns = 0;
41  uint64_t rt2mono_diff = 0;
42 };
44 static bool monotonic_epoch_init = false;
45 
46 static uint64_t getCurrentTime() noexcept
47 {
48 #ifdef _WIN32
49  FILETIME t;
50  GetSystemTimeAsFileTime(&t);
51  return (((uint64_t)t.dwHighDateTime) << 32) | ((uint64_t)t.dwLowDateTime);
52 #else
53 #if defined(__APPLE__)
54  struct timeval tv;
55  timespec tim{0, 0};
56  gettimeofday(&tv, nullptr);
57  tim.tv_sec = tv.tv_sec;
58  tim.tv_nsec = tv.tv_usec * 1000;
59 #else
60  timespec tim{0, 0};
61 
62  switch (selectedClock)
63  {
64  case mrpt::Clock::Source::Realtime:
65  {
66  // Just get the time and that is it:
67  clock_gettime(CLOCK_REALTIME, &tim);
68  }
69  break;
70  case mrpt::Clock::Source::Monotonic:
71  {
72  // Get the realtime clock reference timepoint, the first time we run
73  // this:
76 
77  // get the monotonic clock:
78  clock_gettime(CLOCK_MONOTONIC, &tim);
79 
80  // correct the clock epoch:
81  const uint64_t sum = as_nanoseconds(tim) + m2r_epoch.rt2mono_diff;
82  from_nanoseconds(sum, tim);
83  }
84  break;
85  };
86 #endif
87 
88  // Convert to TTimeStamp 100-nanoseconds representation:
89  return uint64_t(tim.tv_sec) * UINT64_C(10000000) +
90  UINT64_C(116444736) * UINT64_C(1000000000) + tim.tv_nsec / 100;
91 #endif
92 }
93 
95 {
97 }
98 
100 {
102  uint64_t(t * 10000000.0) + UINT64_C(116444736) * UINT64_C(1000000000)));
103 }
104 
105 // Convert to time_t UNIX timestamp, with fractional part.
107 {
108  return double(
109  t.time_since_epoch().count() -
110  UINT64_C(116444736) * UINT64_C(1000000000)) /
111  10000000.0;
112 }
113 
115 {
116  ASSERT_(
117  s == mrpt::Clock::Source::Realtime ||
118  s == mrpt::Clock::Source::Monotonic);
119  selectedClock = s;
120 }
121 
123 
125 {
126 #if !defined(_WIN32)
127  timespec tim_rt{0, 0}, tim_mono{0, 0};
128  clock_gettime(CLOCK_REALTIME, &tim_rt);
129  clock_gettime(CLOCK_MONOTONIC, &tim_mono);
130  m2r_epoch.monotonic_ns = as_nanoseconds(tim_mono);
131  m2r_epoch.realtime_ns = as_nanoseconds(tim_rt);
132 
133  // Save the difference, which is what matters:
134  const auto old_diff = m2r_epoch.rt2mono_diff;
136  {
137  std::cerr << "[mrpt::Clock::resetMonotonicToRealTimeEpoch] CRITICAL: "
138  "Unreliable values: realtime_ns="
140  << " should be larger than monotonic_ns="
141  << m2r_epoch.monotonic_ns << "\n";
142  }
144 
145  const int64_t err = monotonic_epoch_init
146  ? (static_cast<int64_t>(m2r_epoch.rt2mono_diff) -
147  static_cast<int64_t>(old_diff))
148  : 0;
149 
150  monotonic_epoch_init = true;
151  return err;
152 #else
153  monotonic_epoch_init = true;
154  return 0;
155 #endif
156 }
157 
159 {
161  return m2r_epoch.rt2mono_diff;
162 }
static double toDouble(const time_point t) noexcept
Converts a timestamp to a UNIX time_t-like number, with fractional part.
Definition: Clock.cpp:106
std::chrono::duration< rep, period > duration
Definition: Clock.h:24
static time_point fromDouble(const double t) noexcept
Create a timestamp from its double representation.
Definition: Clock.cpp:99
std::chrono::time_point< Clock > time_point
Definition: Clock.h:25
Source
Options for setting the source of all timestamps across MRPT: setActiveClock(), now() ...
Definition: Clock.h:41
static Source getActiveClock()
Returns the currently selected clock.
Definition: Clock.cpp:122
static time_point now() noexcept
Returns the current time using the currently selected Clock source.
Definition: Clock.cpp:94
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
static MonotonicToRealtimeEpoch m2r_epoch
Definition: Clock.cpp:43
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
static bool monotonic_epoch_init
Definition: Clock.cpp:44
static void setActiveClock(const Source s)
Changes the selected clock to get time from when calling now().
Definition: Clock.cpp:114
static uint64_t getMonotonicToRealtimeOffset()
Returns the number of nanoseconds that are added to the output of the POSIX CLOCK_MONOTONIC to make t...
Definition: Clock.cpp:158
static mrpt::Clock::Source selectedClock
Definition: Clock.cpp:24
static int64_t resetMonotonicToRealTimeEpoch() noexcept
Monotonic clock might drift over time with respect to Realtime.
Definition: Clock.cpp:124
static uint64_t getCurrentTime() noexcept
Definition: Clock.cpp:46



Page generated by Doxygen 1.8.14 for MRPT 2.0.2 Git: 9b4fd2465 Mon May 4 16:59:08 2020 +0200 at lun may 4 17:26:07 CEST 2020