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

Last change on this file since 9093 was 8127, checked in by stoecker, 8 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.