1 #ifndef HIGH_RES_TIME_FUNCTIONS_H
2 #define HIGH_RES_TIME_FUNCTIONS_H
7 /* Requires the librt and libm libraries */
9 static const long NSEC_PER_SEC = 1000000000L;
11 static inline bool timespec_greater(const struct timespec* t1, const struct timespec* t0){
12 return ((t1->tv_sec > t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec > t0->tv_nsec)));
15 static inline bool timespec_greater(const struct timespec t1, const struct timespec t0){
16 return ((t1.tv_sec > t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec > t0.tv_nsec)));
19 static inline bool timespec_less(const struct timespec* t1, const struct timespec* t0){
20 return ((t1->tv_sec < t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec < t0->tv_nsec)));
23 static inline bool timespec_less(const struct timespec t1, const struct timespec t0){
24 return ((t1.tv_sec < t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec < t0.tv_nsec)));
27 static inline bool timespec_equal(const struct timespec* t1, const struct timespec* t0){
28 return ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec == t0->tv_nsec));
31 static inline bool timespec_equal(const struct timespec t1, const struct timespec t0){
32 return ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec == t0.tv_nsec));
35 static inline void timespec_reset(struct timespec* ret){
40 static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec){
41 while (nsec > NSEC_PER_SEC){
53 static inline struct timespec convert_to_timespec(const double timeValue){
56 long nsec = static_cast<long>(modf(timeValue, &seconds) * static_cast<double>(NSEC_PER_SEC));
57 time_t sec = static_cast<time_t>(seconds);
59 set_normalized_timespec(&ret, sec, nsec);
64 static inline double convert_from_timespec(const timespec actual){
65 return (static_cast<double>(actual.tv_sec) + (static_cast<double>(actual.tv_nsec) / static_cast<double>(NSEC_PER_SEC)));
68 static inline void timespec_add(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){
69 time_t sec = t1->tv_sec + t0->tv_sec;
70 long nsec = t1->tv_nsec + t0->tv_nsec;
72 set_normalized_timespec(ret, sec, nsec);
75 static inline void timespec_add(struct timespec *ret, const struct timespec t1, const struct timespec t0){
76 return timespec_add(ret, &t1, &t0);
79 static inline struct timespec timespec_add(const struct timespec t1, const struct timespec t0){
81 timespec_add(&ret, &t1, &t0);
85 static inline struct timespec timespec_add(const struct timespec t1, const double time0){
88 t0 = convert_to_timespec(time0);
90 timespec_add(&ret, &t1, &t0);
95 static inline void timespec_subtract(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){
96 time_t sec = t1->tv_sec - t0->tv_sec;
97 long nsec = t1->tv_nsec - t0->tv_nsec;
99 set_normalized_timespec(ret, sec, nsec);
102 static inline void timespec_subtract(struct timespec *ret, const struct timespec t1, const struct timespec t0){
103 return timespec_subtract(ret, &t1, &t0);
106 static inline struct timespec timespec_subtract(const struct timespec t1, const struct timespec t0){
108 timespec_subtract(&ret, &t1, &t0);
112 static inline struct timespec timespec_subtract(const struct timespec t1, const double time0){
115 t0 = convert_to_timespec(time0);
117 timespec_subtract(&ret, &t1, &t0);
122 static inline double diff_timespec(struct timespec* ret, const struct timespec *t1, const struct timespec* t0){
123 struct timespec actual;
127 if(timespec_greater(t1, t0)){
128 sec = t1->tv_sec - t0->tv_sec;
129 nsec = t1->tv_nsec - t0->tv_nsec;
131 set_normalized_timespec(&actual, sec, nsec);
134 ret->tv_sec = actual.tv_sec;
135 ret->tv_nsec = actual.tv_nsec;
138 return convert_from_timespec(actual);
141 sec = t0->tv_sec - t1->tv_sec;
142 nsec = t0->tv_nsec - t1->tv_nsec;
144 // Do nothing with the ret value as the ret value would have to store a negative, which it can't.
146 set_normalized_timespec(&actual, sec, nsec);
148 return (-convert_from_timespec(actual));
152 static inline double diff_timespec(struct timespec* ret, const struct timespec t1, const struct timespec t0){
153 return diff_timespec(ret, &t1, &t0);
156 static inline double diff_timespec(const struct timespec t1, const struct timespec t0){
157 return diff_timespec(NULL, &t1, &t0);
161 static inline double diff_timespec(const struct timespec* t1, const struct timespec* t0){
162 return diff_timespec(NULL, t1, t0);
166 static inline void get_highres_clock(struct timespec* ret){
167 if(clock_gettime(CLOCK_REALTIME, ret) != 0){
168 // Unable to get high resolution time - fail over to low resolution time
170 gettimeofday(&lowResTime, NULL);
171 ret->tv_sec = lowResTime.tv_sec;
172 ret->tv_nsec = lowResTime.tv_usec*1000;
176 static inline struct timespec get_highres_clock(){
178 get_highres_clock(&ret);
182 static inline bool timespec_empty(const struct timespec* ret){
183 return ( (ret->tv_sec == 0 ) && (ret->tv_nsec == 0) );
186 static inline bool timespec_empty(const struct timespec ret){
187 return timespec_empty(&ret);
190 #endif /* HIGH_RES_TIME_FUNCTIONS_H */