LibMultiSense
LibMultiSense Documentation
Loading...
Searching...
No Matches
TimeStamp.cc
Go to the documentation of this file.
1
42#include "utility/TimeStamp.hh"
43#include "utility/Exception.hh"
44
45#ifndef WIN32
46#include <sys/time.h>
47#endif
48#include <time.h>
49
50namespace crl {
51namespace multisense {
52namespace details {
53namespace utility {
54#if defined (WIN32)
55ULARGE_INTEGER TimeStamp::offsetSecondsSince1970;
56#endif
57/*
58 * Constructor. Empty. We rely on the getter methods to do
59 * things that are more useful.
60 */
62{
63 this->set(0, 0);
64}
65
66/*
67 * Constructor. Initializes with the specified
68 */
69TimeStamp::TimeStamp(int32_t seconds, int32_t microSeconds)
70{
71 this->set(seconds, microSeconds);
72}
73
74/*
75 * Constructor. Initializes with the specified
76 */
77TimeStamp::TimeStamp(int64_t nanoseconds)
78{
79 const int64_t totalMicroSeconds = nanoseconds / 1000;
80
81 const int64_t seconds = totalMicroSeconds / 1000000;
82 const int64_t microSeconds = totalMicroSeconds - (seconds * 1000000);
83
84 this->set(static_cast<int32_t>(seconds), static_cast<int32_t>(microSeconds));
85}
86
87/*
88 * Constructor. Initializes with the specified timestamp value.
89 */
90TimeStamp::TimeStamp(const struct timeval& value)
91{
92 this->set(value);
93}
94
95/*
96 * Sets this timestamp equal to the timestamp specified.
97 */
98void TimeStamp::set(const struct timeval& value)
99{
100 set(value.tv_sec, value.tv_usec);
101}
102
103/*
104 * Sets this timestamp to a specific time
105 */
106void TimeStamp::set(int32_t seconds, int32_t microSeconds)
107{
108 const int32_t rollover_sec = microSeconds / 1000000;
109
110 // Convention is for tv_usec to be between 0 and 999999
111 // Handle rollover by moving seconds to the
112 if (rollover_sec != 0)
113 {
114 seconds += rollover_sec;
115 microSeconds %= 1000000;
116 }
117
118 if (microSeconds < 0)
119 {
120 // we know that abs(tv_usec) is less than 1,000,000 at this point
121 seconds -= 1;
122 microSeconds += 1000000;
123 }
124
125 this->time.tv_sec = seconds;
126 this->time.tv_usec = microSeconds;
127}
128
129#ifndef SENSORPOD_FIRMWARE
130
131/*
132 * This routine will get the current time (as gettimeofday()) and
133 * store it off. It is the normal way of initializing time. Notice
134 * that there may be large time skips when you call this routine, due
135 * to time synchronization jumps.
136 *
137 * Notice that the timestamp returned by this object *is* atomic. It
138 * will not change, even if time synchronization skews things.
139 */
141{
142 //
143 // Create a new timestamp object and fill it in with
144 // the current time of day.
145 //
146
147 TimeStamp timeStamp;
148
149#if defined (WIN32)
150
151 // gettimeofday does not exist on Windows
152 FILETIME currentTimeAsFileTime;
153 GetSystemTimeAsFileTime (&currentTimeAsFileTime);
154
155 ULARGE_INTEGER currentTimeAsLargeInteger;
156 currentTimeAsLargeInteger.LowPart = currentTimeAsFileTime.dwLowDateTime;
157 currentTimeAsLargeInteger.HighPart = currentTimeAsFileTime.dwHighDateTime;
158 currentTimeAsLargeInteger.QuadPart -= offsetSecondsSince1970.QuadPart;
159
160 // convert time to nanoseconds
161 timeStamp = TimeStamp(static_cast<int64_t>(currentTimeAsLargeInteger.QuadPart) * 100);
162
163#else
164
165#if defined (USE_MONOTONIC_CLOCK)
166 struct timespec ts;
167 ts.tv_sec = 0;
168 ts.tv_nsec = 0;
169
170 if (0 != clock_gettime(CLOCK_MONOTONIC, &ts))
171 {
172 CRL_EXCEPTION("Failed to call clock_gettime().");
173 }
174
175 TIMESPEC_TO_TIMEVAL(&timeStamp.time, &ts);
176#else
177 gettimeofday(&timeStamp.time, 0);
178#endif
179
180#endif
181
182 return timeStamp;
183}
184
185#endif // SENSORPOD_FIRMWARE
186
187/*
188 * Returns the seconds portion of the timestamp.
189 */
191{
192 return this->time.tv_sec;
193}
194
195/*
196 * Returns the microseconds portion of the timestamp.
197 */
199{
200 return this->time.tv_usec;
201}
202
203/*
204 * Returns the total time as nanoseconds, aggregates seconds and microseconds
205 */
207{
208 return static_cast<int64_t>(this->time.tv_sec) * 1000000000 + static_cast<int64_t>(this->time.tv_usec) * 1000;
209}
210
212{
213 // newly constructed TimeStamp handles usec rollover
214 return {static_cast<int32_t>(this->time.tv_sec + other.time.tv_sec),
215 static_cast<int32_t>(this->time.tv_usec + other.time.tv_usec)};
216}
217
219{
220 // newly constructed TimeStamp handles usec rollover
221 return {static_cast<int32_t>(this->time.tv_sec - other.time.tv_sec),
222 static_cast<int32_t>(this->time.tv_usec - other.time.tv_usec)};
223}
224
226{
227 *this = *this + other;
228 return *this;
229}
230
232{
233 *this = *this - other;
234 return *this;
235}
236
237}}}} // namespaces
This header file is adapted from Eric Kratzer's (and Dan Tascione's?) StandardException....
#define CRL_EXCEPTION(fmt,...)
Definition Exception.hh:85
The timestamp class gives some type-safety and helper routines for managing time stamps.
void set(const struct timeval &value)
Definition TimeStamp.cc:98
TimeStamp & operator+=(TimeStamp const &other)
Definition TimeStamp.cc:225
TimeStamp & operator-=(TimeStamp const &other)
Definition TimeStamp.cc:231
TimeStamp operator-(TimeStamp const &other) const
Definition TimeStamp.cc:218
TimeStamp operator+(TimeStamp const &other) const
Definition TimeStamp.cc:211