/src/server/mysys/my_getsystime.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2004, 2011, Oracle and/or its affiliates. |
2 | | Copyright (c) 2009-2011 Monty Program Ab |
3 | | |
4 | | This program is free software; you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation; version 2 of the License. |
7 | | |
8 | | This program is distributed in the hope that it will be useful, |
9 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | | GNU General Public License for more details. |
12 | | |
13 | | You should have received a copy of the GNU General Public License |
14 | | along with this program; if not, write to the Free Software |
15 | | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ |
16 | | |
17 | | |
18 | | #include "mysys_priv.h" |
19 | | #include "my_static.h" |
20 | | |
21 | | #ifdef _WIN32 |
22 | | #define OFFSET_TO_EPOC 116444736000000000LL |
23 | | static ulonglong query_performance_frequency=1; |
24 | | #endif |
25 | | |
26 | | #ifdef HAVE_LINUX_UNISTD_H |
27 | | #include <linux/unistd.h> |
28 | | #endif |
29 | | |
30 | | /* For CYGWIN */ |
31 | | #if !defined(CLOCK_THREAD_CPUTIME_ID) && defined(CLOCK_THREAD_CPUTIME) |
32 | | #define CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME |
33 | | #endif |
34 | | |
35 | | /* |
36 | | return number of nanoseconds since unspecified (but always the same) |
37 | | point in the past |
38 | | |
39 | | NOTE: |
40 | | Thus to get the current time we should use the system function |
41 | | with the highest possible resolution |
42 | | |
43 | | The value is not anchored to any specific point in time (e.g. epoch) nor |
44 | | is it subject to resetting or drifting by way of adjtime() or settimeofday(), |
45 | | and thus it is *NOT* appropriate for getting the current timestamp. It can be |
46 | | used for calculating time intervals, though. |
47 | | */ |
48 | | |
49 | | ulonglong my_interval_timer() |
50 | 0 | { |
51 | 0 | #ifdef HAVE_CLOCK_GETTIME |
52 | 0 | struct timespec tp; |
53 | 0 | clock_gettime(CLOCK_MONOTONIC, &tp); |
54 | 0 | return tp.tv_sec*1000000000ULL+tp.tv_nsec; |
55 | | #elif defined(HAVE_GETHRTIME) |
56 | | return gethrtime(); |
57 | | #elif defined(_WIN32) |
58 | | DBUG_ASSERT(query_performance_frequency); |
59 | | LARGE_INTEGER t_cnt; |
60 | | QueryPerformanceCounter(&t_cnt); |
61 | | return (t_cnt.QuadPart / query_performance_frequency * 1000000000ULL) + |
62 | | ((t_cnt.QuadPart % query_performance_frequency) * 1000000000ULL / |
63 | | query_performance_frequency); |
64 | | #else |
65 | | /* TODO: check for other possibilities for hi-res timestamping */ |
66 | | struct timeval tv; |
67 | | gettimeofday(&tv,NULL); |
68 | | return tv.tv_sec*1000000000ULL+tv.tv_usec*1000ULL; |
69 | | #endif |
70 | 0 | } |
71 | | |
72 | | |
73 | | /* Return current time in HRTIME_RESOLUTION (microseconds) since epoch */ |
74 | | |
75 | | my_hrtime_t my_hrtime() |
76 | 0 | { |
77 | 0 | my_hrtime_t hrtime; |
78 | | #if defined(_WIN32) |
79 | | ulonglong newtime; |
80 | | GetSystemTimePreciseAsFileTime((FILETIME*)&newtime); |
81 | | hrtime.val= (newtime - OFFSET_TO_EPOC)/10; |
82 | | #elif defined(HAVE_CLOCK_GETTIME) |
83 | | struct timespec tp; |
84 | 0 | clock_gettime(CLOCK_REALTIME, &tp); |
85 | 0 | hrtime.val= tp.tv_sec*1000000ULL+tp.tv_nsec/1000ULL; |
86 | | #else |
87 | | struct timeval t; |
88 | | /* The following loop is here because gettimeofday may fail */ |
89 | | while (gettimeofday(&t, NULL) != 0) {} |
90 | | hrtime.val= t.tv_sec*1000000ULL + t.tv_usec; |
91 | | #endif |
92 | 0 | DBUG_EXECUTE_IF("system_time_plus_one_hour", hrtime.val += 3600*1000000ULL;); |
93 | 0 | DBUG_EXECUTE_IF("system_time_minus_one_hour", hrtime.val -= 3600*1000000ULL;); |
94 | 0 | return hrtime; |
95 | 0 | } |
96 | | |
97 | | #ifdef _WIN32 |
98 | | |
99 | | /* |
100 | | Low accuracy, "coarse" timer. |
101 | | Has lower latency than my_hrtime(). Used in situations, where microsecond |
102 | | precision is not needed, e.g in Windows pthread_cond_timedwait, where POSIX |
103 | | interface needs nanoseconds, yet the underlying Windows function only |
104 | | accepts milliseconds. |
105 | | */ |
106 | | my_hrtime_t my_hrtime_coarse() |
107 | | { |
108 | | my_hrtime_t hrtime; |
109 | | ulonglong t; |
110 | | GetSystemTimeAsFileTime((FILETIME*)&t); |
111 | | hrtime.val= (t - OFFSET_TO_EPOC)/10; |
112 | | return hrtime; |
113 | | } |
114 | | |
115 | | #endif |
116 | | |
117 | | void my_time_init() |
118 | 0 | { |
119 | | #ifdef _WIN32 |
120 | | compile_time_assert(sizeof(LARGE_INTEGER) == |
121 | | sizeof(query_performance_frequency)); |
122 | | QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency); |
123 | | DBUG_ASSERT(query_performance_frequency); |
124 | | #endif |
125 | 0 | } |
126 | | |
127 | | |
128 | | /* |
129 | | Return cpu time in 1/10th on a microsecond (1e-7 s) |
130 | | */ |
131 | | |
132 | | ulonglong my_getcputime() |
133 | 0 | { |
134 | 0 | #ifdef CLOCK_THREAD_CPUTIME_ID |
135 | 0 | struct timespec tp; |
136 | 0 | if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)) |
137 | 0 | return 0; |
138 | 0 | return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; |
139 | | #elif defined(__NR_clock_gettime) |
140 | | struct timespec tp; |
141 | | if (syscall(__NR_clock_gettime, CLOCK_THREAD_CPUTIME_ID, &tp)) |
142 | | return 0; |
143 | | return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; |
144 | | #endif /* CLOCK_THREAD_CPUTIME_ID */ |
145 | 0 | return 0; |
146 | 0 | } |