Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/Timer.h
00001 #ifndef GAMMA_TIMER_H_INC
00002 #define GAMMA_TIMER_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information */
00006 
00007 namespace gam{
00008 
00009 // We use an 8-byte signed integer to represent time in nanoseconds.  This
00010 // allows us represent times accurately up to +/- 292.5 years.
00011 
00012 // Windows
00013 #ifdef WIN32
00014     #include <windows.h>
00015     typedef __int64 nsec_t;     
00016     
00017 // Posix (Mac, Linux)
00018 #else
00019     #include <sys/time.h>
00020     #include <time.h>
00021     typedef long long nsec_t;   
00022     
00023 #endif /* platform specific */
00024 
00025 
00027 static void sleep(nsec_t dt);
00028 
00030 static void sleepSec(double sec);
00031 
00033 static nsec_t sleepUntil(nsec_t t);
00034 
00036 static nsec_t timeNow();
00037 
00039 static double toSec(nsec_t nsec);
00040 
00042 static nsec_t toNsec(double sec);
00043 
00044 
00046 class Timer {
00047 public:
00048     Timer();
00049     ~Timer();
00050 
00051     nsec_t elapsed();       
00052     double elapsedSec();    
00053     double elapsedMSec();   
00054     void start();           
00055     void stop();            
00056 
00057 private:
00058     nsec_t mStart, mStop;   // start and stop times
00059 };
00060 
00061 
00062 
00063 // Implementation_______________________________________________________________
00064 
00065 inline void sleepSec(double t){ sleep(toNsec(t)); }
00066 
00067 inline nsec_t sleepUntil(nsec_t t){
00068     nsec_t now = timeNow();
00069     if(t > now) sleep(t - now);
00070     return t - now;
00071 }
00072 
00073 inline double toSec(nsec_t nsec){ return ((double)nsec) * 1e-9; }
00074 inline nsec_t toNsec(double sec){ return (nsec_t)(sec * 1e9); }
00075 
00076 inline void Timer::start(){ mStart = timeNow(); }
00077 inline void Timer::stop (){ mStop  = timeNow(); }
00078 inline nsec_t Timer::elapsed(){ return mStop - mStart; }
00079 inline double Timer::elapsedSec() { return toSec(elapsed()); }
00080 inline double Timer::elapsedMSec(){ return ((double)elapsed() * 1e-6); }
00081 
00082 
00083 // platform specific
00084 
00085 // Windows
00086 #ifdef WIN32
00087 
00088     inline nsec_t timeNow(){
00089         return (nsec_t)timeGetTime() * (nsec_t)1e6;
00090     }
00091 
00092     inline void sleep(nsec_t dt){
00093         Sleep((DWORD)(dt / (nsec_t)1e6));
00094     }
00095 
00096     inline Timer::Timer(){
00097         timeBeginPeriod(1);     // adjust timer precision (1 millisecond)
00098     }
00099 
00100     inline Timer::~Timer(){
00101         timeEndPeriod(1);       // must call on program exit!
00102     }
00103 
00104 // Posix (Mac, Linux)
00105 #else
00106 
00107     #define NS_S ((nsec_t)1e9)
00108 
00109     inline nsec_t timeNow(){
00110         timeval t;
00111         gettimeofday(&t, NULL); 
00112         return ((nsec_t)t.tv_sec) * NS_S + (nsec_t)(t.tv_usec * 1e3);
00113     }
00114 
00115     inline void sleep(nsec_t t){
00116         time_t sec = (time_t)(t / NS_S);
00117         timespec tspec = { sec, (long)(t - ((nsec_t)sec * NS_S)) }; // { sec, nsec }
00118         nanosleep(&tspec, NULL);
00119     }
00120 
00121     #undef NS_S
00122 
00123     inline Timer::Timer(){}
00124     inline Timer::~Timer(){}
00125     
00126 #endif  /* platform specific */
00127 
00128 } // gam::
00129 
00130 #endif
00131