qwt_system_clock.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_system_clock.h"
00011 
00012 #if QT_VERSION >= 0x040800
00013 #define USE_ELAPSED_TIMER 1
00014 #endif
00015 
00016 #if USE_ELAPSED_TIMER
00017 
00018 #include <qelapsedtimer.h>
00019 
00020 class QwtSystemClock::PrivateData
00021 {
00022 public:
00023     QElapsedTimer timer;
00024 };
00025 
00026 QwtSystemClock::QwtSystemClock()
00027 {
00028     d_data = new PrivateData();
00029 }
00030 
00031 QwtSystemClock::~QwtSystemClock()
00032 {
00033     delete d_data;
00034 }
00035     
00036 bool QwtSystemClock::isNull() const
00037 {
00038     return d_data->timer.isValid();
00039 }
00040         
00041 void QwtSystemClock::start()
00042 {
00043     d_data->timer.start();
00044 }
00045 
00046 double QwtSystemClock::restart()
00047 {
00048     const qint64 nsecs = d_data->timer.restart();
00049     return nsecs / 1e6;
00050 }
00051 
00052 double QwtSystemClock::elapsed() const
00053 {
00054     const qint64 nsecs = d_data->timer.nsecsElapsed();
00055     return nsecs / 1e6;
00056 }
00057     
00058 #else // !USE_ELAPSED_TIMER
00059 
00060 #include <qdatetime.h>
00061 
00062 #if !defined(Q_OS_WIN)
00063 #include <unistd.h>
00064 #endif
00065 
00066 #if defined(Q_OS_MAC)
00067 #include <stdint.h>
00068 #include <mach/mach_time.h>
00069 #define QWT_HIGH_RESOLUTION_CLOCK
00070 #elif defined(_POSIX_TIMERS)
00071 #include <time.h>
00072 #define QWT_HIGH_RESOLUTION_CLOCK
00073 #elif defined(Q_OS_WIN)
00074 #define QWT_HIGH_RESOLUTION_CLOCK
00075 #include <qt_windows.h>
00076 #endif
00077 
00078 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00079 
00080 class QwtHighResolutionClock
00081 {
00082 public:
00083     QwtHighResolutionClock();
00084 
00085     void start();
00086     double restart();
00087     double elapsed() const;
00088 
00089     bool isNull() const;
00090 
00091     static double precision();
00092 
00093 private:
00094 
00095 #if defined(Q_OS_MAC)
00096     static double msecsTo( uint64_t, uint64_t );
00097 
00098     uint64_t d_timeStamp;
00099 #elif defined(_POSIX_TIMERS)
00100 
00101     static double msecsTo( const struct timespec &,
00102         const struct timespec & );
00103 
00104     static bool isMonotonic();
00105 
00106     struct timespec d_timeStamp;
00107     clockid_t d_clockId;
00108 
00109 #elif defined(Q_OS_WIN)
00110 
00111     LARGE_INTEGER d_startTicks;
00112     LARGE_INTEGER d_ticksPerSecond;
00113 #endif
00114 };
00115 
00116 #if defined(Q_OS_MAC)
00117 QwtHighResolutionClock::QwtHighResolutionClock():
00118     d_timeStamp( 0 )
00119 {
00120 }
00121 
00122 double QwtHighResolutionClock::precision()
00123 {
00124     return 1e-6;
00125 }
00126 
00127 void QwtHighResolutionClock::start()
00128 {
00129     d_timeStamp = mach_absolute_time();
00130 }
00131 
00132 double QwtHighResolutionClock::restart()
00133 {
00134     const uint64_t timeStamp = mach_absolute_time();
00135     const double elapsed = msecsTo( d_timeStamp, timeStamp );
00136     d_timeStamp = timeStamp;
00137 
00138     return elapsed;
00139 }
00140 
00141 double QwtHighResolutionClock::elapsed() const
00142 {
00143     return msecsTo( d_timeStamp, mach_absolute_time() );
00144 }
00145 
00146 bool QwtHighResolutionClock::isNull() const
00147 {
00148     return d_timeStamp == 0;
00149 }
00150 
00151 double QwtHighResolutionClock::msecsTo(
00152     uint64_t from, uint64_t to )
00153 {
00154     const uint64_t difference = to - from;
00155 
00156     static double conversion = 0.0;
00157     if ( conversion == 0.0 )
00158     {
00159         mach_timebase_info_data_t info;
00160         kern_return_t err = mach_timebase_info( &info );
00161 
00162         // convert the timebase into ms
00163         if ( err == 0  )
00164             conversion = 1e-6 * ( double ) info.numer / ( double ) info.denom;
00165     }
00166 
00167     return conversion * ( double ) difference;
00168 }
00169 
00170 #elif defined(_POSIX_TIMERS)
00171 
00172 QwtHighResolutionClock::QwtHighResolutionClock()
00173 {
00174     d_clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME;
00175     d_timeStamp.tv_sec = d_timeStamp.tv_nsec = 0;
00176 }
00177 
00178 double QwtHighResolutionClock::precision()
00179 {
00180     struct timespec resolution;
00181 
00182     int clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME;
00183     ::clock_getres( clockId, &resolution );
00184 
00185     return resolution.tv_nsec / 1e3;
00186 }
00187 
00188 inline bool QwtHighResolutionClock::isNull() const
00189 {
00190     return d_timeStamp.tv_sec <= 0 && d_timeStamp.tv_nsec <= 0;
00191 }
00192 
00193 inline void QwtHighResolutionClock::start()
00194 {
00195     ::clock_gettime( d_clockId, &d_timeStamp );
00196 }
00197 
00198 double QwtHighResolutionClock::restart()
00199 {
00200     struct timespec timeStamp;
00201     ::clock_gettime( d_clockId, &timeStamp );
00202 
00203     const double elapsed = msecsTo( d_timeStamp, timeStamp );
00204 
00205     d_timeStamp = timeStamp;
00206     return elapsed;
00207 }
00208 
00209 inline double QwtHighResolutionClock::elapsed() const
00210 {
00211     struct timespec timeStamp;
00212     ::clock_gettime( d_clockId, &timeStamp );
00213 
00214     return msecsTo( d_timeStamp, timeStamp );
00215 }
00216 
00217 inline double QwtHighResolutionClock::msecsTo(
00218     const struct timespec &t1, const struct timespec &t2 )
00219 {
00220     return ( t2.tv_sec - t1.tv_sec ) * 1e3
00221         + ( t2.tv_nsec - t1.tv_nsec ) * 1e-6;
00222 }
00223 
00224 bool QwtHighResolutionClock::isMonotonic()
00225 {
00226     // code copied from qcore_unix.cpp
00227 
00228 #if (_POSIX_MONOTONIC_CLOCK-0 > 0)
00229     return true;
00230 #else
00231     static int returnValue = 0;
00232 
00233     if ( returnValue == 0 )
00234     {
00235 #if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK)
00236         returnValue = -1;
00237 #elif (_POSIX_MONOTONIC_CLOCK == 0)
00238         // detect if the system support monotonic timers
00239         const long x = sysconf( _SC_MONOTONIC_CLOCK );
00240         returnValue = ( x >= 200112L ) ? 1 : -1;
00241 #endif
00242     }
00243 
00244     return returnValue != -1;
00245 #endif
00246 }
00247 
00248 #elif defined(Q_OS_WIN)
00249 
00250 QwtHighResolutionClock::QwtHighResolutionClock()
00251 {
00252     d_startTicks.QuadPart = 0;
00253     QueryPerformanceFrequency( &d_ticksPerSecond );
00254 }
00255 
00256 double QwtHighResolutionClock::precision()
00257 {
00258     LARGE_INTEGER ticks;
00259     if ( QueryPerformanceFrequency( &ticks ) && ticks.QuadPart > 0 )
00260         return 1e3 / ticks.QuadPart;
00261 
00262     return 0.0;
00263 }
00264 
00265 inline bool QwtHighResolutionClock::isNull() const
00266 {
00267     return d_startTicks.QuadPart <= 0;
00268 }
00269 
00270 inline void QwtHighResolutionClock::start()
00271 {
00272     QueryPerformanceCounter( &d_startTicks );
00273 }
00274 
00275 inline double QwtHighResolutionClock::restart()
00276 {
00277     LARGE_INTEGER ticks;
00278     QueryPerformanceCounter( &ticks );
00279 
00280     const double dt = ticks.QuadPart - d_startTicks.QuadPart;
00281     d_startTicks = ticks;
00282 
00283     return dt / d_ticksPerSecond.QuadPart * 1e3;
00284 }
00285 
00286 inline double QwtHighResolutionClock::elapsed() const
00287 {
00288     LARGE_INTEGER ticks;
00289     QueryPerformanceCounter( &ticks );
00290 
00291     const double dt = ticks.QuadPart - d_startTicks.QuadPart;
00292     return dt / d_ticksPerSecond.QuadPart * 1e3;
00293 }
00294 
00295 #endif
00296 
00297 #endif // QWT_HIGH_RESOLUTION_CLOCK
00298 
00299 class QwtSystemClock::PrivateData
00300 {
00301 public:
00302 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00303     QwtHighResolutionClock *clock;
00304 #endif
00305     QTime time;
00306 };
00307 
00309 QwtSystemClock::QwtSystemClock()
00310 {
00311     d_data = new PrivateData;
00312 
00313 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00314     d_data->clock = NULL;
00315     if ( QwtHighResolutionClock::precision() > 0.0 )
00316         d_data->clock = new QwtHighResolutionClock;
00317 #endif
00318 }
00319 
00321 QwtSystemClock::~QwtSystemClock()
00322 {
00323 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00324     delete d_data->clock;
00325 #endif
00326     delete d_data;
00327 }
00328 
00332 bool QwtSystemClock::isNull() const
00333 {
00334 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00335     if ( d_data->clock )
00336         return d_data->clock->isNull();
00337 #endif
00338 
00339     return d_data->time.isNull();
00340 }
00341 
00345 void QwtSystemClock::start()
00346 {
00347 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00348     if ( d_data->clock )
00349     {
00350         d_data->clock->start();
00351         return;
00352     }
00353 #endif
00354 
00355     d_data->time.start();
00356 }
00357 
00362 double QwtSystemClock::restart()
00363 {
00364 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00365     if ( d_data->clock )
00366         return d_data->clock->restart();
00367 #endif
00368 
00369     return d_data->time.restart();
00370 }
00371 
00376 double QwtSystemClock::elapsed() const
00377 {
00378     double elapsed = 0.0;
00379 
00380 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
00381     if ( d_data->clock )
00382     {
00383         if ( !d_data->clock->isNull() )
00384             elapsed = d_data->clock->elapsed();
00385 
00386         return elapsed;
00387     }
00388 #endif
00389 
00390     if ( !d_data->time.isNull() )
00391         elapsed = d_data->time.elapsed();
00392 
00393     return elapsed;
00394 }
00395 
00396 #endif


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:57