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


schunk_libm5api
Author(s): Florian Weisshardt
autogenerated on Thu Aug 27 2015 15:06:52