aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Merger <noreply-android-build-merger@google.com>2018-11-26 00:12:40 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-11-26 00:12:40 +0000
commit282de28131bb6ce6c22635850bc73725b4df50a8 (patch)
tree18b7a7afd8254984f1af06c896442d437e9e3903
parentb94b2e5db25c2d1d5c61c0bff9dbf5ed5bdb619b (diff)
parent03d93962486391815cfec496214e4d4d1b96e11f (diff)
downloadllvm-lldb-master-dev.tar.gz
Merge "[Support/FileSystem] Add sub-second precision for atime/mtime of sys::fs::file_status on unix platforms am: 802db564f9" into lldb-master-devlldb-master-dev
-rw-r--r--cmake/config-ix.cmake6
-rw-r--r--include/llvm/Config/config.h.cmake6
-rw-r--r--include/llvm/Support/Chrono.h8
-rw-r--r--include/llvm/Support/FileSystem.h29
-rw-r--r--lib/Support/Unix/Path.inc21
5 files changed, 61 insertions, 9 deletions
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 4bf2a9e91126..900c35ee4f0c 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -7,6 +7,7 @@ include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckFunctionExists)
+include(CheckStructHasMember)
include(CheckCCompilerFlag)
include(CheckCompilerVersion)
@@ -248,6 +249,11 @@ if( HAVE_DLFCN_H )
endif()
endif()
+CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+
check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)
if( LLVM_USING_GLIBC )
add_definitions( -D_GNU_SOURCE )
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index aece421b77d2..03bbd74d6d32 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -208,6 +208,12 @@
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H ${HAVE_SYS_TIME_H}
+/* Define to 1 if stat struct has st_mtimespec member .*/
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC ${HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC}
+
+/* Define to 1 if stat struct has st_mtim member. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC ${HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC}
+
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
diff --git a/include/llvm/Support/Chrono.h b/include/llvm/Support/Chrono.h
index 994068af3771..57677e8d5cf1 100644
--- a/include/llvm/Support/Chrono.h
+++ b/include/llvm/Support/Chrono.h
@@ -47,6 +47,14 @@ toTimePoint(std::time_t T) {
return time_point_cast<seconds>(system_clock::from_time_t(T));
}
+/// Convert a std::time_t + nanoseconds to a TimePoint
+LLVM_ATTRIBUTE_ALWAYS_INLINE inline TimePoint<>
+toTimePoint(std::time_t T, uint32_t nsec) {
+ using namespace std::chrono;
+ return time_point_cast<nanoseconds>(system_clock::from_time_t(T))
+ + nanoseconds(nsec);
+}
+
} // namespace sys
raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 5ad39c8054f0..827e2e91eea2 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -160,6 +160,8 @@ protected:
#if defined(LLVM_ON_UNIX)
time_t fs_st_atime = 0;
time_t fs_st_mtime = 0;
+ uint32_t fs_st_atime_nsec = 0;
+ uint32_t fs_st_mtime_nsec = 0;
uid_t fs_st_uid = 0;
gid_t fs_st_gid = 0;
off_t fs_st_size = 0;
@@ -180,9 +182,12 @@ public:
explicit basic_file_status(file_type Type) : Type(Type) {}
#if defined(LLVM_ON_UNIX)
- basic_file_status(file_type Type, perms Perms, time_t ATime, time_t MTime,
+ basic_file_status(file_type Type, perms Perms, time_t ATime,
+ uint32_t ATimeNSec, time_t MTime, uint32_t MTimeNSec,
uid_t UID, gid_t GID, off_t Size)
- : fs_st_atime(ATime), fs_st_mtime(MTime), fs_st_uid(UID), fs_st_gid(GID),
+ : fs_st_atime(ATime), fs_st_mtime(MTime),
+ fs_st_atime_nsec(ATimeNSec), fs_st_mtime_nsec(MTimeNSec),
+ fs_st_uid(UID), fs_st_gid(GID),
fs_st_size(Size), Type(Type), Perms(Perms) {}
#elif defined(_WIN32)
basic_file_status(file_type Type, perms Perms, uint32_t LastAccessTimeHigh,
@@ -199,7 +204,20 @@ public:
// getters
file_type type() const { return Type; }
perms permissions() const { return Perms; }
+
+ /// The file access time as reported from the underlying file system.
+ ///
+ /// Also see comments on \c getLastModificationTime() related to the precision
+ /// of the returned value.
TimePoint<> getLastAccessedTime() const;
+
+ /// The file modification time as reported from the underlying file system.
+ ///
+ /// The returned value allows for nanosecond precision but the actual
+ /// resolution is an implementation detail of the underlying file system.
+ /// There is no guarantee for what kind of resolution you can expect, the
+ /// resolution can differ across platforms and even across mountpoints on the
+ /// same machine.
TimePoint<> getLastModificationTime() const;
#if defined(LLVM_ON_UNIX)
@@ -247,8 +265,11 @@ public:
#if defined(LLVM_ON_UNIX)
file_status(file_type Type, perms Perms, dev_t Dev, nlink_t Links, ino_t Ino,
- time_t ATime, time_t MTime, uid_t UID, gid_t GID, off_t Size)
- : basic_file_status(Type, Perms, ATime, MTime, UID, GID, Size),
+ time_t ATime, uint32_t ATimeNSec,
+ time_t MTime, uint32_t MTimeNSec,
+ uid_t UID, gid_t GID, off_t Size)
+ : basic_file_status(Type, Perms, ATime, ATimeNSec, MTime, MTimeNSec,
+ UID, GID, Size),
fs_st_dev(Dev), fs_st_nlinks(Links), fs_st_ino(Ino) {}
#elif defined(_WIN32)
file_status(file_type Type, perms Perms, uint32_t LinkCount,
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index 915496067099..d130b33f840e 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -229,11 +229,11 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
}
TimePoint<> basic_file_status::getLastAccessedTime() const {
- return toTimePoint(fs_st_atime);
+ return toTimePoint(fs_st_atime, fs_st_atime_nsec);
}
TimePoint<> basic_file_status::getLastModificationTime() const {
- return toTimePoint(fs_st_mtime);
+ return toTimePoint(fs_st_mtime, fs_st_mtime_nsec);
}
UniqueID file_status::getUniqueID() const {
@@ -591,11 +591,22 @@ static std::error_code fillStatus(int StatRet, const struct stat &Status,
return EC;
}
+ uint32_t atime_nsec, mtime_nsec;
+#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+ atime_nsec = Status.st_atimespec.tv_nsec;
+ mtime_nsec = Status.st_mtimespec.tv_nsec;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ atime_nsec = Status.st_atim.tv_nsec;
+ mtime_nsec = Status.st_mtim.tv_nsec;
+#else
+ atime_nsec = mtime_nsec = 0;
+#endif
+
perms Perms = static_cast<perms>(Status.st_mode) & all_perms;
Result = file_status(typeForMode(Status.st_mode), Perms, Status.st_dev,
- Status.st_nlink, Status.st_ino, Status.st_atime,
- Status.st_mtime, Status.st_uid, Status.st_gid,
- Status.st_size);
+ Status.st_nlink, Status.st_ino,
+ Status.st_atime, atime_nsec, Status.st_mtime, mtime_nsec,
+ Status.st_uid, Status.st_gid, Status.st_size);
return std::error_code();
}