1
by brian
clean slate |
1 |
/* Copyright (C) 2004 MySQL AB
|
2 |
||
3 |
This program is free software; you can redistribute it and/or modify
|
|
4 |
it under the terms of the GNU General Public License as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
7 |
This program is distributed in the hope that it will be useful,
|
|
8 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
14 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
15 |
||
16 |
/* get time since epoc in 100 nanosec units */
|
|
17 |
/* thus to get the current time we should use the system function
|
|
18 |
with the highest possible resolution */
|
|
19 |
||
20 |
/*
|
|
21 |
TODO: in functions my_micro_time() and my_micro_time_and_time() there
|
|
22 |
exists some common code that should be merged into a function.
|
|
23 |
*/
|
|
24 |
||
25 |
#include "mysys_priv.h" |
|
26 |
#include "my_static.h" |
|
27 |
||
28 |
ulonglong my_getsystime() |
|
29 |
{
|
|
30 |
#ifdef HAVE_CLOCK_GETTIME
|
|
31 |
struct timespec tp; |
|
32 |
clock_gettime(CLOCK_REALTIME, &tp); |
|
33 |
return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; |
|
34 |
#else
|
|
35 |
/* TODO: check for other possibilities for hi-res timestamping */
|
|
36 |
struct timeval tv; |
|
37 |
gettimeofday(&tv,NULL); |
|
38 |
return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10; |
|
39 |
#endif
|
|
40 |
}
|
|
41 |
||
42 |
||
43 |
/*
|
|
44 |
Return current time
|
|
45 |
||
46 |
SYNOPSIS
|
|
47 |
my_time()
|
|
48 |
flags If MY_WME is set, write error if time call fails
|
|
49 |
||
50 |
*/
|
|
51 |
||
52 |
time_t my_time(myf flags __attribute__((unused))) |
|
53 |
{
|
|
54 |
time_t t; |
|
55 |
#ifdef HAVE_GETHRTIME
|
|
56 |
(void) my_micro_time_and_time(&t); |
|
57 |
return t; |
|
58 |
#else
|
|
59 |
/* The following loop is here beacuse time() may fail on some systems */
|
|
60 |
while ((t= time(0)) == (time_t) -1) |
|
61 |
{
|
|
62 |
if (flags & MY_WME) |
|
63 |
fprintf(stderr, "%s: Warning: time() call failed\n", my_progname); |
|
64 |
}
|
|
65 |
return t; |
|
66 |
#endif
|
|
67 |
}
|
|
68 |
||
69 |
||
70 |
/*
|
|
71 |
Return time in micro seconds
|
|
72 |
||
73 |
SYNOPSIS
|
|
74 |
my_micro_time()
|
|
75 |
||
76 |
NOTES
|
|
77 |
This function is to be used to measure performance in micro seconds.
|
|
78 |
As it's not defined whats the start time for the clock, this function
|
|
79 |
us only useful to measure time between two moments.
|
|
80 |
||
81 |
For windows platforms we need the frequency value of the CUP. This is
|
|
82 |
initalized in my_init.c through QueryPerformanceFrequency().
|
|
83 |
||
84 |
If Windows platform doesn't support QueryPerformanceFrequency() we will
|
|
85 |
obtain the time via GetClockCount, which only supports milliseconds.
|
|
86 |
||
87 |
RETURN
|
|
88 |
Value in microseconds from some undefined point in time
|
|
89 |
*/
|
|
90 |
||
91 |
ulonglong my_micro_time() |
|
92 |
{
|
|
93 |
#if defined(HAVE_GETHRTIME)
|
|
94 |
return gethrtime()/1000; |
|
95 |
#else
|
|
96 |
ulonglong newtime; |
|
97 |
struct timeval t; |
|
98 |
/*
|
|
99 |
The following loop is here because gettimeofday may fail on some systems
|
|
100 |
*/
|
|
101 |
while (gettimeofday(&t, NULL) != 0) |
|
102 |
{}
|
|
103 |
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; |
|
104 |
return newtime; |
|
105 |
#endif /* defined(HAVE_GETHRTIME) */ |
|
106 |
}
|
|
107 |
||
108 |
||
109 |
/*
|
|
110 |
Return time in seconds and timer in microseconds (not different start!)
|
|
111 |
||
112 |
SYNOPSIS
|
|
113 |
my_micro_time_and_time()
|
|
114 |
time_arg Will be set to seconds since epoch (00:00:00 UTC,
|
|
115 |
January 1, 1970)
|
|
116 |
||
117 |
NOTES
|
|
118 |
This function is to be useful when we need both the time and microtime.
|
|
119 |
For example in MySQL this is used to get the query time start of a query
|
|
120 |
and to measure the time of a query (for the slow query log)
|
|
121 |
||
122 |
IMPLEMENTATION
|
|
123 |
Value of time is as in time() call.
|
|
124 |
Value of microtime is same as my_micro_time(), which may be totally
|
|
125 |
unrealated to time()
|
|
126 |
||
127 |
RETURN
|
|
128 |
Value in microseconds from some undefined point in time
|
|
129 |
*/
|
|
130 |
||
131 |
#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */ |
|
132 |
||
133 |
ulonglong my_micro_time_and_time(time_t *time_arg) |
|
134 |
{
|
|
135 |
#if defined(HAVE_GETHRTIME)
|
|
136 |
/*
|
|
137 |
Solaris has a very slow time() call. We optimize this by using the very
|
|
138 |
fast gethrtime() call and only calling time() every 1/2 second
|
|
139 |
*/
|
|
140 |
static hrtime_t prev_gethrtime= 0; |
|
141 |
static time_t cur_time= 0; |
|
142 |
hrtime_t cur_gethrtime; |
|
143 |
||
144 |
pthread_mutex_lock(&THR_LOCK_time); |
|
145 |
cur_gethrtime= gethrtime(); |
|
146 |
if ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS) |
|
147 |
{
|
|
148 |
cur_time= time(0); |
|
149 |
prev_gethrtime= cur_gethrtime; |
|
150 |
}
|
|
151 |
*time_arg= cur_time; |
|
152 |
pthread_mutex_unlock(&THR_LOCK_time); |
|
153 |
return cur_gethrtime/1000; |
|
154 |
#else
|
|
155 |
ulonglong newtime; |
|
156 |
struct timeval t; |
|
157 |
/*
|
|
158 |
The following loop is here because gettimeofday may fail on some systems
|
|
159 |
*/
|
|
160 |
while (gettimeofday(&t, NULL) != 0) |
|
161 |
{}
|
|
162 |
*time_arg= t.tv_sec; |
|
163 |
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; |
|
164 |
return newtime; |
|
165 |
#endif /* defined(HAVE_GETHRTIME) */ |
|
166 |
}
|
|
167 |
||
168 |
||
169 |
/*
|
|
170 |
Returns current time
|
|
171 |
||
172 |
SYNOPSIS
|
|
173 |
my_time_possible_from_micro()
|
|
174 |
microtime Value from very recent my_micro_time()
|
|
175 |
||
176 |
NOTES
|
|
177 |
This function returns the current time. The microtime argument is only used
|
|
178 |
if my_micro_time() uses a function that can safely be converted to the
|
|
179 |
current time.
|
|
180 |
||
181 |
RETURN
|
|
182 |
current time
|
|
183 |
*/
|
|
184 |
||
185 |
time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused))) |
|
186 |
{
|
|
187 |
#if defined(HAVE_GETHRTIME)
|
|
188 |
return my_time(0); /* Cached time */ |
|
189 |
#else
|
|
190 |
return (time_t) (microtime / 1000000); |
|
191 |
#endif /* defined(HAVE_GETHRTIME) */ |
|
192 |
}
|
|
193 |