1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "timeval.h"
26*6236dae4SAndroid Build Coastguard Worker
27*6236dae4SAndroid Build Coastguard Worker #if defined(_WIN32)
28*6236dae4SAndroid Build Coastguard Worker
29*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
30*6236dae4SAndroid Build Coastguard Worker #include "system_win32.h"
31*6236dae4SAndroid Build Coastguard Worker
32*6236dae4SAndroid Build Coastguard Worker /* In case of bug fix this function has a counterpart in tool_util.c */
Curl_now(void)33*6236dae4SAndroid Build Coastguard Worker struct curltime Curl_now(void)
34*6236dae4SAndroid Build Coastguard Worker {
35*6236dae4SAndroid Build Coastguard Worker struct curltime now;
36*6236dae4SAndroid Build Coastguard Worker if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
37*6236dae4SAndroid Build Coastguard Worker LARGE_INTEGER count;
38*6236dae4SAndroid Build Coastguard Worker QueryPerformanceCounter(&count);
39*6236dae4SAndroid Build Coastguard Worker now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart);
40*6236dae4SAndroid Build Coastguard Worker now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 /
41*6236dae4SAndroid Build Coastguard Worker Curl_freq.QuadPart);
42*6236dae4SAndroid Build Coastguard Worker }
43*6236dae4SAndroid Build Coastguard Worker else {
44*6236dae4SAndroid Build Coastguard Worker /* Disable /analyze warning that GetTickCount64 is preferred */
45*6236dae4SAndroid Build Coastguard Worker #if defined(_MSC_VER)
46*6236dae4SAndroid Build Coastguard Worker #pragma warning(push)
47*6236dae4SAndroid Build Coastguard Worker #pragma warning(disable:28159)
48*6236dae4SAndroid Build Coastguard Worker #endif
49*6236dae4SAndroid Build Coastguard Worker DWORD milliseconds = GetTickCount();
50*6236dae4SAndroid Build Coastguard Worker #if defined(_MSC_VER)
51*6236dae4SAndroid Build Coastguard Worker #pragma warning(pop)
52*6236dae4SAndroid Build Coastguard Worker #endif
53*6236dae4SAndroid Build Coastguard Worker
54*6236dae4SAndroid Build Coastguard Worker now.tv_sec = (time_t)(milliseconds / 1000);
55*6236dae4SAndroid Build Coastguard Worker now.tv_usec = (int)((milliseconds % 1000) * 1000);
56*6236dae4SAndroid Build Coastguard Worker }
57*6236dae4SAndroid Build Coastguard Worker return now;
58*6236dae4SAndroid Build Coastguard Worker }
59*6236dae4SAndroid Build Coastguard Worker
60*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) || \
61*6236dae4SAndroid Build Coastguard Worker defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
62*6236dae4SAndroid Build Coastguard Worker
Curl_now(void)63*6236dae4SAndroid Build Coastguard Worker struct curltime Curl_now(void)
64*6236dae4SAndroid Build Coastguard Worker {
65*6236dae4SAndroid Build Coastguard Worker /*
66*6236dae4SAndroid Build Coastguard Worker ** clock_gettime() is granted to be increased monotonically when the
67*6236dae4SAndroid Build Coastguard Worker ** monotonic clock is queried. Time starting point is unspecified, it
68*6236dae4SAndroid Build Coastguard Worker ** could be the system start-up time, the Epoch, or something else,
69*6236dae4SAndroid Build Coastguard Worker ** in any case the time starting point does not change once that the
70*6236dae4SAndroid Build Coastguard Worker ** system has started up.
71*6236dae4SAndroid Build Coastguard Worker */
72*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_GETTIMEOFDAY
73*6236dae4SAndroid Build Coastguard Worker struct timeval now;
74*6236dae4SAndroid Build Coastguard Worker #endif
75*6236dae4SAndroid Build Coastguard Worker struct curltime cnow;
76*6236dae4SAndroid Build Coastguard Worker struct timespec tsnow;
77*6236dae4SAndroid Build Coastguard Worker
78*6236dae4SAndroid Build Coastguard Worker /*
79*6236dae4SAndroid Build Coastguard Worker ** clock_gettime() may be defined by Apple's SDK as weak symbol thus
80*6236dae4SAndroid Build Coastguard Worker ** code compiles but fails during runtime if clock_gettime() is
81*6236dae4SAndroid Build Coastguard Worker ** called on unsupported OS version.
82*6236dae4SAndroid Build Coastguard Worker */
83*6236dae4SAndroid Build Coastguard Worker #if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
84*6236dae4SAndroid Build Coastguard Worker (HAVE_BUILTIN_AVAILABLE == 1)
85*6236dae4SAndroid Build Coastguard Worker bool have_clock_gettime = FALSE;
86*6236dae4SAndroid Build Coastguard Worker if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *))
87*6236dae4SAndroid Build Coastguard Worker have_clock_gettime = TRUE;
88*6236dae4SAndroid Build Coastguard Worker #endif
89*6236dae4SAndroid Build Coastguard Worker
90*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_CLOCK_GETTIME_MONOTONIC_RAW
91*6236dae4SAndroid Build Coastguard Worker if(
92*6236dae4SAndroid Build Coastguard Worker #if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
93*6236dae4SAndroid Build Coastguard Worker (HAVE_BUILTIN_AVAILABLE == 1)
94*6236dae4SAndroid Build Coastguard Worker have_clock_gettime &&
95*6236dae4SAndroid Build Coastguard Worker #endif
96*6236dae4SAndroid Build Coastguard Worker (0 == clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow))) {
97*6236dae4SAndroid Build Coastguard Worker cnow.tv_sec = tsnow.tv_sec;
98*6236dae4SAndroid Build Coastguard Worker cnow.tv_usec = (int)(tsnow.tv_nsec / 1000);
99*6236dae4SAndroid Build Coastguard Worker }
100*6236dae4SAndroid Build Coastguard Worker else
101*6236dae4SAndroid Build Coastguard Worker #endif
102*6236dae4SAndroid Build Coastguard Worker
103*6236dae4SAndroid Build Coastguard Worker if(
104*6236dae4SAndroid Build Coastguard Worker #if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
105*6236dae4SAndroid Build Coastguard Worker (HAVE_BUILTIN_AVAILABLE == 1)
106*6236dae4SAndroid Build Coastguard Worker have_clock_gettime &&
107*6236dae4SAndroid Build Coastguard Worker #endif
108*6236dae4SAndroid Build Coastguard Worker (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) {
109*6236dae4SAndroid Build Coastguard Worker cnow.tv_sec = tsnow.tv_sec;
110*6236dae4SAndroid Build Coastguard Worker cnow.tv_usec = (int)(tsnow.tv_nsec / 1000);
111*6236dae4SAndroid Build Coastguard Worker }
112*6236dae4SAndroid Build Coastguard Worker /*
113*6236dae4SAndroid Build Coastguard Worker ** Even when the configure process has truly detected monotonic clock
114*6236dae4SAndroid Build Coastguard Worker ** availability, it might happen that it is not actually available at
115*6236dae4SAndroid Build Coastguard Worker ** runtime. When this occurs simply fallback to other time source.
116*6236dae4SAndroid Build Coastguard Worker */
117*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_GETTIMEOFDAY
118*6236dae4SAndroid Build Coastguard Worker else {
119*6236dae4SAndroid Build Coastguard Worker (void)gettimeofday(&now, NULL);
120*6236dae4SAndroid Build Coastguard Worker cnow.tv_sec = now.tv_sec;
121*6236dae4SAndroid Build Coastguard Worker cnow.tv_usec = (int)now.tv_usec;
122*6236dae4SAndroid Build Coastguard Worker }
123*6236dae4SAndroid Build Coastguard Worker #else
124*6236dae4SAndroid Build Coastguard Worker else {
125*6236dae4SAndroid Build Coastguard Worker cnow.tv_sec = time(NULL);
126*6236dae4SAndroid Build Coastguard Worker cnow.tv_usec = 0;
127*6236dae4SAndroid Build Coastguard Worker }
128*6236dae4SAndroid Build Coastguard Worker #endif
129*6236dae4SAndroid Build Coastguard Worker return cnow;
130*6236dae4SAndroid Build Coastguard Worker }
131*6236dae4SAndroid Build Coastguard Worker
132*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_MACH_ABSOLUTE_TIME)
133*6236dae4SAndroid Build Coastguard Worker
134*6236dae4SAndroid Build Coastguard Worker #include <stdint.h>
135*6236dae4SAndroid Build Coastguard Worker #include <mach/mach_time.h>
136*6236dae4SAndroid Build Coastguard Worker
Curl_now(void)137*6236dae4SAndroid Build Coastguard Worker struct curltime Curl_now(void)
138*6236dae4SAndroid Build Coastguard Worker {
139*6236dae4SAndroid Build Coastguard Worker /*
140*6236dae4SAndroid Build Coastguard Worker ** Monotonic timer on macOS is provided by mach_absolute_time(), which
141*6236dae4SAndroid Build Coastguard Worker ** returns time in Mach "absolute time units," which are platform-dependent.
142*6236dae4SAndroid Build Coastguard Worker ** To convert to nanoseconds, one must use conversion factors specified by
143*6236dae4SAndroid Build Coastguard Worker ** mach_timebase_info().
144*6236dae4SAndroid Build Coastguard Worker */
145*6236dae4SAndroid Build Coastguard Worker static mach_timebase_info_data_t timebase;
146*6236dae4SAndroid Build Coastguard Worker struct curltime cnow;
147*6236dae4SAndroid Build Coastguard Worker uint64_t usecs;
148*6236dae4SAndroid Build Coastguard Worker
149*6236dae4SAndroid Build Coastguard Worker if(0 == timebase.denom)
150*6236dae4SAndroid Build Coastguard Worker (void) mach_timebase_info(&timebase);
151*6236dae4SAndroid Build Coastguard Worker
152*6236dae4SAndroid Build Coastguard Worker usecs = mach_absolute_time();
153*6236dae4SAndroid Build Coastguard Worker usecs *= timebase.numer;
154*6236dae4SAndroid Build Coastguard Worker usecs /= timebase.denom;
155*6236dae4SAndroid Build Coastguard Worker usecs /= 1000;
156*6236dae4SAndroid Build Coastguard Worker
157*6236dae4SAndroid Build Coastguard Worker cnow.tv_sec = usecs / 1000000;
158*6236dae4SAndroid Build Coastguard Worker cnow.tv_usec = (int)(usecs % 1000000);
159*6236dae4SAndroid Build Coastguard Worker
160*6236dae4SAndroid Build Coastguard Worker return cnow;
161*6236dae4SAndroid Build Coastguard Worker }
162*6236dae4SAndroid Build Coastguard Worker
163*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_GETTIMEOFDAY)
164*6236dae4SAndroid Build Coastguard Worker
Curl_now(void)165*6236dae4SAndroid Build Coastguard Worker struct curltime Curl_now(void)
166*6236dae4SAndroid Build Coastguard Worker {
167*6236dae4SAndroid Build Coastguard Worker /*
168*6236dae4SAndroid Build Coastguard Worker ** gettimeofday() is not granted to be increased monotonically, due to
169*6236dae4SAndroid Build Coastguard Worker ** clock drifting and external source time synchronization it can jump
170*6236dae4SAndroid Build Coastguard Worker ** forward or backward in time.
171*6236dae4SAndroid Build Coastguard Worker */
172*6236dae4SAndroid Build Coastguard Worker struct timeval now;
173*6236dae4SAndroid Build Coastguard Worker struct curltime ret;
174*6236dae4SAndroid Build Coastguard Worker (void)gettimeofday(&now, NULL);
175*6236dae4SAndroid Build Coastguard Worker ret.tv_sec = now.tv_sec;
176*6236dae4SAndroid Build Coastguard Worker ret.tv_usec = (int)now.tv_usec;
177*6236dae4SAndroid Build Coastguard Worker return ret;
178*6236dae4SAndroid Build Coastguard Worker }
179*6236dae4SAndroid Build Coastguard Worker
180*6236dae4SAndroid Build Coastguard Worker #else
181*6236dae4SAndroid Build Coastguard Worker
Curl_now(void)182*6236dae4SAndroid Build Coastguard Worker struct curltime Curl_now(void)
183*6236dae4SAndroid Build Coastguard Worker {
184*6236dae4SAndroid Build Coastguard Worker /*
185*6236dae4SAndroid Build Coastguard Worker ** time() returns the value of time in seconds since the Epoch.
186*6236dae4SAndroid Build Coastguard Worker */
187*6236dae4SAndroid Build Coastguard Worker struct curltime now;
188*6236dae4SAndroid Build Coastguard Worker now.tv_sec = time(NULL);
189*6236dae4SAndroid Build Coastguard Worker now.tv_usec = 0;
190*6236dae4SAndroid Build Coastguard Worker return now;
191*6236dae4SAndroid Build Coastguard Worker }
192*6236dae4SAndroid Build Coastguard Worker
193*6236dae4SAndroid Build Coastguard Worker #endif
194*6236dae4SAndroid Build Coastguard Worker
195*6236dae4SAndroid Build Coastguard Worker /*
196*6236dae4SAndroid Build Coastguard Worker * Returns: time difference in number of milliseconds. For too large diffs it
197*6236dae4SAndroid Build Coastguard Worker * returns max value.
198*6236dae4SAndroid Build Coastguard Worker *
199*6236dae4SAndroid Build Coastguard Worker * @unittest: 1323
200*6236dae4SAndroid Build Coastguard Worker */
Curl_timediff(struct curltime newer,struct curltime older)201*6236dae4SAndroid Build Coastguard Worker timediff_t Curl_timediff(struct curltime newer, struct curltime older)
202*6236dae4SAndroid Build Coastguard Worker {
203*6236dae4SAndroid Build Coastguard Worker timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
204*6236dae4SAndroid Build Coastguard Worker if(diff >= (TIMEDIFF_T_MAX/1000))
205*6236dae4SAndroid Build Coastguard Worker return TIMEDIFF_T_MAX;
206*6236dae4SAndroid Build Coastguard Worker else if(diff <= (TIMEDIFF_T_MIN/1000))
207*6236dae4SAndroid Build Coastguard Worker return TIMEDIFF_T_MIN;
208*6236dae4SAndroid Build Coastguard Worker return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
209*6236dae4SAndroid Build Coastguard Worker }
210*6236dae4SAndroid Build Coastguard Worker
211*6236dae4SAndroid Build Coastguard Worker /*
212*6236dae4SAndroid Build Coastguard Worker * Returns: time difference in number of milliseconds, rounded up.
213*6236dae4SAndroid Build Coastguard Worker * For too large diffs it returns max value.
214*6236dae4SAndroid Build Coastguard Worker */
Curl_timediff_ceil(struct curltime newer,struct curltime older)215*6236dae4SAndroid Build Coastguard Worker timediff_t Curl_timediff_ceil(struct curltime newer, struct curltime older)
216*6236dae4SAndroid Build Coastguard Worker {
217*6236dae4SAndroid Build Coastguard Worker timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
218*6236dae4SAndroid Build Coastguard Worker if(diff >= (TIMEDIFF_T_MAX/1000))
219*6236dae4SAndroid Build Coastguard Worker return TIMEDIFF_T_MAX;
220*6236dae4SAndroid Build Coastguard Worker else if(diff <= (TIMEDIFF_T_MIN/1000))
221*6236dae4SAndroid Build Coastguard Worker return TIMEDIFF_T_MIN;
222*6236dae4SAndroid Build Coastguard Worker return diff * 1000 + (newer.tv_usec - older.tv_usec + 999)/1000;
223*6236dae4SAndroid Build Coastguard Worker }
224*6236dae4SAndroid Build Coastguard Worker
225*6236dae4SAndroid Build Coastguard Worker /*
226*6236dae4SAndroid Build Coastguard Worker * Returns: time difference in number of microseconds. For too large diffs it
227*6236dae4SAndroid Build Coastguard Worker * returns max value.
228*6236dae4SAndroid Build Coastguard Worker */
Curl_timediff_us(struct curltime newer,struct curltime older)229*6236dae4SAndroid Build Coastguard Worker timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
230*6236dae4SAndroid Build Coastguard Worker {
231*6236dae4SAndroid Build Coastguard Worker timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
232*6236dae4SAndroid Build Coastguard Worker if(diff >= (TIMEDIFF_T_MAX/1000000))
233*6236dae4SAndroid Build Coastguard Worker return TIMEDIFF_T_MAX;
234*6236dae4SAndroid Build Coastguard Worker else if(diff <= (TIMEDIFF_T_MIN/1000000))
235*6236dae4SAndroid Build Coastguard Worker return TIMEDIFF_T_MIN;
236*6236dae4SAndroid Build Coastguard Worker return diff * 1000000 + newer.tv_usec-older.tv_usec;
237*6236dae4SAndroid Build Coastguard Worker }
238