MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbTick.c
1 /*
2  Copyright (C) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 
20 #include <ndb_global.h>
21 #include <NdbTick.h>
22 
23 #define NANOSEC_PER_SEC 1000000000
24 #define MICROSEC_PER_SEC 1000000
25 #define MILLISEC_PER_SEC 1000
26 #define MICROSEC_PER_MILLISEC 1000
27 #define NANOSEC_PER_MILLISEC 1000000
28 #define NANOSEC_PER_MICROSEC 1000
29 
30 #ifdef HAVE_CLOCK_GETTIME
31 
32 #ifdef CLOCK_MONOTONIC
33 static clockid_t NdbTick_clk_id = CLOCK_MONOTONIC;
34 #else
35 static clockid_t NdbTick_clk_id = CLOCK_REALTIME;
36 #endif
37 
38 void NdbTick_Init(int need_monotonic)
39 {
40  struct timespec tick_time;
41 
42  if (!need_monotonic)
43  NdbTick_clk_id = CLOCK_REALTIME;
44 
45  if (clock_gettime(NdbTick_clk_id, &tick_time) == 0)
46  return;
47 #ifdef CLOCK_MONOTONIC
48  fprintf(stderr, "Failed to use CLOCK_MONOTONIC for clock_realtime,"
49  " errno= %u\n", errno);
50  fflush(stderr);
51  NdbTick_clk_id = CLOCK_REALTIME;
52  if (clock_gettime(NdbTick_clk_id, &tick_time) == 0)
53  return;
54 #endif
55  fprintf(stderr, "Failed to use CLOCK_REALTIME for clock_realtime,"
56  " errno=%u. Aborting\n", errno);
57  fflush(stderr);
58  abort();
59 }
60 
61 NDB_TICKS NdbTick_CurrentMillisecond(void)
62 {
63  struct timespec tick_time;
64  clock_gettime(NdbTick_clk_id, &tick_time);
65 
66  return
67  ((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)MILLISEC_PER_SEC) +
68  ((NDB_TICKS)tick_time.tv_nsec) / ((NDB_TICKS)NANOSEC_PER_MILLISEC);
69 }
70 
71 int
72 NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
73  struct timespec t;
74  int res = clock_gettime(NdbTick_clk_id, &t);
75  * secs = t.tv_sec;
76  * micros = t.tv_nsec / 1000;
77  return res;
78 }
79 
80 NDB_TICKS NdbTick_CurrentNanosecond(void)
81 {
82  struct timespec tick_time;
83  clock_gettime(NdbTick_clk_id, &tick_time);
84 
85  return
86  (((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)NANOSEC_PER_SEC)) +
87  ((NDB_TICKS)tick_time.tv_nsec);
88 }
89 #else
90 void NdbTick_Init(int need_monotonic)
91 {
92 }
93 
94 NDB_TICKS NdbTick_CurrentMillisecond(void)
95 {
96 #ifdef _WIN32
97  NDB_TICKS secs;
98  Uint32 micros;
99  NdbTick_CurrentMicrosecond(&secs, &micros);
100  return secs*1000 + micros/1000;
101 #else
102  struct timeval tick_time;
103  gettimeofday(&tick_time, 0);
104 
105  return
106  ((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)MILLISEC_PER_SEC) +
107  ((NDB_TICKS)tick_time.tv_usec) / ((NDB_TICKS)MICROSEC_PER_MILLISEC);
108 #endif
109 }
110 
111 int
112 NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
113 {
114 #ifdef _WIN32
115  ulonglong time, timemicro, micropart, secpart;
116 
117  GetSystemTimeAsFileTime((FILETIME*)&time);
118  timemicro = time/10;
119 
120  secpart = timemicro/1000000;
121  micropart = timemicro%1000000;
122  assert(micropart <= ULONG_MAX);
123  assert(secpart*1000000+micropart == timemicro);
124 
125  *micros = (Uint32)micropart;
126  *secs = secpart;
127 
128  return 0;
129 #else
130  struct timeval tick_time;
131  int res = gettimeofday(&tick_time, 0);
132 
133  if(secs==0) {
134  NDB_TICKS local_secs = tick_time.tv_sec;
135  *micros = tick_time.tv_usec;
136  *micros = local_secs*1000000+*micros;
137  } else {
138  * secs = tick_time.tv_sec;
139  * micros = tick_time.tv_usec;
140  }
141  return res;
142 #endif
143 }
144 
145 NDB_TICKS NdbTick_CurrentNanosecond(void)
146 {
147 #ifdef _WIN32
148  NDB_TICKS secs;
149  Uint32 micros;
150  NdbTick_CurrentMicrosecond(&secs, &micros);
151  return secs*NANOSEC_PER_SEC + micros*NANOSEC_PER_MICROSEC;
152 #else
153  struct timeval tick_time;
154  gettimeofday(&tick_time, 0);
155 
156  return
157  (((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)NANOSEC_PER_SEC)) +
158  (((NDB_TICKS)tick_time.tv_usec) * ((NDB_TICKS)NANOSEC_PER_MICROSEC));
159 #endif
160 }
161 
162 #endif
163 
164 int
165 NdbTick_getMicroTimer(struct MicroSecondTimer* input_timer)
166 {
167  NDB_TICKS secs;
168  Uint32 mics;
169  int ret_value;
170  ret_value = NdbTick_CurrentMicrosecond(&secs, &mics);
171  input_timer->seconds = secs;
172  input_timer->micro_seconds = (NDB_TICKS)mics;
173  return ret_value;
174 }
175 
176 NDB_TICKS
177 NdbTick_getMicrosPassed(struct MicroSecondTimer start,
178  struct MicroSecondTimer stop)
179 {
180  NDB_TICKS ret_value = (NDB_TICKS)0;
181  if (start.seconds < stop.seconds) {
182  NDB_TICKS sec_passed = stop.seconds - start.seconds;
183  ret_value = ((NDB_TICKS)MICROSEC_PER_SEC) * sec_passed;
184  } else if (start.seconds > stop.seconds) {
185  return ret_value;
186  }
187  if (start.micro_seconds < stop.micro_seconds) {
188  ret_value += (stop.micro_seconds - start.micro_seconds);
189  } else if (ret_value != (NDB_TICKS)0) {
190  ret_value -= (start.micro_seconds - stop.micro_seconds);
191  }
192  return ret_value;
193 }