llvm.org GIT mirror llvm / 802db56
[Support/FileSystem] Add sub-second precision for atime/mtime of sys::fs::file_status on unix platforms Summary: getLastAccessedTime() and getLastModificationTime() provided times in nanoseconds but with only 1 second resolution, even when the underlying file system could provide more precise times than that. These changes add sub-second precision for unix platforms that support improved precision. Also add some comments to make sure people are aware that the resolution of times can vary across different file systems. Reviewers: labath, zturner, aaron.ballman, kristina Reviewed By: aaron.ballman, kristina Subscribers: lebedev.ri, mgorny, kristina, llvm-commits Differential Revision: https://reviews.llvm.org/D54826 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@347530 91177308-0d34-0410-b5e6-96231b3b80d8 Argyrios Kyrtzidis 10 months ago
5 changed file(s) with 61 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
66 include(CheckLibraryExists)
77 include(CheckSymbolExists)
88 include(CheckFunctionExists)
9 include(CheckStructHasMember)
910 include(CheckCCompilerFlag)
1011
1112 include(CheckCompilerVersion)
246247 list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES dl)
247248 endif()
248249 endif()
250
251 CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec
252 "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
253 CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec
254 "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
249255
250256 check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)
251257 if( LLVM_USING_GLIBC )
207207 /* Define to 1 if you have the header file. */
208208 #cmakedefine HAVE_SYS_TIME_H ${HAVE_SYS_TIME_H}
209209
210 /* Define to 1 if stat struct has st_mtimespec member .*/
211 #cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC ${HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC}
212
213 /* Define to 1 if stat struct has st_mtim member. */
214 #cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC ${HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC}
215
210216 /* Define to 1 if you have the header file. */
211217 #cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
212218
4444 toTimePoint(std::time_t T) {
4545 using namespace std::chrono;
4646 return time_point_cast(system_clock::from_time_t(T));
47 }
48
49 /// Convert a std::time_t + nanoseconds to a TimePoint
50 LLVM_ATTRIBUTE_ALWAYS_INLINE inline TimePoint<>
51 toTimePoint(std::time_t T, uint32_t nsec) {
52 using namespace std::chrono;
53 return time_point_cast(system_clock::from_time_t(T))
54 + nanoseconds(nsec);
4755 }
4856
4957 } // namespace sys
159159 #if defined(LLVM_ON_UNIX)
160160 time_t fs_st_atime = 0;
161161 time_t fs_st_mtime = 0;
162 uint32_t fs_st_atime_nsec = 0;
163 uint32_t fs_st_mtime_nsec = 0;
162164 uid_t fs_st_uid = 0;
163165 gid_t fs_st_gid = 0;
164166 off_t fs_st_size = 0;
179181 explicit basic_file_status(file_type Type) : Type(Type) {}
180182
181183 #if defined(LLVM_ON_UNIX)
182 basic_file_status(file_type Type, perms Perms, time_t ATime, time_t MTime,
184 basic_file_status(file_type Type, perms Perms, time_t ATime,
185 uint32_t ATimeNSec, time_t MTime, uint32_t MTimeNSec,
183186 uid_t UID, gid_t GID, off_t Size)
184 : fs_st_atime(ATime), fs_st_mtime(MTime), fs_st_uid(UID), fs_st_gid(GID),
187 : fs_st_atime(ATime), fs_st_mtime(MTime),
188 fs_st_atime_nsec(ATimeNSec), fs_st_mtime_nsec(MTimeNSec),
189 fs_st_uid(UID), fs_st_gid(GID),
185190 fs_st_size(Size), Type(Type), Perms(Perms) {}
186191 #elif defined(_WIN32)
187192 basic_file_status(file_type Type, perms Perms, uint32_t LastAccessTimeHigh,
198203 // getters
199204 file_type type() const { return Type; }
200205 perms permissions() const { return Perms; }
206
207 /// The file access time as reported from the underlying file system.
208 ///
209 /// Also see comments on \c getLastModificationTime() related to the precision
210 /// of the returned value.
201211 TimePoint<> getLastAccessedTime() const;
212
213 /// The file modification time as reported from the underlying file system.
214 ///
215 /// The returned value allows for nanosecond precision but the actual
216 /// resolution is an implementation detail of the underlying file system.
217 /// There is no guarantee for what kind of resolution you can expect, the
218 /// resolution can differ across platforms and even across mountpoints on the
219 /// same machine.
202220 TimePoint<> getLastModificationTime() const;
203221
204222 #if defined(LLVM_ON_UNIX)
246264
247265 #if defined(LLVM_ON_UNIX)
248266 file_status(file_type Type, perms Perms, dev_t Dev, nlink_t Links, ino_t Ino,
249 time_t ATime, time_t MTime, uid_t UID, gid_t GID, off_t Size)
250 : basic_file_status(Type, Perms, ATime, MTime, UID, GID, Size),
267 time_t ATime, uint32_t ATimeNSec,
268 time_t MTime, uint32_t MTimeNSec,
269 uid_t UID, gid_t GID, off_t Size)
270 : basic_file_status(Type, Perms, ATime, ATimeNSec, MTime, MTimeNSec,
271 UID, GID, Size),
251272 fs_st_dev(Dev), fs_st_nlinks(Links), fs_st_ino(Ino) {}
252273 #elif defined(_WIN32)
253274 file_status(file_type Type, perms Perms, uint32_t LinkCount,
228228 }
229229
230230 TimePoint<> basic_file_status::getLastAccessedTime() const {
231 return toTimePoint(fs_st_atime);
231 return toTimePoint(fs_st_atime, fs_st_atime_nsec);
232232 }
233233
234234 TimePoint<> basic_file_status::getLastModificationTime() const {
235 return toTimePoint(fs_st_mtime);
235 return toTimePoint(fs_st_mtime, fs_st_mtime_nsec);
236236 }
237237
238238 UniqueID file_status::getUniqueID() const {
590590 return EC;
591591 }
592592
593 uint32_t atime_nsec, mtime_nsec;
594 #if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
595 atime_nsec = Status.st_atimespec.tv_nsec;
596 mtime_nsec = Status.st_mtimespec.tv_nsec;
597 #elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
598 atime_nsec = Status.st_atim.tv_nsec;
599 mtime_nsec = Status.st_mtim.tv_nsec;
600 #else
601 atime_nsec = mtime_nsec = 0;
602 #endif
603
593604 perms Perms = static_cast(Status.st_mode) & all_perms;
594605 Result = file_status(typeForMode(Status.st_mode), Perms, Status.st_dev,
595 Status.st_nlink, Status.st_ino, Status.st_atime,
596 Status.st_mtime, Status.st_uid, Status.st_gid,
597 Status.st_size);
606 Status.st_nlink, Status.st_ino,
607 Status.st_atime, atime_nsec, Status.st_mtime, mtime_nsec,
608 Status.st_uid, Status.st_gid, Status.st_size);
598609
599610 return std::error_code();
600611 }