Home | History | Annotate | Download | only in libtest
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2016, 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 "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 = 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 
     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 = (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  */
    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