• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2020, 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 
tutil_tvnow(void)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 
tutil_tvnow(void)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 = (long)time(NULL);
71     now.tv_usec = 0;
72   }
73 #endif
74   return now;
75 }
76 
77 #elif defined(HAVE_GETTIMEOFDAY)
78 
tutil_tvnow(void)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 
tutil_tvnow(void)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 = (long)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  */
tutil_tvdiff(struct timeval newer,struct timeval older)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  */
tutil_tvdiff_secs(struct timeval newer,struct timeval older)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