blob: abd43cb475617e5284042b9b2ab36cc3d2fd4e8c [file] [log] [blame]
#include "absl/time/clock.h"
#include <sys/time.h>
#include <ctime>
#include <cstdint>
#include "absl/base/internal/raw_logging.h"
// These are not defined in the Xcode 7.3.1 SDK Headers.
// Once we are no longer supporting Xcode 7.3.1 we can
// remove these.
#ifndef __WATCHOS_3_0
#define __WATCHOS_3_0 30000
#endif
#ifndef __TVOS_10_0
#define __TVOS_10_0 100000
#endif
#ifndef __IPHONE_10_0
#define __IPHONE_10_0 100000
#endif
#ifndef __MAC_10_12
#define __MAC_10_12 101200
#endif
namespace absl {
inline namespace lts_2018_06_20 {
namespace time_internal {
static int64_t GetCurrentTimeNanosFromSystem() {
#if (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_12) || \
(__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0) || \
(__WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0) || \
(__TV_OS_VERSION_MAX_ALLOWED >= __TVOS_10_0)
// clock_gettime_nsec_np is not defined on SDKs before Xcode 8.0.
// This preprocessor logic is based upon __CLOCK_AVAILABILITY in
// usr/include/time.h. Once we are no longer supporting Xcode 7.3.1 we can
// remove this #if.
// We must continue to check if it is defined until we are sure that ALL the
// platforms we are shipping on support it.
// clock_gettime_nsec_np is preferred because it may give higher accuracy than
// gettimeofday in future Apple operating systems.
// Currently (macOS 10.12/iOS 10.2) clock_gettime_nsec_np accuracy is
// microsecond accuracy (i.e. equivalent to gettimeofday).
if (&clock_gettime_nsec_np != nullptr) {
return clock_gettime_nsec_np(CLOCK_REALTIME);
}
#endif
#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
(__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12)) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
(__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)) || \
(defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
(__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0)) || \
(defined(__TV_OS_VERSION_MIN_REQUIRED) && \
(__TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0))
// We need this block in 2 different cases:
// a) where we are compiling with Xcode 7 in which case the block above
// will not be compiled in, and this is the only block executed.
// b) where we are compiling with Xcode 8+ but supporting operating systems
// that do not define clock_gettime_nsec_np, so this is in effect
// an else block to the block above.
// This block will not be compiled if the min supported version is
// guaranteed to supply clock_gettime_nsec_np.
//
// Once we know that clock_gettime_nsec_np is in the SDK *AND* exists on
// all the platforms we support, we can remove both this block and alter the
// block above to just call clock_gettime_nsec_np directly.
const int64_t kNanosPerSecond = 1000 * 1000 * 1000;
const int64_t kNanosPerMicrosecond = 1000;
struct timeval tp;
ABSL_RAW_CHECK(gettimeofday(&tp, nullptr) == 0, "Failed gettimeofday");
return (int64_t{tp.tv_sec} * kNanosPerSecond +
int64_t{tp.tv_usec} * kNanosPerMicrosecond);
#endif
}
} // namespace time_internal
} // inline namespace lts_2018_06_20
} // namespace absl