source: ntrip/trunk/BNC/qwt/qwt_system_clock.cpp @ 8127

Last change on this file since 8127 was 8127, checked in by stoecker, 2 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

File size: 7.9 KB
Line 
1/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997   Josef Wilgen
4 * Copyright (C) 2002   Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_system_clock.h"
11
12#if QT_VERSION >= 0x040800
13#define USE_ELAPSED_TIMER 1
14#endif
15
16#if USE_ELAPSED_TIMER
17
18#include <qelapsedtimer.h>
19
20class QwtSystemClock::PrivateData
21{
22public:
23    QElapsedTimer timer;
24};
25
26QwtSystemClock::QwtSystemClock()
27{
28    d_data = new PrivateData();
29}
30
31QwtSystemClock::~QwtSystemClock()
32{
33    delete d_data;
34}
35   
36bool QwtSystemClock::isNull() const
37{
38    return d_data->timer.isValid();
39}
40       
41void QwtSystemClock::start()
42{
43    d_data->timer.start();
44}
45
46double QwtSystemClock::restart()
47{
48    const qint64 nsecs = d_data->timer.restart();
49    return nsecs / 1e6;
50}
51
52double QwtSystemClock::elapsed() const
53{
54    const qint64 nsecs = d_data->timer.nsecsElapsed();
55    return nsecs / 1e6;
56}
57   
58#else // !USE_ELAPSED_TIMER
59
60#include <qdatetime.h>
61
62#if !defined(Q_OS_WIN)
63#include <unistd.h>
64#endif
65
66#if defined(Q_OS_MAC)
67#include <stdint.h>
68#include <mach/mach_time.h>
69#define QWT_HIGH_RESOLUTION_CLOCK
70#elif defined(_POSIX_TIMERS)
71#include <time.h>
72#define QWT_HIGH_RESOLUTION_CLOCK
73#elif defined(Q_OS_WIN)
74#define QWT_HIGH_RESOLUTION_CLOCK
75#include <qt_windows.h>
76#endif
77
78#if defined(QWT_HIGH_RESOLUTION_CLOCK)
79
80class QwtHighResolutionClock
81{
82public:
83    QwtHighResolutionClock();
84
85    void start();
86    double restart();
87    double elapsed() const;
88
89    bool isNull() const;
90
91    static double precision();
92
93private:
94
95#if defined(Q_OS_MAC)
96    static double msecsTo( uint64_t, uint64_t );
97
98    uint64_t d_timeStamp;
99#elif defined(_POSIX_TIMERS)
100
101    static double msecsTo( const struct timespec &,
102        const struct timespec & );
103
104    static bool isMonotonic();
105
106    struct timespec d_timeStamp;
107    clockid_t d_clockId;
108
109#elif defined(Q_OS_WIN)
110
111    LARGE_INTEGER d_startTicks;
112    LARGE_INTEGER d_ticksPerSecond;
113#endif
114};
115
116#if defined(Q_OS_MAC)
117QwtHighResolutionClock::QwtHighResolutionClock():
118    d_timeStamp( 0 )
119{
120}
121
122double QwtHighResolutionClock::precision()
123{
124    return 1e-6;
125}
126
127void QwtHighResolutionClock::start()
128{
129    d_timeStamp = mach_absolute_time();
130}
131
132double QwtHighResolutionClock::restart()
133{
134    const uint64_t timeStamp = mach_absolute_time();
135    const double elapsed = msecsTo( d_timeStamp, timeStamp );
136    d_timeStamp = timeStamp;
137
138    return elapsed;
139}
140
141double QwtHighResolutionClock::elapsed() const
142{
143    return msecsTo( d_timeStamp, mach_absolute_time() );
144}
145
146bool QwtHighResolutionClock::isNull() const
147{
148    return d_timeStamp == 0;
149}
150
151double QwtHighResolutionClock::msecsTo(
152    uint64_t from, uint64_t to )
153{
154    const uint64_t difference = to - from;
155
156    static double conversion = 0.0;
157    if ( conversion == 0.0 )
158    {
159        mach_timebase_info_data_t info;
160        kern_return_t err = mach_timebase_info( &info );
161
162        // convert the timebase into ms
163        if ( err == 0  )
164            conversion = 1e-6 * ( double ) info.numer / ( double ) info.denom;
165    }
166
167    return conversion * ( double ) difference;
168}
169
170#elif defined(_POSIX_TIMERS)
171
172QwtHighResolutionClock::QwtHighResolutionClock()
173{
174    d_clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME;
175    d_timeStamp.tv_sec = d_timeStamp.tv_nsec = 0;
176}
177
178double QwtHighResolutionClock::precision()
179{
180    struct timespec resolution;
181
182    int clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME;
183    ::clock_getres( clockId, &resolution );
184
185    return resolution.tv_nsec / 1e3;
186}
187
188inline bool QwtHighResolutionClock::isNull() const
189{
190    return d_timeStamp.tv_sec <= 0 && d_timeStamp.tv_nsec <= 0;
191}
192
193inline void QwtHighResolutionClock::start()
194{
195    ::clock_gettime( d_clockId, &d_timeStamp );
196}
197
198double QwtHighResolutionClock::restart()
199{
200    struct timespec timeStamp;
201    ::clock_gettime( d_clockId, &timeStamp );
202
203    const double elapsed = msecsTo( d_timeStamp, timeStamp );
204
205    d_timeStamp = timeStamp;
206    return elapsed;
207}
208
209inline double QwtHighResolutionClock::elapsed() const
210{
211    struct timespec timeStamp;
212    ::clock_gettime( d_clockId, &timeStamp );
213
214    return msecsTo( d_timeStamp, timeStamp );
215}
216
217inline double QwtHighResolutionClock::msecsTo(
218    const struct timespec &t1, const struct timespec &t2 )
219{
220    return ( t2.tv_sec - t1.tv_sec ) * 1e3
221        + ( t2.tv_nsec - t1.tv_nsec ) * 1e-6;
222}
223
224bool QwtHighResolutionClock::isMonotonic()
225{
226    // code copied from qcore_unix.cpp
227
228#if (_POSIX_MONOTONIC_CLOCK-0 > 0)
229    return true;
230#else
231    static int returnValue = 0;
232
233    if ( returnValue == 0 )
234    {
235#if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK)
236        returnValue = -1;
237#elif (_POSIX_MONOTONIC_CLOCK == 0)
238        // detect if the system support monotonic timers
239        const long x = sysconf( _SC_MONOTONIC_CLOCK );
240        returnValue = ( x >= 200112L ) ? 1 : -1;
241#endif
242    }
243
244    return returnValue != -1;
245#endif
246}
247
248#elif defined(Q_OS_WIN)
249
250QwtHighResolutionClock::QwtHighResolutionClock()
251{
252    d_startTicks.QuadPart = 0;
253    QueryPerformanceFrequency( &d_ticksPerSecond );
254}
255
256double QwtHighResolutionClock::precision()
257{
258    LARGE_INTEGER ticks;
259    if ( QueryPerformanceFrequency( &ticks ) && ticks.QuadPart > 0 )
260        return 1e3 / ticks.QuadPart;
261
262    return 0.0;
263}
264
265inline bool QwtHighResolutionClock::isNull() const
266{
267    return d_startTicks.QuadPart <= 0;
268}
269
270inline void QwtHighResolutionClock::start()
271{
272    QueryPerformanceCounter( &d_startTicks );
273}
274
275inline double QwtHighResolutionClock::restart()
276{
277    LARGE_INTEGER ticks;
278    QueryPerformanceCounter( &ticks );
279
280    const double dt = ticks.QuadPart - d_startTicks.QuadPart;
281    d_startTicks = ticks;
282
283    return dt / d_ticksPerSecond.QuadPart * 1e3;
284}
285
286inline double QwtHighResolutionClock::elapsed() const
287{
288    LARGE_INTEGER ticks;
289    QueryPerformanceCounter( &ticks );
290
291    const double dt = ticks.QuadPart - d_startTicks.QuadPart;
292    return dt / d_ticksPerSecond.QuadPart * 1e3;
293}
294
295#endif
296
297#endif // QWT_HIGH_RESOLUTION_CLOCK
298
299class QwtSystemClock::PrivateData
300{
301public:
302#if defined(QWT_HIGH_RESOLUTION_CLOCK)
303    QwtHighResolutionClock *clock;
304#endif
305    QTime time;
306};
307
308//!  Constructs a null clock object.
309QwtSystemClock::QwtSystemClock()
310{
311    d_data = new PrivateData;
312
313#if defined(QWT_HIGH_RESOLUTION_CLOCK)
314    d_data->clock = NULL;
315    if ( QwtHighResolutionClock::precision() > 0.0 )
316        d_data->clock = new QwtHighResolutionClock;
317#endif
318}
319
320//! Destructor
321QwtSystemClock::~QwtSystemClock()
322{
323#if defined(QWT_HIGH_RESOLUTION_CLOCK)
324    delete d_data->clock;
325#endif
326    delete d_data;
327}
328
329/*!
330  \return true if the clock has never been started.
331*/
332bool QwtSystemClock::isNull() const
333{
334#if defined(QWT_HIGH_RESOLUTION_CLOCK)
335    if ( d_data->clock )
336        return d_data->clock->isNull();
337#endif
338
339    return d_data->time.isNull();
340}
341
342/*!
343  Sets the start time to the current time.
344*/
345void QwtSystemClock::start()
346{
347#if defined(QWT_HIGH_RESOLUTION_CLOCK)
348    if ( d_data->clock )
349    {
350        d_data->clock->start();
351        return;
352    }
353#endif
354
355    d_data->time.start();
356}
357
358/*!
359  Set the start time to the current time
360  \return Time, that is elapsed since the previous start time.
361*/
362double QwtSystemClock::restart()
363{
364#if defined(QWT_HIGH_RESOLUTION_CLOCK)
365    if ( d_data->clock )
366        return d_data->clock->restart();
367#endif
368
369    return d_data->time.restart();
370}
371
372/*!
373  \return Number of milliseconds that have elapsed since the last time
374          start() or restart() was called or 0.0 for null clocks.
375*/
376double QwtSystemClock::elapsed() const
377{
378    double elapsed = 0.0;
379
380#if defined(QWT_HIGH_RESOLUTION_CLOCK)
381    if ( d_data->clock )
382    {
383        if ( !d_data->clock->isNull() )
384            elapsed = d_data->clock->elapsed();
385
386        return elapsed;
387    }
388#endif
389
390    if ( !d_data->time.isNull() )
391        elapsed = d_data->time.elapsed();
392
393    return elapsed;
394}
395
396#endif
Note: See TracBrowser for help on using the repository browser.