[libc++] NFCI: Refactor chrono.cpp to make it easier to support new platforms
Also simplify a few conditionals along the way for readability.
This commit is contained in:
parent
45e0f65162
commit
2dec36e532
|
@ -42,14 +42,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
namespace chrono
|
||||
{
|
||||
|
||||
//
|
||||
// system_clock
|
||||
//
|
||||
|
||||
const bool system_clock::is_steady;
|
||||
|
||||
system_clock::time_point
|
||||
system_clock::now() _NOEXCEPT
|
||||
{
|
||||
#if defined(_LIBCPP_WIN32API)
|
||||
|
||||
static system_clock::time_point __libcpp_system_clock_now() {
|
||||
// FILETIME is in 100ns units
|
||||
using filetime_duration =
|
||||
_VSTD::chrono::duration<__int64,
|
||||
|
@ -60,31 +59,42 @@ system_clock::now() _NOEXCEPT
|
|||
static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600};
|
||||
|
||||
FILETIME ft;
|
||||
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
GetSystemTimePreciseAsFileTime(&ft);
|
||||
#else
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
#endif
|
||||
#else
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
#endif
|
||||
|
||||
filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) |
|
||||
static_cast<__int64>(ft.dwLowDateTime)};
|
||||
return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
|
||||
#else
|
||||
#if defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME)
|
||||
return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
|
||||
}
|
||||
|
||||
#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME)
|
||||
|
||||
static system_clock::time_point __libcpp_system_clock_now() {
|
||||
struct timespec tp;
|
||||
if (0 != clock_gettime(CLOCK_REALTIME, &tp))
|
||||
__throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
|
||||
return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
|
||||
return system_clock::time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static system_clock::time_point __libcpp_system_clock_now() {
|
||||
timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
|
||||
#endif
|
||||
return system_clock::time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const bool system_clock::is_steady;
|
||||
|
||||
system_clock::time_point
|
||||
system_clock::now() _NOEXCEPT
|
||||
{
|
||||
return __libcpp_system_clock_now();
|
||||
}
|
||||
|
||||
time_t
|
||||
|
@ -99,33 +109,28 @@ system_clock::from_time_t(time_t t) _NOEXCEPT
|
|||
return system_clock::time_point(seconds(t));
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
|
||||
//
|
||||
// steady_clock
|
||||
//
|
||||
// Warning: If this is not truly steady, then it is non-conforming. It is
|
||||
// better for it to not exist and have the rest of libc++ use system_clock
|
||||
// instead.
|
||||
//
|
||||
|
||||
const bool steady_clock::is_steady;
|
||||
#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#if !defined(CLOCK_MONOTONIC_RAW)
|
||||
# error "Building libc++ on Apple platforms requires CLOCK_MONOTONIC_RAW"
|
||||
#endif
|
||||
|
||||
// On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
|
||||
// mach_absolute_time are able to time functions in the nanosecond range.
|
||||
// Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
|
||||
// also counts cycles when the system is asleep. Thus, it is the only
|
||||
// acceptable implementation of steady_clock.
|
||||
steady_clock::time_point
|
||||
steady_clock::now() _NOEXCEPT
|
||||
{
|
||||
static steady_clock::time_point __libcpp_steady_clock_now() {
|
||||
struct timespec tp;
|
||||
if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp))
|
||||
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC_RAW) failed");
|
||||
return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
|
||||
return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
|
||||
}
|
||||
|
||||
#elif defined(_LIBCPP_WIN32API)
|
||||
|
@ -138,36 +143,40 @@ steady_clock::now() _NOEXCEPT
|
|||
static LARGE_INTEGER
|
||||
__QueryPerformanceFrequency()
|
||||
{
|
||||
LARGE_INTEGER val;
|
||||
(void) QueryPerformanceFrequency(&val);
|
||||
return val;
|
||||
LARGE_INTEGER val;
|
||||
(void) QueryPerformanceFrequency(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
steady_clock::time_point
|
||||
steady_clock::now() _NOEXCEPT
|
||||
{
|
||||
static steady_clock::time_point __libcpp_steady_clock_now() {
|
||||
static const LARGE_INTEGER freq = __QueryPerformanceFrequency();
|
||||
|
||||
LARGE_INTEGER counter;
|
||||
(void) QueryPerformanceCounter(&counter);
|
||||
return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
|
||||
return steady_clock::time_point(steady_clock::duration(counter.QuadPart * nano::den / freq.QuadPart));
|
||||
}
|
||||
|
||||
#elif defined(CLOCK_MONOTONIC)
|
||||
|
||||
steady_clock::time_point
|
||||
steady_clock::now() _NOEXCEPT
|
||||
{
|
||||
static steady_clock::time_point __libcpp_steady_clock_now() {
|
||||
struct timespec tp;
|
||||
if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
|
||||
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
|
||||
return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
|
||||
return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
|
||||
}
|
||||
|
||||
#else
|
||||
# error "Monotonic clock not implemented"
|
||||
# error "Monotonic clock not implemented on this platform"
|
||||
#endif
|
||||
|
||||
const bool steady_clock::is_steady;
|
||||
|
||||
steady_clock::time_point
|
||||
steady_clock::now() _NOEXCEPT
|
||||
{
|
||||
return __libcpp_steady_clock_now();
|
||||
}
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue