xref: /aosp_15_r20/external/curl/lib/timeval.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
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