[libc++] Use __int128_t to represent file_time_type.

Summary:
The ``file_time_type`` time point is used to represent the write times for files.
Its job is to act as part of a C++ wrapper for less ideal system interfaces. The
underlying filesystem uses the ``timespec`` struct for the same purpose.

However, the initial implementation of ``file_time_type`` could not represent
either the range or resolution of ``timespec``, making it unsuitable. Fixing
this requires an implementation which uses more than 64 bits to store the
time point.

I primarily considered two solutions: Using ``__int128_t`` and using a
arithmetic emulation of ``timespec``. Each has its pros and cons, and both
come with more than one complication.

However, after a lot of consideration, I decided on using `__int128_t`. This patch implements that change.

Please see the [FileTimeType Design Document](http://libcxx.llvm.org/docs/DesignDocs/FileTimeType.html) for more information.

Reviewers: mclow.lists, ldionne, joerg, arthur.j.odwyer, EricWF

Reviewed By: EricWF

Subscribers: christof, K-ballo, cfe-commits, BillyONeal

Differential Revision: https://reviews.llvm.org/D49774

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@337960 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2018-07-25 20:51:49 +00:00
parent a1ae56c033
commit 81872e95bf
9 changed files with 759 additions and 404 deletions

View File

@@ -11,27 +11,10 @@
#include "cerrno" // errno
#include "system_error" // __throw_system_error
#include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
#include "include/apple_availability.h"
#if (__APPLE__)
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
#define _LIBCXX_USE_CLOCK_GETTIME
#endif
#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 100000
#define _LIBCXX_USE_CLOCK_GETTIME
#endif
#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 100000
#define _LIBCXX_USE_CLOCK_GETTIME
#endif
#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 30000
#define _LIBCXX_USE_CLOCK_GETTIME
#endif
#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
#else
#define _LIBCXX_USE_CLOCK_GETTIME
#if !defined(__APPLE__)
#define _LIBCPP_USE_CLOCK_GETTIME
#endif // __APPLE__
#if defined(_LIBCPP_WIN32API)
@@ -42,7 +25,7 @@
#include <winapifamily.h>
#endif
#else
#if !defined(CLOCK_REALTIME) || !defined(_LIBCXX_USE_CLOCK_GETTIME)
#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
#include <sys/time.h> // for gettimeofday and timeval
#endif // !defined(CLOCK_REALTIME)
#endif // defined(_LIBCPP_WIN32API)
@@ -92,16 +75,16 @@ system_clock::now() _NOEXCEPT
static_cast<__int64>(ft.dwLowDateTime)};
return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
#else
#if defined(_LIBCXX_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
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));
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
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));
#else
timeval tv;
gettimeofday(&tv, 0);
return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif // _LIBCXX_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif
}
@@ -129,7 +112,7 @@ const bool steady_clock::is_steady;
#if defined(__APPLE__)
// Darwin libc versions >= 1133 provide ns precision via CLOCK_UPTIME_RAW
#if defined(_LIBCXX_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
@@ -191,7 +174,7 @@ steady_clock::now() _NOEXCEPT
static FP fp = init_steady_clock();
return time_point(duration(fp()));
}
#endif // defined(_LIBCXX_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
#endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
#elif defined(_LIBCPP_WIN32API)