GNU Radio 3.3.0 C++ API
highResTimeFunctions.h
Go to the documentation of this file.
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 */