Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/vr/osvr/Util/TimeValueC.h
Line
Count
Source (jump to first uncovered line)
1
/** @file
2
    @brief Header defining a dependency-free, cross-platform substitute for
3
   struct timeval
4
5
    Must be c-safe!
6
7
    @date 2014
8
9
    @author
10
    Sensics, Inc.
11
    <http://sensics.com/osvr>
12
*/
13
14
/*
15
// Copyright 2014 Sensics, Inc.
16
//
17
// Licensed under the Apache License, Version 2.0 (the "License");
18
// you may not use this file except in compliance with the License.
19
// You may obtain a copy of the License at
20
//
21
//     http://www.apache.org/licenses/LICENSE-2.0
22
//
23
// Unless required by applicable law or agreed to in writing, software
24
// distributed under the License is distributed on an "AS IS" BASIS,
25
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26
// See the License for the specific language governing permissions and
27
// limitations under the License.
28
*/
29
30
#ifndef INCLUDED_TimeValueC_h_GUID_A02C6917_124D_4CB3_E63E_07F2DA7144E9
31
#define INCLUDED_TimeValueC_h_GUID_A02C6917_124D_4CB3_E63E_07F2DA7144E9
32
33
/* Internal Includes */
34
#include <osvr/Util/Export.h>
35
#include <osvr/Util/APIBaseC.h>
36
#include <osvr/Util/AnnotationMacrosC.h>
37
#include <osvr/Util/PlatformConfig.h>
38
#include <osvr/Util/StdInt.h>
39
#include <osvr/Util/BoolC.h>
40
41
/* Library/third-party includes */
42
/* none */
43
44
/* Standard includes */
45
/* none */
46
47
OSVR_EXTERN_C_BEGIN
48
49
/** @defgroup UtilTime Timestamp interaction
50
    @ingroup Util
51
52
    This provides a level of interoperability with struct timeval on systems
53
    with that facility. It provides a neutral representation with sufficiently
54
    large types.
55
56
    For C++ code, use of std::chrono or boost::chrono instead is recommended.
57
58
    Note that these time values may not necessarily correlate between processes
59
   so should not be used to estimate or measure latency, etc.
60
61
    @{
62
*/
63
64
/** @brief The signed integer type storing the seconds in a struct
65
    OSVR_TimeValue */
66
typedef int64_t OSVR_TimeValue_Seconds;
67
/** @brief The signed integer type storing the microseconds in a struct
68
    OSVR_TimeValue */
69
typedef int32_t OSVR_TimeValue_Microseconds;
70
71
/** @brief Standardized, portable parallel to struct timeval for representing
72
   both absolute times and time intervals.
73
74
   Where interpreted as an absolute time, its meaning is to be considered the
75
   same as that of the POSIX struct timeval:
76
   time since 00:00 Coordinated Universal Time (UTC), January 1, 1970.
77
78
   For best results, please keep normalized. Output of all functions here
79
   is normalized.
80
   */
81
typedef struct OSVR_TimeValue {
82
    /** @brief Seconds portion of the time value. */
83
    OSVR_TimeValue_Seconds seconds;
84
    /** @brief Microseconds portion of the time value. */
85
    OSVR_TimeValue_Microseconds microseconds;
86
} OSVR_TimeValue;
87
88
#ifdef OSVR_HAVE_STRUCT_TIMEVAL
89
/** @brief Gets the current time in the TimeValue. Parallel to gettimeofday. */
90
OSVR_UTIL_EXPORT void osvrTimeValueGetNow(OSVR_OUT OSVR_TimeValue *dest)
91
    OSVR_FUNC_NONNULL((1));
92
93
struct timeval; /* forward declaration */
94
95
/** @brief Converts from a TimeValue struct to your system's struct timeval.
96
97
    @param dest Pointer to an empty struct timeval for your platform.
98
    @param src A pointer to an OSVR_TimeValue you'd like to convert from.
99
100
    If either parameter is NULL, the function will return without doing
101
   anything.
102
*/
103
OSVR_UTIL_EXPORT void
104
osvrTimeValueToStructTimeval(OSVR_OUT struct timeval *dest,
105
                             OSVR_IN_PTR const OSVR_TimeValue *src)
106
    OSVR_FUNC_NONNULL((1, 2));
107
108
/** @brief Converts from a TimeValue struct to your system's struct timeval.
109
    @param dest An OSVR_TimeValue destination pointer.
110
    @param src Pointer to a struct timeval you'd like to convert from.
111
112
    The result is normalized.
113
114
    If either parameter is NULL, the function will return without doing
115
   anything.
116
*/
117
OSVR_UTIL_EXPORT void
118
osvrStructTimevalToTimeValue(OSVR_OUT OSVR_TimeValue *dest,
119
                             OSVR_IN_PTR const struct timeval *src)
120
    OSVR_FUNC_NONNULL((1, 2));
121
#endif
122
123
/** @brief "Normalizes" a time value so that the absolute number of microseconds
124
    is less than 1,000,000, and that the sign of both components is the same.
125
126
    @param tv Address of a struct TimeValue to normalize in place.
127
128
    If the given pointer is NULL, this function returns without doing anything.
129
*/
130
OSVR_UTIL_EXPORT void osvrTimeValueNormalize(OSVR_INOUT_PTR OSVR_TimeValue *tv)
131
    OSVR_FUNC_NONNULL((1));
132
133
/** @brief Sums two time values, replacing the first with the result.
134
135
    @param tvA Destination and first source.
136
    @param tvB second source
137
138
    If a given pointer is NULL, this function returns without doing anything.
139
140
    Both parameters are expected to be in normalized form.
141
*/
142
OSVR_UTIL_EXPORT void osvrTimeValueSum(OSVR_INOUT_PTR OSVR_TimeValue *tvA,
143
                                       OSVR_IN_PTR const OSVR_TimeValue *tvB)
144
    OSVR_FUNC_NONNULL((1, 2));
145
146
/** @brief Computes the difference between two time values, replacing the first
147
    with the result.
148
149
    Effectively, `*tvA = *tvA - *tvB`
150
151
    @param tvA Destination and first source.
152
    @param tvB second source
153
154
    If a given pointer is NULL, this function returns without doing anything.
155
156
    Both parameters are expected to be in normalized form.
157
*/
158
OSVR_UTIL_EXPORT void
159
osvrTimeValueDifference(OSVR_INOUT_PTR OSVR_TimeValue *tvA,
160
                        OSVR_IN_PTR const OSVR_TimeValue *tvB)
161
    OSVR_FUNC_NONNULL((1, 2));
162
163
/** @brief  Compares two time values (assumed to be normalized), returning
164
    the same values as strcmp
165
166
    @return <0 if A is earlier than B, 0 if they are the same, and >0 if A
167
    is later than B.
168
*/
169
OSVR_UTIL_EXPORT int osvrTimeValueCmp(OSVR_IN_PTR const OSVR_TimeValue *tvA,
170
                                      OSVR_IN_PTR const OSVR_TimeValue *tvB)
171
    OSVR_FUNC_NONNULL((1, 2));
172
173
OSVR_EXTERN_C_END
174
175
/** @brief Compute the difference between the two time values, returning the
176
    duration as a double-precision floating-point number of seconds.
177
178
    Effectively, `ret = *tvA - *tvB`
179
180
    @param tvA first source.
181
    @param tvB second source
182
    @return Duration of timespan in seconds (floating-point)
183
*/
184
OSVR_INLINE double
185
osvrTimeValueDurationSeconds(OSVR_IN_PTR const OSVR_TimeValue *tvA,
186
0
                             OSVR_IN_PTR const OSVR_TimeValue *tvB) {
187
0
    OSVR_TimeValue A = *tvA;
188
0
    osvrTimeValueDifference(&A, tvB);
189
0
    double dt = A.seconds + A.microseconds / 1000000.0;
190
0
    return dt;
191
0
}
192
193
/** @brief True if A is later than B */
194
OSVR_INLINE OSVR_CBool
195
osvrTimeValueGreater(OSVR_IN_PTR const OSVR_TimeValue *tvA,
196
0
                     OSVR_IN_PTR const OSVR_TimeValue *tvB) {
197
0
    if (!tvA || !tvB) {
198
0
        return OSVR_FALSE;
199
0
    }
200
0
    return ((tvA->seconds > tvB->seconds) ||
201
0
            (tvA->seconds == tvB->seconds &&
202
0
             tvA->microseconds > tvB->microseconds))
203
0
               ? OSVR_TRUE
204
0
               : OSVR_FALSE;
205
0
}
206
207
#ifdef __cplusplus
208
209
#include <cmath>
210
#include <cassert>
211
212
/// Returns true if the time value is normalized. Typically used in assertions.
213
0
inline bool osvrTimeValueIsNormalized(const OSVR_TimeValue &tv) {
214
0
#ifdef __APPLE__
215
0
    // apparently standard library used on mac only has floating-point abs?
216
0
    return std::abs(double(tv.microseconds)) < 1000000 &&
217
0
#else
218
0
    return std::abs(tv.microseconds) < 1000000 &&
219
0
#endif
220
0
           ((tv.seconds > 0) == (tv.microseconds > 0));
221
0
}
222
223
/// True if A is later than B
224
inline bool osvrTimeValueGreater(const OSVR_TimeValue &tvA,
225
0
                                 const OSVR_TimeValue &tvB) {
226
0
    assert(osvrTimeValueIsNormalized(tvA) &&
227
0
           "First timevalue argument to comparison was not normalized!");
228
0
    assert(osvrTimeValueIsNormalized(tvB) &&
229
0
           "Second timevalue argument to comparison was not normalized!");
230
0
    return (tvA.seconds > tvB.seconds) ||
231
0
           (tvA.seconds == tvB.seconds && tvA.microseconds > tvB.microseconds);
232
0
}
233
234
/// Operator > overload for time values
235
0
inline bool operator>(const OSVR_TimeValue &tvA, const OSVR_TimeValue &tvB) {
236
0
    return osvrTimeValueGreater(tvA, tvB);
237
0
}
238
239
/// Operator < overload for time values
240
0
inline bool operator<(const OSVR_TimeValue &tvA, const OSVR_TimeValue &tvB) {
241
0
    // Change the order of arguments before forwarding.
242
0
    return osvrTimeValueGreater(tvB, tvA);
243
0
}
244
245
/// Operator == overload for time values
246
0
inline bool operator==(const OSVR_TimeValue &tvA, const OSVR_TimeValue &tvB) {
247
0
    assert(
248
0
        osvrTimeValueIsNormalized(tvA) &&
249
0
        "First timevalue argument to equality comparison was not normalized!");
250
0
    assert(
251
0
        osvrTimeValueIsNormalized(tvB) &&
252
0
        "Second timevalue argument to equality comparison was not normalized!");
253
0
    return (tvA.seconds == tvB.seconds) &&
254
0
           (tvA.microseconds == tvB.microseconds);
255
0
}
256
/// Operator == overload for time values
257
0
inline bool operator!=(const OSVR_TimeValue &tvA, const OSVR_TimeValue &tvB) {
258
0
    assert(osvrTimeValueIsNormalized(tvA) && "First timevalue argument to "
259
0
                                             "inequality comparison was not "
260
0
                                             "normalized!");
261
0
    assert(osvrTimeValueIsNormalized(tvB) && "Second timevalue argument to "
262
0
                                             "inequality comparison was not "
263
0
                                             "normalized!");
264
0
    return (tvA.seconds != tvB.seconds) ||
265
0
           (tvA.microseconds != tvB.microseconds);
266
0
}
267
#endif
268
269
/** @} */
270
271
#endif