38 ** $QT_END_LICENSE$ |
38 ** $QT_END_LICENSE$ |
39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "qcore_unix_p.h" |
42 #include "qcore_unix_p.h" |
|
43 #include "qelapsedtimer.h" |
43 |
44 |
44 #ifndef Q_OS_VXWORKS |
45 #ifndef Q_OS_VXWORKS |
45 # if !defined(Q_OS_HPUX) || defined(__ia64) |
46 # if !defined(Q_OS_HPUX) || defined(__ia64) |
46 # include <sys/select.h> |
47 # include <sys/select.h> |
47 # endif |
48 # endif |
54 |
55 |
55 #ifdef Q_OS_MAC |
56 #ifdef Q_OS_MAC |
56 #include <mach/mach_time.h> |
57 #include <mach/mach_time.h> |
57 #endif |
58 #endif |
58 |
59 |
59 #if !defined(QT_NO_CLOCK_MONOTONIC) |
|
60 # if defined(QT_BOOTSTRAPPED) |
|
61 # define QT_NO_CLOCK_MONOTONIC |
|
62 # endif |
|
63 #endif |
|
64 |
|
65 QT_BEGIN_NAMESPACE |
60 QT_BEGIN_NAMESPACE |
66 |
|
67 bool qt_gettime_is_monotonic() |
|
68 { |
|
69 #if (_POSIX_MONOTONIC_CLOCK-0 > 0) || defined(Q_OS_MAC) |
|
70 return true; |
|
71 #else |
|
72 static int returnValue = 0; |
|
73 |
|
74 if (returnValue == 0) { |
|
75 # if (_POSIX_MONOTONIC_CLOCK-0 < 0) |
|
76 returnValue = -1; |
|
77 # elif (_POSIX_MONOTONIC_CLOCK == 0) |
|
78 // detect if the system support monotonic timers |
|
79 long x = sysconf(_SC_MONOTONIC_CLOCK); |
|
80 returnValue = (x >= 200112L) ? 1 : -1; |
|
81 # endif |
|
82 } |
|
83 |
|
84 return returnValue != -1; |
|
85 #endif |
|
86 } |
|
87 |
|
88 timeval qt_gettime() |
|
89 { |
|
90 timeval tv; |
|
91 #if defined(Q_OS_MAC) |
|
92 static mach_timebase_info_data_t info = {0,0}; |
|
93 if (info.denom == 0) |
|
94 mach_timebase_info(&info); |
|
95 |
|
96 uint64_t cpu_time = mach_absolute_time(); |
|
97 uint64_t nsecs = cpu_time * (info.numer / info.denom); |
|
98 tv.tv_sec = nsecs / 1000000000ull; |
|
99 tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000); |
|
100 return tv; |
|
101 #elif (_POSIX_MONOTONIC_CLOCK-0 > 0) |
|
102 timespec ts; |
|
103 clock_gettime(CLOCK_MONOTONIC, &ts); |
|
104 tv.tv_sec = ts.tv_sec; |
|
105 tv.tv_usec = ts.tv_nsec / 1000; |
|
106 return tv; |
|
107 #else |
|
108 # if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) |
|
109 if (qt_gettime_is_monotonic()) { |
|
110 timespec ts; |
|
111 clock_gettime(CLOCK_MONOTONIC, &ts); |
|
112 tv.tv_sec = ts.tv_sec; |
|
113 tv.tv_usec = ts.tv_nsec / 1000; |
|
114 return tv; |
|
115 } |
|
116 # endif |
|
117 // use gettimeofday |
|
118 ::gettimeofday(&tv, 0); |
|
119 return tv; |
|
120 #endif |
|
121 } |
|
122 |
61 |
123 static inline bool time_update(struct timeval *tv, const struct timeval &start, |
62 static inline bool time_update(struct timeval *tv, const struct timeval &start, |
124 const struct timeval &timeout) |
63 const struct timeval &timeout) |
125 { |
64 { |
126 if (!qt_gettime_is_monotonic()) { |
65 if (!QElapsedTimer::isMonotonic()) { |
127 // we cannot recalculate the timeout without a monotonic clock as the time may have changed |
66 // we cannot recalculate the timeout without a monotonic clock as the time may have changed |
128 return false; |
67 return false; |
129 } |
68 } |
130 |
69 |
131 // clock source is monotonic, so we can recalculate how much timeout is left |
70 // clock source is monotonic, so we can recalculate how much timeout is left |