1 | /*************************************************************************** |
2 | * _ _ ____ _ |
3 | * Project ___| | | | _ \| | |
4 | * / __| | | | |_) | | |
5 | * | (__| |_| | _ <| |___ |
6 | * \___|\___/|_| \_\_____| |
7 | * |
8 | * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. |
9 | * |
10 | * This software is licensed as described in the file COPYING, which |
11 | * you should have received as part of this distribution. The terms |
12 | * are also available at https://curl.se/docs/copyright.html. |
13 | * |
14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
15 | * copies of the Software, and permit persons to whom the Software is |
16 | * furnished to do so, under the terms of the COPYING file. |
17 | * |
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
19 | * KIND, either express or implied. |
20 | * |
21 | ***************************************************************************/ |
22 | #include "curl_setup.h" |
23 | #include <curl/curl.h> |
24 | #include "testutil.h" |
25 | #include "memdebug.h" |
26 | |
27 | #if defined(WIN32) && !defined(MSDOS) |
28 | |
29 | struct timeval tutil_tvnow(void) |
30 | { |
31 | /* |
32 | ** GetTickCount() is available on _all_ Windows versions from W95 up |
33 | ** to nowadays. Returns milliseconds elapsed since last system boot, |
34 | ** increases monotonically and wraps once 49.7 days have elapsed. |
35 | */ |
36 | struct timeval now; |
37 | DWORD milliseconds = GetTickCount(); |
38 | now.tv_sec = milliseconds / 1000; |
39 | now.tv_usec = (milliseconds % 1000) * 1000; |
40 | return now; |
41 | } |
42 | |
43 | #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) |
44 | |
45 | struct timeval tutil_tvnow(void) |
46 | { |
47 | /* |
48 | ** clock_gettime() is granted to be increased monotonically when the |
49 | ** monotonic clock is queried. Time starting point is unspecified, it |
50 | ** could be the system start-up time, the Epoch, or something else, |
51 | ** in any case the time starting point does not change once that the |
52 | ** system has started up. |
53 | */ |
54 | struct timeval now; |
55 | struct timespec tsnow; |
56 | if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { |
57 | now.tv_sec = tsnow.tv_sec; |
58 | now.tv_usec = (int)(tsnow.tv_nsec / 1000); |
59 | } |
60 | /* |
61 | ** Even when the configure process has truly detected monotonic clock |
62 | ** availability, it might happen that it is not actually available at |
63 | ** run-time. When this occurs simply fallback to other time source. |
64 | */ |
65 | #ifdef HAVE_GETTIMEOFDAY |
66 | else |
67 | (void)gettimeofday(&now, NULL); |
68 | #else |
69 | else { |
70 | now.tv_sec = time(NULL); |
71 | now.tv_usec = 0; |
72 | } |
73 | #endif |
74 | return now; |
75 | } |
76 | |
77 | #elif defined(HAVE_GETTIMEOFDAY) |
78 | |
79 | struct timeval tutil_tvnow(void) |
80 | { |
81 | /* |
82 | ** gettimeofday() is not granted to be increased monotonically, due to |
83 | ** clock drifting and external source time synchronization it can jump |
84 | ** forward or backward in time. |
85 | */ |
86 | struct timeval now; |
87 | (void)gettimeofday(&now, NULL); |
88 | return now; |
89 | } |
90 | |
91 | #else |
92 | |
93 | struct timeval tutil_tvnow(void) |
94 | { |
95 | /* |
96 | ** time() returns the value of time in seconds since the Epoch. |
97 | */ |
98 | struct timeval now; |
99 | now.tv_sec = time(NULL); |
100 | now.tv_usec = 0; |
101 | return now; |
102 | } |
103 | |
104 | #endif |
105 | |
106 | /* |
107 | * Make sure that the first argument is the more recent time, as otherwise |
108 | * we'll get a weird negative time-diff back... |
109 | * |
110 | * Returns: the time difference in number of milliseconds. |
111 | */ |
112 | long tutil_tvdiff(struct timeval newer, struct timeval older) |
113 | { |
114 | return (long)(newer.tv_sec-older.tv_sec)*1000+ |
115 | (long)(newer.tv_usec-older.tv_usec)/1000; |
116 | } |
117 | |
118 | |
119 | /* |
120 | * Same as tutil_tvdiff but with full usec resolution. |
121 | * |
122 | * Returns: the time difference in seconds with subsecond resolution. |
123 | */ |
124 | double tutil_tvdiff_secs(struct timeval newer, struct timeval older) |
125 | { |
126 | if(newer.tv_sec != older.tv_sec) |
127 | return (double)(newer.tv_sec-older.tv_sec)+ |
128 | (double)(newer.tv_usec-older.tv_usec)/1000000.0; |
129 | return (double)(newer.tv_usec-older.tv_usec)/1000000.0; |
130 | } |
131 | |