TimeStampCounter.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <iostream>
00032 #include <fesa-core/Diagnostic/TimeStampCounter.h>
00033
00034 namespace fesa
00035 {
00036
00037 double TsCounter::mPeriod = 0;
00038
00039 void TsCounter::calibrateCountPeriod(uint32_t inDelay, uint32_t inTimes)
00040 {
00041
00042 if (mHardware)
00043 {
00044 #if defined (__GNUG__) && (defined (__i386__) || defined (__PPC__))
00045 double lPeriod = 0;
00046
00047 for (uint32_t i = 0; i < inTimes; ++i)
00048 {
00049 timeval lStartTime, lTime;
00050 ::gettimeofday(&lStartTime, 0);
00051 uint64_t lStartCount = getCount();
00052
00053 struct timespec theDelay, time_left_before_wakeup;
00054 int32_t sec = inDelay / 1000;
00055 int32_t nsec = 0;
00056 if ((nsec = inDelay % 1000))
00057 nsec *= (int32_t) 1E6;
00058 theDelay.tv_sec = sec;
00059 theDelay.tv_nsec = nsec;
00060 nanosleep(&theDelay, &time_left_before_wakeup);
00061 ::gettimeofday(&lTime, 0);
00062 uint64_t lCount = getCount() - lStartCount;
00063 lTime.tv_sec -= lStartTime.tv_sec;
00064 lTime.tv_usec -= lStartTime.tv_usec;
00065
00066 if (i != 0)
00067 lPeriod += (lTime.tv_sec + lTime.tv_usec * 0.000001) / lCount;
00068 }
00069 mPeriod = lPeriod / (inTimes - 1);
00070 #else
00071
00072 mPeriod = 0.000001;
00073 #endif
00074 }
00075 else
00076 {
00077
00078 mPeriod = 0.000001;
00079 }
00080 }
00081
00082 uint64_t TsCounter::getCount(void) const
00083 {
00084 uint64_t lCount = 0;
00085
00086 if (mHardware)
00087 {
00088 #if defined (__GNUG__) && defined (__i386__)
00089 __asm__ volatile("rdtsc" : "=A" (lCount));
00090 #else
00091 #if defined (__GNUG__) && defined (__PPC__)
00092 register uint32_t lLow;
00093 register uint32_t lHigh1;
00094 register uint32_t lHigh2;
00095 do
00096 {
00097
00098 __asm__ volatile ( "mftbu %0" : "=r" (lHigh1) );
00099 __asm__ volatile ( "mftb %0" : "=r" (lLow) );
00100 __asm__ volatile ( "mftbu %0" : "=r" (lHigh2) );
00101 }while(lHigh1 != lHigh2);
00102
00103 uint32_t *lPtr = (uint32_t*) &lCount;
00104 *lPtr++ = lHigh1; *lPtr = lLow;
00105 #else
00106 timeval lCurrent;
00107 ::gettimeofday(&lCurrent, 0);
00108 lCount = (uint64_t)lCurrent.tv_sec*1000000 + lCurrent.tv_usec;
00109 #endif
00110 #endif
00111 }
00112 else
00113 {
00114 timeval lCurrent;
00115 ::gettimeofday(&lCurrent, 0);
00116 lCount = (uint64_t) lCurrent.tv_sec * 1000000 + lCurrent.tv_usec;
00117 }
00118
00119 return lCount;
00120 }
00121 }