00001 #ifndef _TIMER_H_ 00002 #define _TIMER_H_ 00003 00004 #include "Object.h" 00005 #include "misc.h" 00006 #include <list> 00007 #include <unistd.h> 00008 #include <sys/time.h> 00009 #include <unistd.h> 00010 #include <pthread.h> 00011 00012 namespace RobotFlow { 00013 00014 //(ER) for debugging 00015 extern timespec startTime; 00016 00017 class Timer : public FD::Object { 00018 00019 friend void* timer_thread (void* timerPtr); 00020 00021 private: 00022 00023 pthread_t m_thread; 00024 pthread_mutex_t m_mutex; 00025 long m_remaining_time; 00026 00027 void lock () { 00028 pthread_mutex_lock(&m_mutex); 00029 } 00030 00031 void unlock() { 00032 pthread_mutex_unlock(&m_mutex); 00033 } 00034 00035 public: 00036 00037 Timer(long msec) { 00038 m_remaining_time = msec; 00039 pthread_mutex_init(&m_mutex, NULL); 00040 } 00041 00042 ~Timer() { 00043 stop(); 00044 } 00045 00046 void start() { 00047 00048 lock(); 00049 pthread_create(&m_thread, NULL,timer_thread, this); 00050 unlock(); 00051 } 00052 00053 void stop() { 00054 00055 void *return_value; 00056 00057 lock(); 00058 m_remaining_time = 0; 00059 unlock(); 00060 00061 pthread_join(m_thread,&return_value); 00062 } 00063 00064 bool ready() { 00065 lock(); 00066 bool is_ready = (m_remaining_time == 0); 00067 unlock(); 00068 return is_ready; 00069 } 00070 00071 void reset (long msec) { 00072 00073 //usec 00074 stop(); 00075 m_remaining_time = msec; 00076 start(); 00077 } 00078 00079 virtual void printOn(std::ostream &out=std::cout) const { 00080 out<<"Timer : "<<m_remaining_time<<" msec"<<std::endl; 00081 } 00082 00083 }; 00084 00085 00086 // TIMING functions 00087 00088 //The definition for timespec structure, from time.h 00089 /* POSIX.1b structure for a time value. This is like a `struct timeval' but 00090 has nanoseconds instead of microseconds. */ 00091 //struct timespec 00092 // { 00093 // __time_t tv_sec; /* Seconds. */ 00094 // long int tv_nsec; /* Nanoseconds. */ 00095 // }; 00096 00097 // Puts current system time in the timespec structure 00098 void vGetSystemTime( timespec* a_ptNow ); 00099 // Returns the result of ac_ptFinal - ac_ptInitial in milliseconds 00100 long lMsBetweenTimes( timespec const* ac_ptInitial, timespec const* ac_ptFinal ); 00101 // Returns the number of milliseconds remaining until 'a_ptFinal' time 00102 long lMsRemainingUntil( timespec const* ac_ptFinal ); 00103 // Returns the number of milliseconds elapsed since 'a_ptInitial' time 00104 long lMsElapsedSince( timespec const* ac_ptInitial ); 00105 // Adds 'a_ulNbrMs' milliseconds to 'a_ptInitial' time 00106 void vAddMsToTime( unsigned long a_ulNbrMs, timespec* a_ptInitial ); 00107 00108 //BE CAREFULL: The following functions should only be used to calculate 00109 // relatively short periods of time (max ~30 min). Otherwise, there will 00110 // be overflow. 00111 // Returns the result of ac_ptFinal - ac_ptInitial in microseconds 00112 long lUsBetweenTimes( timespec const* ac_ptInitial, timespec const* ac_ptFinal ); 00113 // Returns the number of microseconds remaining until 'a_ptFinal' time 00114 long lUsRemainingUntil( timespec const* ac_ptFinal ); 00115 // Returns the number of microseconds elapsed since 'a_ptInitial' time 00116 long lUsElapsedSince( timespec const* ac_ptInitial ); 00117 // Adds 'a_ulNbrUs' microseconds to 'a_ptInitial' time 00118 void vAddUsToTime( unsigned long a_ulNbrUs, timespec* a_ptInitial ); 00119 00120 //Makes the current thread sleep for "a_ulNbrUs" microseconds 00121 void thread_usleep( unsigned long a_ulNbrUs ); 00122 00123 }//namespace RobotFlow 00124 00125 #endif