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