Home | History | Annotate | Download | only in src
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) 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 
     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   ULONGLONG milliseconds = GetTickCount64();
     45 #else
     46   DWORD milliseconds = GetTickCount();
     47 #endif
     48   now.tv_sec = (long)(milliseconds / 1000);
     49   now.tv_usec = (milliseconds % 1000) * 1000;
     50   return now;
     51 }
     52 
     53 #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
     54 
     55 struct timeval tvnow(void)
     56 {
     57   /*
     58   ** clock_gettime() is granted to be increased monotonically when the
     59   ** monotonic clock is queried. Time starting point is unspecified, it
     60   ** could be the system start-up time, the Epoch, or something else,
     61   ** in any case the time starting point does not change once that the
     62   ** system has started up.
     63   */
     64   struct timeval now;
     65   struct timespec tsnow;
     66   if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
     67     now.tv_sec = tsnow.tv_sec;
     68     now.tv_usec = tsnow.tv_nsec / 1000;
     69   }
     70   /*
     71   ** Even when the configure process has truly detected monotonic clock
     72   ** availability, it might happen that it is not actually available at
     73   ** run-time. When this occurs simply fallback to other time source.
     74   */
     75 #ifdef HAVE_GETTIMEOFDAY
     76   else
     77     (void)gettimeofday(&now, NULL);
     78 #else
     79   else {
     80     now.tv_sec = (long)time(NULL);
     81     now.tv_usec = 0;
     82   }
     83 #endif
     84   return now;
     85 }
     86 
     87 #elif defined(HAVE_GETTIMEOFDAY)
     88 
     89 struct timeval tvnow(void)
     90 {
     91   /*
     92   ** gettimeofday() is not granted to be increased monotonically, due to
     93   ** clock drifting and external source time synchronization it can jump
     94   ** forward or backward in time.
     95   */
     96   struct timeval now;
     97   (void)gettimeofday(&now, NULL);
     98   return now;
     99 }
    100 
    101 #else
    102 
    103 struct timeval tvnow(void)
    104 {
    105   /*
    106   ** time() returns the value of time in seconds since the Epoch.
    107   */
    108   struct timeval now;
    109   now.tv_sec = (long)time(NULL);
    110   now.tv_usec = 0;
    111   return now;
    112 }
    113 
    114 #endif
    115 
    116 /*
    117  * Make sure that the first argument is the more recent time, as otherwise
    118  * we'll get a weird negative time-diff back...
    119  *
    120  * Returns: the time difference in number of milliseconds.
    121  */
    122 long tvdiff(struct timeval newer, struct timeval older)
    123 {
    124   return (long)(newer.tv_sec-older.tv_sec)*1000+
    125     (long)(newer.tv_usec-older.tv_usec)/1000;
    126 }
    127