00001 /*************************************************************************** 00002 * _ _ ____ _ 00003 * Project ___| | | | _ \| | 00004 * / __| | | | |_) | | 00005 * | (__| |_| | _ <| |___ 00006 * \___|\___/|_| \_\_____| 00007 * 00008 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. 00009 * 00010 * This software is licensed as described in the file COPYING, which 00011 * you should have received as part of this distribution. The terms 00012 * are also available at https://curl.haxx.se/docs/copyright.html. 00013 * 00014 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 00015 * copies of the Software, and permit persons to whom the Software is 00016 * furnished to do so, under the terms of the COPYING file. 00017 * 00018 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 00019 * KIND, either express or implied. 00020 * 00021 ***************************************************************************/ 00022 #include "tool_setup.h" 00023 00024 #include "tool_util.h" 00025 00026 #include "memdebug.h" /* keep this as LAST include */ 00027 00028 #if defined(WIN32) && !defined(MSDOS) 00029 00030 struct timeval tool_tvnow(void) 00031 { 00032 /* 00033 ** GetTickCount() is available on _all_ Windows versions from W95 up 00034 ** to nowadays. Returns milliseconds elapsed since last system boot, 00035 ** increases monotonically and wraps once 49.7 days have elapsed. 00036 ** 00037 ** GetTickCount64() is available on Windows version from Windows Vista 00038 ** and Windows Server 2008 up to nowadays. The resolution of the 00039 ** function is limited to the resolution of the system timer, which 00040 ** is typically in the range of 10 milliseconds to 16 milliseconds. 00041 */ 00042 struct timeval now; 00043 #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) 00044 ULONGLONG milliseconds = GetTickCount64(); 00045 #else 00046 DWORD milliseconds = GetTickCount(); 00047 #endif 00048 now.tv_sec = (long)(milliseconds / 1000); 00049 now.tv_usec = (milliseconds % 1000) * 1000; 00050 return now; 00051 } 00052 00053 #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) 00054 00055 struct timeval tool_tvnow(void) 00056 { 00057 /* 00058 ** clock_gettime() is granted to be increased monotonically when the 00059 ** monotonic clock is queried. Time starting point is unspecified, it 00060 ** could be the system start-up time, the Epoch, or something else, 00061 ** in any case the time starting point does not change once that the 00062 ** system has started up. 00063 */ 00064 struct timeval now; 00065 struct timespec tsnow; 00066 if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { 00067 now.tv_sec = tsnow.tv_sec; 00068 now.tv_usec = tsnow.tv_nsec / 1000; 00069 } 00070 /* 00071 ** Even when the configure process has truly detected monotonic clock 00072 ** availability, it might happen that it is not actually available at 00073 ** run-time. When this occurs simply fallback to other time source. 00074 */ 00075 #ifdef HAVE_GETTIMEOFDAY 00076 else 00077 (void)gettimeofday(&now, NULL); 00078 #else 00079 else { 00080 now.tv_sec = (long)time(NULL); 00081 now.tv_usec = 0; 00082 } 00083 #endif 00084 return now; 00085 } 00086 00087 #elif defined(HAVE_GETTIMEOFDAY) 00088 00089 struct timeval tool_tvnow(void) 00090 { 00091 /* 00092 ** gettimeofday() is not granted to be increased monotonically, due to 00093 ** clock drifting and external source time synchronization it can jump 00094 ** forward or backward in time. 00095 */ 00096 struct timeval now; 00097 (void)gettimeofday(&now, NULL); 00098 return now; 00099 } 00100 00101 #else 00102 00103 struct timeval tool_tvnow(void) 00104 { 00105 /* 00106 ** time() returns the value of time in seconds since the Epoch. 00107 */ 00108 struct timeval now; 00109 now.tv_sec = (long)time(NULL); 00110 now.tv_usec = 0; 00111 return now; 00112 } 00113 00114 #endif 00115 00116 /* 00117 * Make sure that the first argument is the more recent time, as otherwise 00118 * we'll get a weird negative time-diff back... 00119 * 00120 * Returns: the time difference in number of milliseconds. 00121 */ 00122 long tool_tvdiff(struct timeval newer, struct timeval older) 00123 { 00124 return (newer.tv_sec-older.tv_sec)*1000+ 00125 (newer.tv_usec-older.tv_usec)/1000; 00126 } 00127 00128 /* 00129 * Same as tool_tvdiff but with full usec resolution. 00130 * 00131 * Returns: the time difference in seconds with subsecond resolution. 00132 */ 00133 double tool_tvdiff_secs(struct timeval newer, struct timeval older) 00134 { 00135 if(newer.tv_sec != older.tv_sec) 00136 return (double)(newer.tv_sec-older.tv_sec)+ 00137 (double)(newer.tv_usec-older.tv_usec)/1000000.0; 00138 else 00139 return (double)(newer.tv_usec-older.tv_usec)/1000000.0; 00140 } 00141 00142 /* return the number of seconds in the given input timeval struct */ 00143 long tool_tvlong(struct timeval t1) 00144 { 00145 return t1.tv_sec; 00146 } 00147