StopWatch.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012 SCHUNK GmbH & Co. KG
00003  * Copyright (c) 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *   http://www.apache.org/licenses/LICENSE-2.0
00010 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "StopWatch.h"
00019 
00020 // ========================================================================== ;
00021 //                                                                            ;
00022 //                  private auxiliary functions          
00023 //                                                                            ;
00024 // ========================================================================== ;
00025 
00026 // ========================================================================== ;
00027 //                                                                            ;
00028 //                  protected auxiliary functions
00029 //                                                                            ;
00030 // ========================================================================== ;
00031 
00032 // ========================================================================= ;
00033 //                                                                           ;
00034 //                      constructors / destructor                            ;
00035 //                                                                           ;
00036 // ========================================================================= ;
00037 
00038 CStopWatch::CStopWatch()
00039           : CMessage("CStopWatch", g_iDebugLevel, g_bDebug, g_bDebugFile),
00040                 m_bStartFlag(false),
00041                 m_bStopFlag(false),
00042                 m_iTimeType(util_REAL_TIME)
00043 {
00044                 m_iFirst = 0;
00045                 m_iLast = 0;
00046                 m_fOverflowTime = 0.0;
00047                 
00048 #if defined(_WIN32)
00049                 QueryPerformanceFrequency(&m_TempTime);   // pointer to current frequency
00050                 frequencyE = m_TempTime.LowPart;
00051                 m_FirstTime.HighPart = 0;
00052                 m_FirstTime.LowPart = 0;
00053                 m_LastTime.HighPart = 0;
00054                 m_LastTime.LowPart = 0;
00055                 m_TempTime.HighPart = 0;
00056                 m_TempTime.LowPart = 0;
00057                 m_ActualTime.HighPart = 0;
00058                 m_ActualTime.LowPart = 0;
00059 #elif defined(__QNX__)
00060                 m_FirstTime.tv_sec = 0;
00061                 m_FirstTime.tv_nsec = 0;
00062                 m_LastTime.tv_sec = 0;
00063                 m_LastTime.tv_nsec = 0;
00064                 m_TempTime.tv_sec = 0;
00065                 m_TempTime.tv_nsec = 500000;
00066                 clock_setres(CLOCK_REALTIME, &m_TempTime);
00067                 m_ActualTime.tv_sec = 0;
00068                 m_ActualTime.tv_nsec = 0;
00069 #else
00070                 m_FirstTime.tv_sec = 0;
00071                 m_FirstTime.tv_usec = 0;
00072                 m_LastTime.tv_sec = 0;
00073                 m_LastTime.tv_usec = 0;
00074                 m_TempTime.tv_sec = 0;
00075                 m_TempTime.tv_usec = 0;
00076                 m_ActualTime.tv_sec = 0;
00077                 m_ActualTime.tv_usec = 0;
00078 #endif
00079 }
00080 
00081 CStopWatch::CStopWatch(util_TimeMeasurementType iTimeType)
00082           : CMessage("CStopWatch", g_iDebugLevel, g_bDebug, g_bDebugFile),
00083                 m_bStartFlag(false),
00084                 m_bStopFlag(false),
00085                 m_iTimeType(iTimeType)
00086 {
00087                 m_iFirst = 0;
00088                 m_iLast = 0;
00089                 m_fOverflowTime = 0.0;
00090                 
00091 #if defined(_WIN32)
00092                 QueryPerformanceFrequency(&m_TempTime);   // pointer to current frequency
00093                 frequencyE = m_TempTime.LowPart;
00094                 m_FirstTime.HighPart = 0;
00095                 m_FirstTime.LowPart = 0;
00096                 m_LastTime.HighPart = 0;
00097                 m_LastTime.LowPart = 0;
00098                 m_TempTime.HighPart = 0;
00099                 m_TempTime.LowPart = 0;
00100                 m_ActualTime.HighPart = 0;
00101                 m_ActualTime.LowPart = 0;
00102 #elif defined(__QNX__)
00103                 m_FirstTime.tv_sec = 0;
00104                 m_FirstTime.tv_nsec = 0;
00105                 m_LastTime.tv_sec = 0;
00106                 m_LastTime.tv_nsec = 0;
00107                 m_TempTime.tv_sec = 0;
00108                 m_TempTime.tv_nsec = 500000;
00109                 clock_setres(CLOCK_REALTIME, &m_TempTime);
00110                 m_ActualTime.tv_sec = 0;
00111                 m_ActualTime.tv_nsec = 0;
00112 #else
00113                 m_FirstTime.tv_sec = 0;
00114                 m_FirstTime.tv_usec = 0;
00115                 m_LastTime.tv_sec = 0;
00116                 m_LastTime.tv_usec = 0;
00117                 m_TempTime.tv_sec = 0;
00118                 m_TempTime.tv_usec = 0;
00119                 m_ActualTime.tv_sec = 0;
00120                 m_ActualTime.tv_usec = 0;
00121 #endif
00122 }
00123 
00124 CStopWatch::CStopWatch(const CStopWatch& )
00125 {
00126         error(-1, "copy constructor : method should not be called!");
00127 }
00128 
00129 // ========================================================================= ;
00130 //                                                                           ;
00131 //                  operators
00132 //                                                                           ;
00133 // ========================================================================= ;
00134 
00135 CStopWatch& CStopWatch::operator=(const CStopWatch&)
00136 {
00137         error(-1, "assignment operator : method should not be called!");
00138         return *this;
00139 }
00140 
00141 // ========================================================================= ;
00142 //                                                                           ;
00143 //                  query functions
00144 //                                                                           ;
00145 // ========================================================================= ;
00146 
00147 // ========================================================================= ;
00148 //                                                                           ;
00149 //                  modifiy functions
00150 //                                                                           ;
00151 // ========================================================================= ;
00152 
00153 // ========================================================================= ;
00154 //                                                                           ;
00155 //                  I/O
00156 //                                                                           ;
00157 // ========================================================================= ;
00158 
00159 /*
00160         This member function computes the difference between the taken start and stop times, if both are valid.
00161         Attention: cpu-time is calculated in a wrong way, if process lasts longer than 35 min or 2 processes
00162                     are stoped with the second beginning more than half an hour after the first one was started.
00163                    Look for function testOverflow in any of these cases.
00164          difference or $0.0$ if call was invalid
00165 */
00166 double CStopWatch::executionTime()
00167 {
00168         // --- check
00169         if ( !(m_bStartFlag && m_bStopFlag) )
00170         {
00171                 warning("executionTime() : return 0.0, for you must call 'start()' and 'stop()' first");
00172                 return 0.0;
00173         };
00174 
00175         if(m_iTimeType == util_CPU_TIME)
00176         {
00177                 if ((m_iLast < m_iFirst) && (m_fOverflowTime == 0))
00178                 {
00179                         warning("executionTime() : return 0.0, for start time is bigger than stop time and no overflow was detected");
00180                         return 0.0;
00181                 }
00182                 else
00183                 {
00184                         double fTempTime;
00185                         testOverflow();
00186                         fTempTime = m_fOverflowTime;
00187                         m_fOverflowTime = 0.0;
00188                         return fTempTime + (double(m_iLast - m_iFirst)) / CLOCKS_PER_SEC;
00189                 };
00190         }
00191         else
00192         {
00193                 #if defined(__QNX__)
00194                 return (m_LastTime.tv_sec-m_FirstTime.tv_sec
00195                   +(double(m_LastTime.tv_nsec-m_FirstTime.tv_nsec)/1e+9));
00196                 #elif defined(_WIN32)
00197                 return double(m_LastTime.LowPart-m_FirstTime.LowPart)/frequencyE;
00198                 #else
00199                 return (m_LastTime.tv_sec-m_FirstTime.tv_sec
00200                   +(double(m_LastTime.tv_usec-m_FirstTime.tv_usec)/1e+6));
00201                 #endif   
00202         };
00203 };
00204 
00205 // ========================================================================= ;
00206 //                                                                           ;
00207 //                  exec functions
00208 //                                                                           ;
00209 // ========================================================================= ;
00210 
00211 void  CStopWatch::start() 
00212 {
00213         if(m_iTimeType == util_CPU_TIME)
00214         {
00215                 m_iFirst=clock();
00216                 m_bStartFlag = true;
00217                 m_bStopFlag = false;
00218         }
00219         else
00220         {
00221 #if defined(__QNX__)
00222                 clock_gettime(CLOCK_REALTIME,&m_FirstTime);
00223 #elif defined(_WIN32)
00224                 QueryPerformanceCounter(&m_FirstTime);
00225 #else
00226                 gettimeofday(&m_FirstTime,0);
00227 #endif
00228                 m_bStartFlag = true;
00229                 m_bStopFlag = false;
00230         };
00231 };
00232 
00233 /*
00234         This member function sets the stop time of the watch to the current clock value, if a valid start time exists.
00235 */
00236 void CStopWatch::stop()
00237 {
00238         if (m_bStartFlag)
00239         {
00240                 if(m_iTimeType == util_CPU_TIME)
00241                 {
00242                         m_iLast = clock();
00243                 }
00244                 else
00245                 {
00246                         #if defined(__QNX__)
00247                         clock_gettime(CLOCK_REALTIME,&m_LastTime);
00248                         #elif defined(_WIN32)
00249                         QueryPerformanceCounter(&m_LastTime);
00250                         #else
00251                         gettimeofday(&m_LastTime,0);
00252                         #endif
00253                 };
00254                 m_bStopFlag = true;
00255         }
00256         else
00257         {
00258                 m_bStopFlag = false;
00259                 warning("stop() : you must call 'start()' first");
00260         };
00261 };
00262 
00263 // -------------------------------------------------------------------------- ;
00264 
00265 /*
00266         This member function continues the run of the clock after is has been stopped.
00267 */
00268 void CStopWatch::cont()
00269 {
00270         if (m_bStartFlag && m_bStopFlag)
00271         {
00272                 if(m_iTimeType == util_CPU_TIME)
00273                 {  
00274                         m_iFirst      = m_iFirst + (clock() - m_iLast);
00275                         m_bStopFlag  = false;
00276                 }
00277                 else
00278                 {
00279                         #if defined(__QNX__)
00280                         clock_gettime(CLOCK_REALTIME,&m_TempTime);
00281                         m_FirstTime.tv_sec +=  m_TempTime.tv_sec-m_LastTime.tv_sec;
00282                         m_FirstTime.tv_nsec +=  m_TempTime.tv_nsec-m_LastTime.tv_nsec;
00283                         #elif defined(_WIN32)
00284                         QueryPerformanceCounter(&m_TempTime);
00285                         m_FirstTime.HighPart +=  m_TempTime.HighPart-m_LastTime.HighPart;
00286                         m_FirstTime.LowPart +=  m_TempTime.LowPart-m_LastTime.LowPart;
00287                         #else
00288                         gettimeofday(&m_TempTime,0);
00289                         m_FirstTime.tv_sec +=  m_TempTime.tv_sec-m_LastTime.tv_sec;
00290                         m_FirstTime.tv_usec +=  m_TempTime.tv_usec-m_LastTime.tv_usec;
00291                         #endif
00292                 };
00293         }
00294         else
00295                 warning("cont() : you must call 'start()' and 'stop()' first");
00296 };
00297 
00298 // This member function returns the current real time in [s].
00299 double CStopWatch::realTime() 
00300 {
00301         #if defined(__QNX__)
00302         clock_gettime(CLOCK_REALTIME,&m_ActualTime);
00303         return (m_ActualTime.tv_sec+(double(m_ActualTime.tv_nsec)/1e+9));
00304         #elif defined(_WIN32)
00305         QueryPerformanceCounter(&m_ActualTime);
00306         return (double(m_ActualTime.LowPart)/frequencyE);
00307         #else
00308         gettimeofday(&m_ActualTime,0);
00309         return (m_ActualTime.tv_sec
00310           +(double(m_ActualTime.tv_usec)/1e+6));
00311         #endif
00312 };
00313 
00314 // This member function returns the real time resolution in [s].
00315 double CStopWatch::realTimeResolution() 
00316 {
00317         #if defined(__QNX__)
00318         clock_getres(CLOCK_REALTIME,&m_TempTime);
00319         return (m_TempTime.tv_sec+(double(m_TempTime.tv_nsec)/1e+9));
00320         #elif defined(_WIN32)
00321         warning("unkown real time resolution\n");
00322         return 0.001;
00323         #else
00324         warning("unkown real time resolution\n");
00325         return 0.001;
00326         #endif
00327 };
00328 
00329 /*
00330         This member function waits the given realtime in [ms].
00331         uiTime: realtime in [ms]
00332 */
00333 void CStopWatch::wait(unsigned int uiTime)
00334 {
00335         bool bTimeOutFlag = false;
00336 #if defined(__QNX__)
00337         unsigned int uiSec, uiNSec;
00338         uiSec = uiTime / 1000;
00339         uiNSec = (uiTime % 1000) * 1000000;
00340         clock_gettime(CLOCK_REALTIME, &m_TempTime);
00341         m_TempTime.tv_sec = m_TempTime.tv_sec + uiSec + (m_TempTime.tv_nsec + uiNSec) / 1000000000;
00342         m_TempTime.tv_nsec = (m_FirstTime.tv_nsec + uiNSec) % 1000000000;
00343         do
00344         {
00345                 clock_gettime(CLOCK_REALTIME, &m_ActualTime);
00346                 if(m_ActualTime.tv_sec > m_TempTime.tv_sec)
00347                         bTimeOutFlag = true;
00348                 else if((m_ActualTime.tv_sec == m_TempTime.tv_sec) && (m_ActualTime.tv_nsec > m_TempTime.tv_nsec))
00349                         bTimeOutFlag = true;
00350         }
00351         while(!bTimeOutFlag);
00352 #elif defined(_WIN32)
00353         Sleep(uiTime);
00354 #else
00355         unsigned int uiSec, uiUSec;
00356         uiSec = uiTime / 1000;
00357         uiUSec = (uiTime % 1000) * 1000;
00358         gettimeofday(&m_TempTime, 0);
00359         m_TempTime.tv_sec = m_TempTime.tv_sec + uiSec + (m_TempTime.tv_usec + uiUSec) / 1000000;
00360         m_TempTime.tv_usec = (m_TempTime.tv_usec + uiUSec) % 1000000;
00361         do
00362         {
00363                 gettimeofday(&m_ActualTime, 0);
00364                 if(m_ActualTime.tv_sec > m_TempTime.tv_sec)
00365                         bTimeOutFlag = true;
00366                 else if((m_ActualTime.tv_sec == m_TempTime.tv_sec) && (m_ActualTime.tv_usec > m_TempTime.tv_usec))
00367                         bTimeOutFlag = true;
00368         }
00369         while(!bTimeOutFlag);
00370 #endif
00371 };
00372 
00373 // -------------------------------------------------------------------------- ;
00374 
00375 /*
00376         This member function returns the current date and time in local representation
00377         char* to hold the local date and time
00378 */
00379 void CStopWatch::date(char* acDate)  const
00380 {
00381         time_t currentTime;
00382         struct tm *localTime;
00383 
00384         // get the current time
00385         currentTime = time (NULL);
00386 
00387         // convert it to local time representation
00388         localTime = localtime (&currentTime);
00389 
00390         // print it out in a buffer
00391         strftime (acDate, 256, "%a %b %d %I:%M:%S %p %Z %Y", localTime);
00392 };
00393 
00394 // -------------------------------------------------------------------------- ;
00395 
00396 /*
00397         This member function returns the current weekday in local representation
00398         string to hold the local weekday
00399 */
00400 void CStopWatch::weekday(char* acWeekDay)  const
00401 {
00402         time_t currentTime;
00403         struct tm *localTime;
00404 
00405         // get the current time
00406         currentTime = time (NULL);
00407 
00408         // convert it to local time representation
00409         localTime = localtime (&currentTime);
00410 
00411         // print it out in a buffer
00412         strftime (acWeekDay, 256, "%A", localTime);
00413 };
00414 
00415 // ========================================================================= ;
00416 
00417 /*
00418         This function tests, if there is an overflow at the clock counter
00419         Function should be called at least every 30 min., if the cpu_time is stoped
00420         Otherwise there might be more than one overflow and results are wrong!
00421 */
00422 void CStopWatch::testOverflow()
00423 {
00424         if(m_iTimeType == util_CPU_TIME)
00425         {
00426                 stop();
00427                 if (m_iLast < m_iFirst)
00428                 {
00429                         m_fOverflowTime += (double(m_iLast - m_iFirst + ULONG_MAX)) / CLOCKS_PER_SEC;
00430                         start();
00431                 }
00432                 else
00433                         cont();
00434         }
00435         else
00436                 warning("testOverflow() : overflow has to be tested only when measuring cpu-time");
00437 };
00438 
00439 // ========================================================================= ;


schunk_libm5api
Author(s): Florian Weisshardt
autogenerated on Sat Jun 8 2019 20:25:13