IBR-DTNSuite
0.8
|
00001 /* 00002 * TimeMeasurement.cpp 00003 * 00004 * Created on: 20.01.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include "ibrcommon/config.h" 00009 #include "ibrcommon/TimeMeasurement.h" 00010 #include <iostream> 00011 #include <iomanip> 00012 #include <stdio.h> 00013 00014 #ifdef HAVE_FEATURES_H 00015 #include <features.h> 00016 #endif 00017 00018 #ifdef HAVE_MACH_MACH_TIME_H 00019 #include <mach/mach_time.h> 00020 #endif 00021 00022 namespace ibrcommon 00023 { 00024 TimeMeasurement::TimeMeasurement() 00025 { 00026 start(); stop(); 00027 } 00028 00029 TimeMeasurement::~TimeMeasurement() 00030 { 00031 } 00032 00033 void TimeMeasurement::start() 00034 { 00035 #ifdef HAVE_MACH_MACH_TIME_H 00036 _uint64_start = mach_absolute_time(); 00037 #else 00038 // set sending time 00039 clock_gettime(CLOCK_MONOTONIC, &_start); 00040 00041 #endif 00042 } 00043 00044 void TimeMeasurement::stop() 00045 { 00046 #ifdef HAVE_MACH_MACH_TIME_H 00047 _uint64_end = mach_absolute_time(); 00048 #else 00049 // set receiving time 00050 clock_gettime(CLOCK_MONOTONIC, &_end); 00051 #endif 00052 } 00053 00054 float TimeMeasurement::getMilliseconds() const 00055 { 00056 // calc difference 00057 u_int64_t timeElapsed = getNanoseconds(); 00058 00059 // make it readable 00060 float delay_ms = (float)timeElapsed / 1000000; 00061 00062 return delay_ms; 00063 } 00064 00065 u_int64_t TimeMeasurement::getNanoseconds() const 00066 { 00067 // calc difference 00068 #ifdef HAVE_MACH_MACH_TIME_H 00069 int64_t val = TimeMeasurement::timespecDiff(_uint64_end, _uint64_start); 00070 #else 00071 int64_t val = TimeMeasurement::timespecDiff(&_end, &_start); 00072 #endif 00073 00074 if (val < 0) return 0; 00075 return val; 00076 } 00077 00078 float TimeMeasurement::getMicroseconds() const 00079 { 00080 // calc difference 00081 u_int64_t timeElapsed = getNanoseconds(); 00082 00083 // make it readable 00084 float delay_m = (float)timeElapsed / 1000; 00085 00086 return delay_m; 00087 } 00088 00089 float TimeMeasurement::getSeconds() const 00090 { 00091 return getMilliseconds() / 1000; 00092 } 00093 00094 std::ostream& TimeMeasurement::format(std::ostream &stream, const float value) 00095 { 00096 #ifdef __UCLIBC__ 00097 char buf[32]; 00098 snprintf(buf, 32, "%4.2f", value); 00099 stream << std::string(buf); 00100 #else 00101 stream << std::setiosflags(std::ios::fixed) << std::setprecision(2) << value; 00102 #endif 00103 return stream; 00104 } 00105 00106 std::ostream &operator<<(std::ostream &stream, const TimeMeasurement &measurement) 00107 { 00108 // calc difference 00109 #ifdef HAVE_MACH_MACH_TIME_H 00110 u_int64_t timeElapsed = TimeMeasurement::timespecDiff(measurement._uint64_end, measurement._uint64_start); 00111 #else 00112 u_int64_t timeElapsed = TimeMeasurement::timespecDiff(&(measurement._end), &(measurement._start)); 00113 #endif 00114 00115 // make it readable 00116 float delay_ms = (float)timeElapsed / 1000000; 00117 float delay_sec = delay_ms / 1000; 00118 float delay_min = delay_sec / 60; 00119 float delay_h = delay_min / 60; 00120 00121 if (delay_h > 1) 00122 { 00123 TimeMeasurement::format(stream, delay_h); stream << " h"; 00124 } 00125 else if (delay_min > 1) 00126 { 00127 TimeMeasurement::format(stream, delay_min); stream << " m"; 00128 } 00129 else if (delay_sec > 1) 00130 { 00131 TimeMeasurement::format(stream, delay_sec); stream << " s"; 00132 } 00133 else 00134 { 00135 TimeMeasurement::format(stream, delay_ms); stream << " ms"; 00136 } 00137 00138 return stream; 00139 } 00140 00141 int64_t TimeMeasurement::timespecDiff(const uint64_t &timeA, const uint64_t &timeB) 00142 { 00143 int64_t duration = timeA - timeB; 00144 00145 #ifdef HAVE_MACH_MACH_TIME_H 00146 mach_timebase_info_data_t info; 00147 mach_timebase_info(&info); 00148 00149 /* Convert to nanoseconds */ 00150 duration *= info.numer; 00151 duration /= info.denom; 00152 #endif 00153 return duration; 00154 } 00155 00156 int64_t TimeMeasurement::timespecDiff(const struct timespec *timeA_p, const struct timespec *timeB_p) 00157 { 00158 //Casting to 64Bit, otherwise it caps out at ~ 5 secs for 32bit machines 00159 return ( ( (int64_t)(timeA_p->tv_sec) * 1e9 + (int64_t)(timeA_p->tv_nsec)) - ( (int64_t)(timeB_p->tv_sec) * 1e9 + (int64_t)(timeB_p->tv_nsec)) ); 00160 } 00161 }