// ============================================================================ // $Id: Timer.cc,v 1.1.1.1 2006-10-25 16:14:15 habbecke Exp $ // ---------------------------------------------------------------------------- #ifndef DOXY_IGNORE_THIS // ---------------------------------------------------------------------------- #include #if defined(OM_CC_MIPS) # include # include #else # include # include #endif #include "Timer.hh" // ---------------------------------------------------------------------------- // ------------------------------------------------------------- namespace ---- namespace OpenMesh { namespace Utils { // ---------------------------------------------------------------------------- using namespace std; // -------------------------------------------------------------- TimerImpl ---- // just a base class for the implementation class TimerImpl { protected: public: TimerImpl() { ; } virtual ~TimerImpl() { ; } virtual void reset(void) = 0; virtual void start(void) = 0; virtual void stop(void) = 0; virtual void cont(void) = 0; virtual double seconds(void) const = 0; }; // compiler and os dependent implementation // ------------------------------------------------------------- windows 32 ---- #if defined(WIN32) && (defined(_MSC_VER) || defined(__INTEL_COMPILER)) #include class TimerImplWin32 : public TimerImpl { protected: LARGE_INTEGER freq_; LARGE_INTEGER count_; LARGE_INTEGER start_; public: TimerImplWin32(void); ~TimerImplWin32(void) { ; } virtual void reset(void); virtual void start(void); virtual void stop(void); virtual void cont(void); virtual double seconds(void) const; }; TimerImplWin32::TimerImplWin32(void) { if (QueryPerformanceFrequency(&freq_)==FALSE) throw std::runtime_error("Performance counter of of stock!"); reset(); } void TimerImplWin32::reset(void) { memset(&count_,0,sizeof(count_)); memset(&start_,0,sizeof(count_)); } void TimerImplWin32::start(void) { reset(); QueryPerformanceCounter(&start_); } void TimerImplWin32::stop(void) { LARGE_INTEGER stop_; QueryPerformanceCounter(&stop_); count_.QuadPart += stop_.QuadPart - start_.QuadPart; } void TimerImplWin32::cont(void) { QueryPerformanceCounter(&start_); } double TimerImplWin32::seconds(void) const { return (double)count_.QuadPart/(double)freq_.QuadPart; } // ------------------------------------------------------------- posix time ---- #elif defined(__GNUC__) && defined(__POSIX__) # include template class TimerImplPosix : public TimerImpl { public: TimerImplPosix() : id_(N), seconds_(0.0) { } ~TimerImplPosix() { } virtual void reset(void) { seconds_ = 0.0; } virtual void start(void) { seconds_ = 0.0; clock_gettime( id_, &start_ ); } virtual void stop(void) { timespec stop; clock_gettime( id_, &stop ); seconds_ += ( stop.tv_sec - start_.tv_sec ); seconds_ += ( (double(stop.tv_nsec-start_.tv_nsec)*1e-9) ); } virtual void cont(void) { clock_gettime( id_, &start_ ); } virtual double seconds() const { return seconds_; } protected: clockid_t id_; double seconds_; timespec start_; }; // ----------------------------------------------------------- gettimeofday ---- #elif defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(WIN32)) # include # include # include class TimerImplGToD: public TimerImpl { public: TimerImplGToD() : seconds_(0.0) { } ~TimerImplGToD() { } virtual void reset(void) { seconds_ = 0.0; } virtual void start(void) { seconds_ = 0.0; gettimeofday( &start_, &tz_ ); } virtual void stop(void) { gettimeofday( &stop_, &tz_ ); seconds_ += (double)(stop_.tv_sec - start_.tv_sec); seconds_ += (double)(stop_.tv_usec- start_.tv_usec)*1e-6; } virtual void cont(void) { gettimeofday( &start_, &tz_); } virtual double seconds() const { return seconds_; } private: struct timeval start_, stop_; struct timezone tz_; double seconds_; }; #else // ---------------------------------------- standard implementation ---- #include static const unsigned long clockticks = CLOCKS_PER_SEC; class TimerImplStd : public TimerImpl { public: TimerImplStd() : freq_(clockticks) { reset(); } ~TimerImplStd() { ; } virtual void reset(void) { count_ = 0; } virtual void start(void) { count_ = 0; start_ = clock(); } virtual void stop(void); virtual void cont(void) { start_ = clock(); } virtual double seconds(void) const { return (double)count_/(double)freq_; } protected: unsigned long freq_; unsigned long count_; unsigned long start_; }; void TimerImplStd::stop(void) { unsigned long stop_ = clock(); count_ += stop_-start_; } #endif // ----------------------------------------------------------------- Timer ---- Timer::Timer(void) { #if defined(WIN32) && defined(_MSC_VER) impl_ = new TimerImplWin32; #elif defined(__GNUC__) && defined(__POSIX__) // CLOCK_REALTIME // CLOCK_MONOTONIC - ? // CLOCK_REALTIME_HR - RTlinux // CLOCK_MONOTONIC_HR - ? # if defined(CLOCK_REALTIME_HR) impl_ = new TimerImplPosix; # else impl_ = new TimerImplPosix; # endif #elif defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(WIN32)) impl_ = new TimerImplGToD; #else impl_ = new TimerImplStd; #endif state_ = Stopped; } Timer::~Timer(void) { delete impl_; state_ = Stopped; } void Timer::reset(void) { state_ = Stopped; impl_->reset(); } void Timer::start(void) { state_ = Running; impl_->start(); } void Timer::stop(void) { impl_->stop(); state_ = Stopped; } void Timer::cont(void) { impl_->cont(); state_ = Running; } double Timer::seconds(void) const { return state_==Stopped ? impl_->seconds() : 0.0; } std::string Timer::as_string(Timer::Format format) { if (state_ == Running) return "Running"; return as_string(impl_->seconds(),format); } std::string Timer::as_string(double seconds, Timer::Format format) { char string[32]; double fraction; double integer; unsigned long t; // double rest; short hour,min,sec; bool negative = false; if ( seconds < 0 ) { negative = true; seconds *= -1; } fraction = modf(seconds,&integer); t = (unsigned long)integer; hour = short( t / 3600L ); t %= 3600L; min = short( t / 60L ); t %= 60L; sec = short( t ); // rest = (double)t + fraction; char *ptr = string; if (negative) *ptr++ = '-'; switch(format) { case Timer::Automatic: if (hour) ptr += sprintf(ptr,"%02dh:",hour); if (min) ptr += sprintf(ptr,"%02dm:",min); else if (ptr>string && hour) ptr += sprintf(ptr,"00m:"); if (sec) ptr += sprintf(ptr,"%02d",sec); else if (ptr>string && min) ptr += sprintf(ptr,"00"); if (!hour && !min) // higher resolution necessary { if (ptr > string && sec) { sprintf(ptr,".%.3fs",fraction); ptr++; while(*(ptr+2)) { *ptr = *(ptr+2); ptr++; } *ptr = '\0'; } else if ( fraction * 1e2 > 0.1) sprintf(ptr,"%.3fcs",fraction*1.e2); else if ( fraction * 1e3 > 0.1) sprintf(ptr,"%.3fms",fraction*1.e3); else if ( fraction * 1e6 > 0.1) sprintf(ptr,"%.1f\xb5s",fraction*1.e6); else if ( fraction * 1e9 > 0.1) sprintf(ptr,"%.1fns",fraction*1.e9); else sprintf(ptr,"%.1fps",fraction*1.e12); } else // append a 's' for seconds! { ptr[0] = 's'; ptr[1] = '\0'; } break; case Timer::Long: ptr += sprintf(ptr,"%02dh:%02dm:%02d",hour,min,sec); sprintf(ptr,".%.12fs",fraction); ptr++; while(*(ptr+2)) { *ptr = *(ptr+2); ptr++; } *ptr = '\0'; break; case Timer::Hours: sprintf(ptr,"%02dh:%02dm:%02ds",hour,min,sec); break; case Timer::Minutes: ptr += sprintf(ptr,"%02dm:%02d", min, sec); sprintf(ptr,".%.2fs",fraction); ptr++; while(*(ptr+2)) { *ptr = *(ptr+2); ptr++; } *ptr = '\0'; break; case Timer::Seconds: sprintf(ptr,"%.3fs",seconds); break; case Timer::HSeconds: sprintf(ptr,"%.3fcs",seconds*1e2); break; case Timer::MSeconds: sprintf(ptr,"%.3fms",seconds*1e3); break; case Timer::MicroSeconds: sprintf(ptr,"%.1f\xb5s",seconds*1e6); break; case Timer::NanoSeconds: sprintf(ptr,"%.1fns",seconds*1e9); break; } return string; } // ============================================================================ } // END_NS_UTILS } // END_NS_OPENMESH // ---------------------------------------------------------------------------- #endif // DOXY_IGNORE_THIS // ============================================================================ // end of file Timer.cc // ============================================================================