Imported Upstream version 3.2.2
[debian/gnuradio] / gr-qtgui / src / lib / highResTimeFunctions.h
1 #ifndef HIGH_RES_TIME_FUNCTIONS_H
2 #define HIGH_RES_TIME_FUNCTIONS_H
3
4 #include <ctime>
5 #include <sys/time.h>
6 #include <cmath>
7 /* Requires the librt and libm libraries */
8
9 static const long NSEC_PER_SEC = 1000000000L;
10
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)));
13 }
14
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)));
17 }
18
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)));
21 }
22
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)));
25 }
26
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));
29 }
30
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));
33 }
34
35 static inline void timespec_reset(struct timespec* ret){
36   ret->tv_sec = 0;
37   ret->tv_nsec = 0;
38 }
39
40 static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec){
41   while (nsec > NSEC_PER_SEC){
42     nsec -= NSEC_PER_SEC;
43     ++sec;
44   }
45   while(nsec < 0){
46     nsec += NSEC_PER_SEC;
47     --sec;
48   }
49   ts->tv_sec = sec;
50   ts->tv_nsec = nsec;
51 }
52
53 static inline struct timespec convert_to_timespec(const double timeValue){
54   struct timespec ret;
55   double seconds = 0;
56   long nsec = static_cast<long>(modf(timeValue, &seconds) * static_cast<double>(NSEC_PER_SEC));
57   time_t sec = static_cast<time_t>(seconds);
58
59   set_normalized_timespec(&ret, sec, nsec);
60
61   return ret;
62 }
63
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)));
66 }
67
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;
71
72   set_normalized_timespec(ret, sec, nsec);
73 }
74
75 static inline void timespec_add(struct timespec *ret, const struct timespec t1, const struct timespec t0){
76   return timespec_add(ret, &t1, &t0);
77 }
78
79 static inline struct timespec timespec_add(const struct timespec t1, const struct timespec t0){
80   struct timespec ret;
81   timespec_add(&ret, &t1, &t0);
82   return ret;
83 }
84
85 static inline struct timespec timespec_add(const struct timespec t1, const double time0){
86   struct timespec ret;
87   struct timespec t0;
88   t0 = convert_to_timespec(time0);
89
90   timespec_add(&ret, &t1, &t0);
91
92   return ret;
93 }
94
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;
98
99   set_normalized_timespec(ret, sec, nsec);
100 }
101
102 static inline void timespec_subtract(struct timespec *ret, const struct timespec t1, const struct timespec t0){
103   return timespec_subtract(ret, &t1, &t0);
104 }
105
106 static inline struct timespec timespec_subtract(const struct timespec t1, const struct timespec t0){
107   struct timespec ret;
108   timespec_subtract(&ret, &t1, &t0);
109   return ret;
110 }
111
112 static inline struct timespec timespec_subtract(const struct timespec t1, const double time0){
113   struct timespec ret;
114   struct timespec t0;
115   t0 = convert_to_timespec(time0);
116
117   timespec_subtract(&ret, &t1, &t0);
118
119   return ret;
120 }
121
122 static inline double diff_timespec(struct timespec* ret, const struct timespec *t1, const struct timespec* t0){
123   struct timespec actual;
124   time_t sec = 0;
125   long nsec = 0;
126
127   if(timespec_greater(t1, t0)){
128     sec = t1->tv_sec - t0->tv_sec;
129     nsec = t1->tv_nsec - t0->tv_nsec;
130
131     set_normalized_timespec(&actual, sec, nsec);
132     
133     if(ret != NULL){
134       ret->tv_sec = actual.tv_sec;
135       ret->tv_nsec = actual.tv_nsec;
136     }
137
138     return convert_from_timespec(actual);
139   }
140   else{
141     sec = t0->tv_sec - t1->tv_sec;
142     nsec = t0->tv_nsec - t1->tv_nsec;
143
144     // Do nothing with the ret value as the ret value would have to store a negative, which it can't.
145
146     set_normalized_timespec(&actual, sec, nsec);
147     
148     return (-convert_from_timespec(actual));
149   }
150 }
151
152 static inline double diff_timespec(struct timespec* ret, const struct timespec t1, const struct timespec t0){
153   return diff_timespec(ret, &t1, &t0);
154 }
155
156 static inline double diff_timespec(const struct timespec t1, const struct timespec t0){
157   return diff_timespec(NULL, &t1, &t0);
158 }
159
160
161 static inline double diff_timespec(const struct timespec* t1, const struct timespec* t0){
162   return diff_timespec(NULL, t1, t0);
163 }
164
165
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
169     timeval lowResTime;
170     gettimeofday(&lowResTime, NULL);
171     ret->tv_sec = lowResTime.tv_sec;
172     ret->tv_nsec = lowResTime.tv_usec*1000;
173   }
174 }
175
176 static inline struct timespec get_highres_clock(){
177   struct timespec ret;
178   get_highres_clock(&ret);
179   return ret;
180 }
181
182 static inline bool timespec_empty(const struct timespec* ret){
183   return ( (ret->tv_sec == 0 ) &&  (ret->tv_nsec == 0) );
184 }
185
186 static inline bool timespec_empty(const struct timespec ret){
187   return timespec_empty(&ret);
188 }
189
190 #endif /* HIGH_RES_TIME_FUNCTIONS_H */