GNU Radio 3.3.0 C++ API
|
00001 #ifndef HIGH_RES_TIME_FUNCTIONS_H 00002 #define HIGH_RES_TIME_FUNCTIONS_H 00003 00004 #include <ctime> 00005 #include <sys/time.h> 00006 #include <cmath> 00007 /* Requires the librt and libm libraries */ 00008 00009 static const long NSEC_PER_SEC = 1000000000L; 00010 00011 static inline bool timespec_greater(const struct timespec* t1, const struct timespec* t0){ 00012 return ((t1->tv_sec > t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec > t0->tv_nsec))); 00013 } 00014 00015 static inline bool timespec_greater(const struct timespec t1, const struct timespec t0){ 00016 return ((t1.tv_sec > t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec > t0.tv_nsec))); 00017 } 00018 00019 static inline bool timespec_less(const struct timespec* t1, const struct timespec* t0){ 00020 return ((t1->tv_sec < t0->tv_sec) || ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec < t0->tv_nsec))); 00021 } 00022 00023 static inline bool timespec_less(const struct timespec t1, const struct timespec t0){ 00024 return ((t1.tv_sec < t0.tv_sec) || ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec < t0.tv_nsec))); 00025 } 00026 00027 static inline bool timespec_equal(const struct timespec* t1, const struct timespec* t0){ 00028 return ((t1->tv_sec == t0->tv_sec) && (t1->tv_nsec == t0->tv_nsec)); 00029 } 00030 00031 static inline bool timespec_equal(const struct timespec t1, const struct timespec t0){ 00032 return ((t1.tv_sec == t0.tv_sec) && (t1.tv_nsec == t0.tv_nsec)); 00033 } 00034 00035 static inline void timespec_reset(struct timespec* ret){ 00036 ret->tv_sec = 0; 00037 ret->tv_nsec = 0; 00038 } 00039 00040 static inline void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec){ 00041 while (nsec > NSEC_PER_SEC){ 00042 nsec -= NSEC_PER_SEC; 00043 ++sec; 00044 } 00045 while(nsec < 0){ 00046 nsec += NSEC_PER_SEC; 00047 --sec; 00048 } 00049 ts->tv_sec = sec; 00050 ts->tv_nsec = nsec; 00051 } 00052 00053 static inline struct timespec convert_to_timespec(const double timeValue){ 00054 struct timespec ret; 00055 double seconds = 0; 00056 long nsec = static_cast<long>(modf(timeValue, &seconds) * static_cast<double>(NSEC_PER_SEC)); 00057 time_t sec = static_cast<time_t>(seconds); 00058 00059 set_normalized_timespec(&ret, sec, nsec); 00060 00061 return ret; 00062 } 00063 00064 static inline double convert_from_timespec(const timespec actual){ 00065 return (static_cast<double>(actual.tv_sec) + (static_cast<double>(actual.tv_nsec) / static_cast<double>(NSEC_PER_SEC))); 00066 } 00067 00068 static inline void timespec_add(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){ 00069 time_t sec = t1->tv_sec + t0->tv_sec; 00070 long nsec = t1->tv_nsec + t0->tv_nsec; 00071 00072 set_normalized_timespec(ret, sec, nsec); 00073 } 00074 00075 static inline void timespec_add(struct timespec *ret, const struct timespec t1, const struct timespec t0){ 00076 return timespec_add(ret, &t1, &t0); 00077 } 00078 00079 static inline struct timespec timespec_add(const struct timespec t1, const struct timespec t0){ 00080 struct timespec ret; 00081 timespec_add(&ret, &t1, &t0); 00082 return ret; 00083 } 00084 00085 static inline struct timespec timespec_add(const struct timespec t1, const double time0){ 00086 struct timespec ret; 00087 struct timespec t0; 00088 t0 = convert_to_timespec(time0); 00089 00090 timespec_add(&ret, &t1, &t0); 00091 00092 return ret; 00093 } 00094 00095 static inline void timespec_subtract(struct timespec *ret, const struct timespec* t1, const struct timespec* t0){ 00096 time_t sec = t1->tv_sec - t0->tv_sec; 00097 long nsec = t1->tv_nsec - t0->tv_nsec; 00098 00099 set_normalized_timespec(ret, sec, nsec); 00100 } 00101 00102 static inline void timespec_subtract(struct timespec *ret, const struct timespec t1, const struct timespec t0){ 00103 return timespec_subtract(ret, &t1, &t0); 00104 } 00105 00106 static inline struct timespec timespec_subtract(const struct timespec t1, const struct timespec t0){ 00107 struct timespec ret; 00108 timespec_subtract(&ret, &t1, &t0); 00109 return ret; 00110 } 00111 00112 static inline struct timespec timespec_subtract(const struct timespec t1, const double time0){ 00113 struct timespec ret; 00114 struct timespec t0; 00115 t0 = convert_to_timespec(time0); 00116 00117 timespec_subtract(&ret, &t1, &t0); 00118 00119 return ret; 00120 } 00121 00122 static inline double diff_timespec(struct timespec* ret, const struct timespec *t1, const struct timespec* t0){ 00123 struct timespec actual; 00124 time_t sec = 0; 00125 long nsec = 0; 00126 00127 if(timespec_greater(t1, t0)){ 00128 sec = t1->tv_sec - t0->tv_sec; 00129 nsec = t1->tv_nsec - t0->tv_nsec; 00130 00131 set_normalized_timespec(&actual, sec, nsec); 00132 00133 if(ret != NULL){ 00134 ret->tv_sec = actual.tv_sec; 00135 ret->tv_nsec = actual.tv_nsec; 00136 } 00137 00138 return convert_from_timespec(actual); 00139 } 00140 else{ 00141 sec = t0->tv_sec - t1->tv_sec; 00142 nsec = t0->tv_nsec - t1->tv_nsec; 00143 00144 // Do nothing with the ret value as the ret value would have to store a negative, which it can't. 00145 00146 set_normalized_timespec(&actual, sec, nsec); 00147 00148 return (-convert_from_timespec(actual)); 00149 } 00150 } 00151 00152 static inline double diff_timespec(struct timespec* ret, const struct timespec t1, const struct timespec t0){ 00153 return diff_timespec(ret, &t1, &t0); 00154 } 00155 00156 static inline double diff_timespec(const struct timespec t1, const struct timespec t0){ 00157 return diff_timespec(NULL, &t1, &t0); 00158 } 00159 00160 00161 static inline double diff_timespec(const struct timespec* t1, const struct timespec* t0){ 00162 return diff_timespec(NULL, t1, t0); 00163 } 00164 00165 00166 static inline void get_highres_clock(struct timespec* ret){ 00167 if(clock_gettime(CLOCK_REALTIME, ret) != 0){ 00168 // Unable to get high resolution time - fail over to low resolution time 00169 timeval lowResTime; 00170 gettimeofday(&lowResTime, NULL); 00171 ret->tv_sec = lowResTime.tv_sec; 00172 ret->tv_nsec = lowResTime.tv_usec*1000; 00173 } 00174 } 00175 00176 static inline struct timespec get_highres_clock(){ 00177 struct timespec ret; 00178 get_highres_clock(&ret); 00179 return ret; 00180 } 00181 00182 static inline bool timespec_empty(const struct timespec* ret){ 00183 return ( (ret->tv_sec == 0 ) && (ret->tv_nsec == 0) ); 00184 } 00185 00186 static inline bool timespec_empty(const struct timespec ret){ 00187 return timespec_empty(&ret); 00188 } 00189 00190 #endif /* HIGH_RES_TIME_FUNCTIONS_H */