Annotation of embedaddon/curl/lib/timeval.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2020, 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:
! 23: #include "timeval.h"
! 24:
! 25: #if defined(WIN32) && !defined(MSDOS)
! 26:
! 27: /* set in win32_init() */
! 28: extern LARGE_INTEGER Curl_freq;
! 29: extern bool Curl_isVistaOrGreater;
! 30:
! 31: /* In case of bug fix this function has a counterpart in tool_util.c */
! 32: struct curltime Curl_now(void)
! 33: {
! 34: struct curltime now;
! 35: if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
! 36: LARGE_INTEGER count;
! 37: QueryPerformanceCounter(&count);
! 38: now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart);
! 39: now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 /
! 40: Curl_freq.QuadPart);
! 41: }
! 42: else {
! 43: /* Disable /analyze warning that GetTickCount64 is preferred */
! 44: #if defined(_MSC_VER)
! 45: #pragma warning(push)
! 46: #pragma warning(disable:28159)
! 47: #endif
! 48: DWORD milliseconds = GetTickCount();
! 49: #if defined(_MSC_VER)
! 50: #pragma warning(pop)
! 51: #endif
! 52:
! 53: now.tv_sec = milliseconds / 1000;
! 54: now.tv_usec = (milliseconds % 1000) * 1000;
! 55: }
! 56: return now;
! 57: }
! 58:
! 59: #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
! 60:
! 61: struct curltime Curl_now(void)
! 62: {
! 63: /*
! 64: ** clock_gettime() is granted to be increased monotonically when the
! 65: ** monotonic clock is queried. Time starting point is unspecified, it
! 66: ** could be the system start-up time, the Epoch, or something else,
! 67: ** in any case the time starting point does not change once that the
! 68: ** system has started up.
! 69: */
! 70: #ifdef HAVE_GETTIMEOFDAY
! 71: struct timeval now;
! 72: #endif
! 73: struct curltime cnow;
! 74: struct timespec tsnow;
! 75:
! 76: /*
! 77: ** clock_gettime() may be defined by Apple's SDK as weak symbol thus
! 78: ** code compiles but fails during run-time if clock_gettime() is
! 79: ** called on unsupported OS version.
! 80: */
! 81: #if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1)
! 82: bool have_clock_gettime = FALSE;
! 83: if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *))
! 84: have_clock_gettime = TRUE;
! 85: #endif
! 86:
! 87: if(
! 88: #if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1)
! 89: have_clock_gettime &&
! 90: #endif
! 91: (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) {
! 92: cnow.tv_sec = tsnow.tv_sec;
! 93: cnow.tv_usec = (unsigned int)(tsnow.tv_nsec / 1000);
! 94: }
! 95: /*
! 96: ** Even when the configure process has truly detected monotonic clock
! 97: ** availability, it might happen that it is not actually available at
! 98: ** run-time. When this occurs simply fallback to other time source.
! 99: */
! 100: #ifdef HAVE_GETTIMEOFDAY
! 101: else {
! 102: (void)gettimeofday(&now, NULL);
! 103: cnow.tv_sec = now.tv_sec;
! 104: cnow.tv_usec = (unsigned int)now.tv_usec;
! 105: }
! 106: #else
! 107: else {
! 108: cnow.tv_sec = time(NULL);
! 109: cnow.tv_usec = 0;
! 110: }
! 111: #endif
! 112: return cnow;
! 113: }
! 114:
! 115: #elif defined(HAVE_MACH_ABSOLUTE_TIME)
! 116:
! 117: #include <stdint.h>
! 118: #include <mach/mach_time.h>
! 119:
! 120: struct curltime Curl_now(void)
! 121: {
! 122: /*
! 123: ** Monotonic timer on Mac OS is provided by mach_absolute_time(), which
! 124: ** returns time in Mach "absolute time units," which are platform-dependent.
! 125: ** To convert to nanoseconds, one must use conversion factors specified by
! 126: ** mach_timebase_info().
! 127: */
! 128: static mach_timebase_info_data_t timebase;
! 129: struct curltime cnow;
! 130: uint64_t usecs;
! 131:
! 132: if(0 == timebase.denom)
! 133: (void) mach_timebase_info(&timebase);
! 134:
! 135: usecs = mach_absolute_time();
! 136: usecs *= timebase.numer;
! 137: usecs /= timebase.denom;
! 138: usecs /= 1000;
! 139:
! 140: cnow.tv_sec = usecs / 1000000;
! 141: cnow.tv_usec = (int)(usecs % 1000000);
! 142:
! 143: return cnow;
! 144: }
! 145:
! 146: #elif defined(HAVE_GETTIMEOFDAY)
! 147:
! 148: struct curltime Curl_now(void)
! 149: {
! 150: /*
! 151: ** gettimeofday() is not granted to be increased monotonically, due to
! 152: ** clock drifting and external source time synchronization it can jump
! 153: ** forward or backward in time.
! 154: */
! 155: struct timeval now;
! 156: struct curltime ret;
! 157: (void)gettimeofday(&now, NULL);
! 158: ret.tv_sec = now.tv_sec;
! 159: ret.tv_usec = (int)now.tv_usec;
! 160: return ret;
! 161: }
! 162:
! 163: #else
! 164:
! 165: struct curltime Curl_now(void)
! 166: {
! 167: /*
! 168: ** time() returns the value of time in seconds since the Epoch.
! 169: */
! 170: struct curltime now;
! 171: now.tv_sec = time(NULL);
! 172: now.tv_usec = 0;
! 173: return now;
! 174: }
! 175:
! 176: #endif
! 177:
! 178: /*
! 179: * Returns: time difference in number of milliseconds. For too large diffs it
! 180: * returns max value.
! 181: *
! 182: * @unittest: 1323
! 183: */
! 184: timediff_t Curl_timediff(struct curltime newer, struct curltime older)
! 185: {
! 186: timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
! 187: if(diff >= (TIMEDIFF_T_MAX/1000))
! 188: return TIMEDIFF_T_MAX;
! 189: else if(diff <= (TIMEDIFF_T_MIN/1000))
! 190: return TIMEDIFF_T_MIN;
! 191: return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
! 192: }
! 193:
! 194: /*
! 195: * Returns: time difference in number of microseconds. For too large diffs it
! 196: * returns max value.
! 197: */
! 198: timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
! 199: {
! 200: timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
! 201: if(diff >= (TIMEDIFF_T_MAX/1000000))
! 202: return TIMEDIFF_T_MAX;
! 203: else if(diff <= (TIMEDIFF_T_MIN/1000000))
! 204: return TIMEDIFF_T_MIN;
! 205: return diff * 1000000 + newer.tv_usec-older.tv_usec;
! 206: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>