• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, 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.haxx.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 "tool_setup.h"
23 
24 #include "tool_util.h"
25 
26 #include "memdebug.h" /* keep this as LAST include */
27 
28 #if defined(WIN32) && !defined(MSDOS)
29 
tvnow(void)30 struct timeval tvnow(void)
31 {
32   /*
33   ** GetTickCount() is available on _all_ Windows versions from W95 up
34   ** to nowadays. Returns milliseconds elapsed since last system boot,
35   ** increases monotonically and wraps once 49.7 days have elapsed.
36   **
37   ** GetTickCount64() is available on Windows version from Windows Vista
38   ** and Windows Server 2008 up to nowadays. The resolution of the
39   ** function is limited to the resolution of the system timer, which
40   ** is typically in the range of 10 milliseconds to 16 milliseconds.
41   */
42   struct timeval now;
43 #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) && \
44     (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
45   ULONGLONG milliseconds = GetTickCount64();
46 #else
47   DWORD milliseconds = GetTickCount();
48 #endif
49   now.tv_sec = (long)(milliseconds / 1000);
50   now.tv_usec = (long)((milliseconds % 1000) * 1000);
51   return now;
52 }
53 
54 #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
55 
tvnow(void)56 struct timeval tvnow(void)
57 {
58   /*
59   ** clock_gettime() is granted to be increased monotonically when the
60   ** monotonic clock is queried. Time starting point is unspecified, it
61   ** could be the system start-up time, the Epoch, or something else,
62   ** in any case the time starting point does not change once that the
63   ** system has started up.
64   */
65   struct timeval now;
66   struct timespec tsnow;
67   if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
68     now.tv_sec = tsnow.tv_sec;
69     now.tv_usec = tsnow.tv_nsec / 1000;
70   }
71   /*
72   ** Even when the configure process has truly detected monotonic clock
73   ** availability, it might happen that it is not actually available at
74   ** run-time. When this occurs simply fallback to other time source.
75   */
76 #ifdef HAVE_GETTIMEOFDAY
77   else
78     (void)gettimeofday(&now, NULL);
79 #else
80   else {
81     now.tv_sec = (long)time(NULL);
82     now.tv_usec = 0;
83   }
84 #endif
85   return now;
86 }
87 
88 #elif defined(HAVE_GETTIMEOFDAY)
89 
tvnow(void)90 struct timeval tvnow(void)
91 {
92   /*
93   ** gettimeofday() is not granted to be increased monotonically, due to
94   ** clock drifting and external source time synchronization it can jump
95   ** forward or backward in time.
96   */
97   struct timeval now;
98   (void)gettimeofday(&now, NULL);
99   return now;
100 }
101 
102 #else
103 
tvnow(void)104 struct timeval tvnow(void)
105 {
106   /*
107   ** time() returns the value of time in seconds since the Epoch.
108   */
109   struct timeval now;
110   now.tv_sec = (long)time(NULL);
111   now.tv_usec = 0;
112   return now;
113 }
114 
115 #endif
116 
117 /*
118  * Make sure that the first argument is the more recent time, as otherwise
119  * we'll get a weird negative time-diff back...
120  *
121  * Returns: the time difference in number of milliseconds.
122  */
tvdiff(struct timeval newer,struct timeval older)123 long tvdiff(struct timeval newer, struct timeval older)
124 {
125   return (long)(newer.tv_sec-older.tv_sec)*1000+
126     (long)(newer.tv_usec-older.tv_usec)/1000;
127 }
128