llvm.org GIT mirror llvm / 2864c2a
Remove TimeValue usage from llvm/Support Summary: This is a follow-up to D25416. It removes all usages of TimeValue from llvm/Support library (except for the actual TimeValue declaration), and replaces them with appropriate usages of std::chrono. To facilitate this, I have added small utility functions for converting time points and durations into appropriate OS-specific types (FILETIME, struct timespec, ...). Reviewers: zturner, mehdi_amini Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D25730 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284966 91177308-0d34-0410-b5e6-96231b3b80d8 Pavel Labath 3 years ago
15 changed file(s) with 155 addition(s) and 118 deletion(s). Raw diff Collapse all Expand all
1717 #include "llvm/ADT/StringRef.h"
1818 #include "llvm/ADT/iterator_range.h"
1919 #include "llvm/Object/Binary.h"
20 #include "llvm/Support/Error.h"
2021 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/Error.h"
2222 #include "llvm/Support/FileSystem.h"
2323 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Support/TimeValue.h"
2425
2526 namespace llvm {
2627 namespace object {
1515 #define LLVM_SUPPORT_CACHE_PRUNING_H
1616
1717 #include "llvm/ADT/StringRef.h"
18 #include
1819
1920 namespace llvm {
2021
2829 /// Define the pruning interval. This is intended to be used to avoid scanning
2930 /// the directory too often. It does not impact the decision of which file to
3031 /// prune. A value of 0 forces the scan to occurs.
31 CachePruning &setPruningInterval(int PruningInterval) {
32 CachePruning &setPruningInterval(std::chrono::seconds PruningInterval) {
3233 Interval = PruningInterval;
3334 return *this;
3435 }
3637 /// Define the expiration for a file. When a file hasn't been accessed for
3738 /// \p ExpireAfter seconds, it is removed from the cache. A value of 0 disable
3839 /// the expiration-based pruning.
39 CachePruning &setEntryExpiration(unsigned ExpireAfter) {
40 CachePruning &setEntryExpiration(std::chrono::seconds ExpireAfter) {
4041 Expiration = ExpireAfter;
4142 return *this;
4243 }
5859 private:
5960 // Options that matches the setters above.
6061 std::string Path;
61 unsigned Expiration = 0;
62 unsigned Interval = 0;
62 std::chrono::seconds Expiration;
63 std::chrono::seconds Interval;
6364 unsigned PercentageOfAvailableSpace = 0;
6465 };
6566
6667 } // namespace llvm
6768
68 #endif
69 #endif
3030 #include "llvm/ADT/SmallString.h"
3131 #include "llvm/ADT/StringRef.h"
3232 #include "llvm/ADT/Twine.h"
33 #include "llvm/Support/Chrono.h"
3334 #include "llvm/Support/DataTypes.h"
3435 #include "llvm/Support/ErrorHandling.h"
3536 #include "llvm/Support/ErrorOr.h"
36 #include "llvm/Support/TimeValue.h"
3737 #include
3838 #include
3939 #include
208208 // getters
209209 file_type type() const { return Type; }
210210 perms permissions() const { return Perms; }
211 TimeValue getLastAccessedTime() const;
212 TimeValue getLastModificationTime() const;
211 TimePoint<> getLastAccessedTime() const;
212 TimePoint<> getLastModificationTime() const;
213213 UniqueID getUniqueID() const;
214214
215215 #if defined(LLVM_ON_UNIX)
539539 /// @returns errc::success if the file times were successfully set, otherwise a
540540 /// platform-specific error_code or errc::function_not_supported on
541541 /// platforms where the functionality isn't available.
542 std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
542 std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time);
543543
544544 /// @brief Is status available?
545545 ///
2727 #include "llvm/ADT/Optional.h"
2828 #include "llvm/Config/llvm-config.h"
2929 #include "llvm/Support/Allocator.h"
30 #include "llvm/Support/Chrono.h"
3031 #include "llvm/Support/DataTypes.h"
31 #include "llvm/Support/TimeValue.h"
3232 #include
3333
3434 namespace llvm {
5454 /// This static function will set \p user_time to the amount of CPU time
5555 /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
5656 /// time spent in system (kernel) mode. If the operating system does not
57 /// support collection of these metrics, a zero TimeValue will be for both
57 /// support collection of these metrics, a zero duration will be for both
5858 /// values.
59 /// \param elapsed Returns the TimeValue::now() giving current time
59 /// \param elapsed Returns the system_clock::now() giving current time
6060 /// \param user_time Returns the current amount of user time for the process
6161 /// \param sys_time Returns the current amount of system time for the process
62 static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
63 TimeValue &sys_time);
62 static void GetTimeUsage(TimePoint<> &elapsed,
63 std::chrono::nanoseconds &user_time,
64 std::chrono::nanoseconds &sys_time);
6465
6566 /// This function makes the necessary calls to the operating system to
6667 /// prevent core files or any other kind of large memory dumps that can
835835 }
836836
837837 CachePruning(CacheOptions.Path)
838 .setPruningInterval(CacheOptions.PruningInterval)
839 .setEntryExpiration(CacheOptions.Expiration)
838 .setPruningInterval(std::chrono::seconds(CacheOptions.PruningInterval))
839 .setEntryExpiration(std::chrono::seconds(CacheOptions.Expiration))
840840 .setMaxSize(CacheOptions.MaxPercentageOfAvailableSpace)
841841 .prune();
842842
3434
3535 /// Prune the cache of files that haven't been accessed in a long time.
3636 bool CachePruning::prune() {
37 using namespace std::chrono;
38
3739 if (Path.empty())
3840 return false;
3941
4446 if (!isPathDir)
4547 return false;
4648
47 if (Expiration == 0 && PercentageOfAvailableSpace == 0) {
49 if (Expiration == seconds(0) && PercentageOfAvailableSpace == 0) {
4850 DEBUG(dbgs() << "No pruning settings set, exit early\n");
4951 // Nothing will be pruned, early exit
5052 return false;
5456 SmallString<128> TimestampFile(Path);
5557 sys::path::append(TimestampFile, "llvmcache.timestamp");
5658 sys::fs::file_status FileStatus;
57 sys::TimeValue CurrentTime = sys::TimeValue::now();
59 const auto CurrentTime = system_clock::now();
5860 if (auto EC = sys::fs::status(TimestampFile, FileStatus)) {
5961 if (EC == errc::no_such_file_or_directory) {
6062 // If the timestamp file wasn't there, create one now.
6466 return false;
6567 }
6668 } else {
67 if (Interval) {
69 if (Interval == seconds(0)) {
6870 // Check whether the time stamp is older than our pruning interval.
6971 // If not, do nothing.
70 sys::TimeValue TimeStampModTime = FileStatus.getLastModificationTime();
71 auto TimeInterval = sys::TimeValue(sys::TimeValue::SecondsType(Interval));
72 const auto TimeStampModTime = FileStatus.getLastModificationTime();
7273 auto TimeStampAge = CurrentTime - TimeStampModTime;
73 if (TimeStampAge <= TimeInterval) {
74 DEBUG(dbgs() << "Timestamp file too recent (" << TimeStampAge.seconds()
74 if (TimeStampAge <= Interval) {
75 DEBUG(dbgs() << "Timestamp file too recent ("
76 << duration_cast(TimeStampAge).count()
7577 << "s old), do not prune.\n");
7678 return false;
7779 }
102104 std::error_code EC;
103105 SmallString<128> CachePathNative;
104106 sys::path::native(Path, CachePathNative);
105 auto TimeExpiration = sys::TimeValue(sys::TimeValue::SecondsType(Expiration));
106107 // Walk all of the files within this directory.
107108 for (sys::fs::directory_iterator File(CachePathNative, EC), FileEnd;
108109 File != FileEnd && !EC; File.increment(EC)) {
118119 }
119120
120121 // If the file hasn't been used recently enough, delete it
121 sys::TimeValue FileAccessTime = FileStatus.getLastAccessedTime();
122 const auto FileAccessTime = FileStatus.getLastAccessedTime();
122123 auto FileAge = CurrentTime - FileAccessTime;
123 if (FileAge > TimeExpiration) {
124 DEBUG(dbgs() << "Remove " << File->path() << " (" << FileAge.seconds()
125 << "s old)\n");
124 if (FileAge > Expiration) {
125 DEBUG(dbgs() << "Remove " << File->path() << " ("
126 << duration_cast(FileAge).count() << "s old)\n");
126127 sys::fs::remove(File->path());
127128 continue;
128129 }
115115 }
116116
117117 TimeRecord TimeRecord::getCurrentTime(bool Start) {
118 using Seconds = std::chrono::duration>;
118119 TimeRecord Result;
119 sys::TimeValue now(0,0), user(0,0), sys(0,0);
120 sys::TimePoint<> now;
121 std::chrono::nanoseconds user, sys;
120122
121123 if (Start) {
122124 Result.MemUsed = getMemUsage();
126128 Result.MemUsed = getMemUsage();
127129 }
128130
129 Result.WallTime = now.seconds() + now.microseconds() / 1000000.0;
130 Result.UserTime = user.seconds() + user.microseconds() / 1000000.0;
131 Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0;
131 Result.WallTime = Seconds(now.time_since_epoch()).count();
132 Result.UserTime = Seconds(user).count();
133 Result.SystemTime = Seconds(sys).count();
132134 return Result;
133135 }
134136
197197 return "";
198198 }
199199
200 TimeValue file_status::getLastAccessedTime() const {
201 TimeValue Ret;
202 Ret.fromEpochTime(fs_st_atime);
203 return Ret;
204 }
205
206 TimeValue file_status::getLastModificationTime() const {
207 TimeValue Ret;
208 Ret.fromEpochTime(fs_st_mtime);
209 return Ret;
200 TimePoint<> file_status::getLastAccessedTime() const {
201 return toTimePoint(fs_st_atime);
202 }
203
204 TimePoint<> file_status::getLastModificationTime() const {
205 return toTimePoint(fs_st_mtime);
210206 }
211207
212208 UniqueID file_status::getUniqueID() const {
445441 return fillStatus(StatRet, Status, Result);
446442 }
447443
448 std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
444 std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
449445 #if defined(HAVE_FUTIMENS)
450446 timespec Times[2];
451 Times[0].tv_sec = Time.toEpochTime();
452 Times[0].tv_nsec = 0;
453 Times[1] = Times[0];
447 Times[0] = Times[1] = sys::toTimeSpec(Time);
454448 if (::futimens(FD, Times))
455449 return std::error_code(errno, std::generic_category());
456450 return std::error_code();
457451 #elif defined(HAVE_FUTIMES)
458452 timeval Times[2];
459 Times[0].tv_sec = Time.toEpochTime();
460 Times[0].tv_usec = 0;
461 Times[1] = Times[0];
453 Times[0] = Times[1] = sys::toTimeVal(Time);
462454 if (::futimes(FD, Times))
463455 return std::error_code(errno, std::generic_category());
464456 return std::error_code();
1616 #include "llvm/Support/ManagedStatic.h"
1717 #include "llvm/Support/Mutex.h"
1818 #include "llvm/Support/MutexGuard.h"
19 #include "llvm/Support/TimeValue.h"
2019 #if HAVE_FCNTL_H
2120 #include
2221 #endif
5958 using namespace llvm;
6059 using namespace sys;
6160
62 static std::pair<TimeValue, TimeValue> getRUsageTimes() {
61 static std::pair<std::chrono::microseconds, std::chrono::microseconds> getRUsageTimes() {
6362 #if defined(HAVE_GETRUSAGE)
6463 struct rusage RU;
6564 ::getrusage(RUSAGE_SELF, &RU);
66 return std::make_pair(
67 TimeValue(
68 static_cast(RU.ru_utime.tv_sec),
69 static_cast(
70 RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
71 TimeValue(
72 static_cast(RU.ru_stime.tv_sec),
73 static_cast(
74 RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
65 return { toDuration(RU.ru_utime), toDuration(RU.ru_stime) };
7566 #else
7667 #warning Cannot get usage times on this platform
77 return std::make_pair(TimeValue(), TimeValue());
68 return {};
7869 #endif
7970 }
8071
120111 #endif
121112 }
122113
123 void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
124 TimeValue &sys_time) {
125 elapsed = TimeValue::now();
114 void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
115 std::chrono::nanoseconds &sys_time) {
116 elapsed = std::chrono::system_clock::now();
126117 std::tie(user_time, sys_time) = getRUsageTimes();
127118 }
128119
448439
449440 // Otherwise, swizzle the current time and the process ID to form a reasonable
450441 // seed.
451 TimeValue Now = TimeValue::now();
452 return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
442 const auto Now = std::chrono::high_resolution_clock::now();
443 return hash_combine(Now.time_since_epoch().count(), ::getpid());
453444 }
454445 #endif
455446
1818 //=== is guaranteed to work on all UNIX variants.
1919 //===----------------------------------------------------------------------===//
2020
21 #include "llvm/Config/config.h" // Get autoconf configuration settings
21 #include "llvm/Config/config.h" // Get autoconf configuration settings
22 #include "llvm/Support/Chrono.h"
2223 #include "llvm/Support/Errno.h"
2324 #include
2425 #include
6869 return true;
6970 }
7071
72 namespace llvm {
73 namespace sys {
74
75 /// Convert a struct timeval to a duration. Note that timeval can be used both
76 /// as a time point and a duration. Be sure to check what the input represents.
77 inline std::chrono::microseconds toDuration(const struct timeval &TV) {
78 return std::chrono::seconds(TV.tv_sec) +
79 std::chrono::microseconds(TV.tv_usec);
80 }
81
82 /// Convert a time point to struct timespec.
83 inline struct timespec toTimeSpec(TimePoint<> TP) {
84 using namespace std::chrono;
85
86 struct timespec RetVal;
87 RetVal.tv_sec = toTimeT(TP);
88 RetVal.tv_nsec = (TP.time_since_epoch() % seconds(1)).count();
89 return RetVal;
90 }
91
92 /// Convert a time point to struct timeval.
93 inline struct timeval toTimeVal(TimePoint TP) {
94 using namespace std::chrono;
95
96 struct timeval RetVal;
97 RetVal.tv_sec = toTimeT(TP);
98 RetVal.tv_usec = (TP.time_since_epoch() % seconds(1)).count();
99 return RetVal;
100 }
101
102 } // namespace sys
103 } // namespace llvm
104
71105 #endif
163163 return SpaceInfo;
164164 }
165165
166 TimeValue file_status::getLastAccessedTime() const {
167 ULARGE_INTEGER UI;
168 UI.LowPart = LastAccessedTimeLow;
169 UI.HighPart = LastAccessedTimeHigh;
170
171 TimeValue Ret;
172 Ret.fromWin32Time(UI.QuadPart);
173 return Ret;
174 }
175
176 TimeValue file_status::getLastModificationTime() const {
177 ULARGE_INTEGER UI;
178 UI.LowPart = LastWriteTimeLow;
179 UI.HighPart = LastWriteTimeHigh;
180
181 TimeValue Ret;
182 Ret.fromWin32Time(UI.QuadPart);
183 return Ret;
166 TimePoint<> file_status::getLastAccessedTime() const {
167 FILETIME Time;
168 Time.dwLowDateTime = LastAccessedTimeLow;
169 Time.dwHighDateTime = LastAccessedTimeHigh;
170 return toTimePoint(Time);
171 }
172
173 TimePoint<> file_status::getLastModificationTime() const {
174 FILETIME Time;
175 Time.dwLowDateTime = LastWriteTimeLow;
176 Time.dwHighDateTime = LastWriteTimeHigh;
177 return toTimePoint(Time);
184178 }
185179
186180 std::error_code current_path(SmallVectorImpl &result) {
512506 return getStatus(FileHandle, Result);
513507 }
514508
515 std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
516 ULARGE_INTEGER UI;
517 UI.QuadPart = Time.toWin32Time();
518 FILETIME FT;
519 FT.dwLowDateTime = UI.LowPart;
520 FT.dwHighDateTime = UI.HighPart;
509 std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
510 FILETIME FT = toFILETIME(Time);
521511 HANDLE FileHandle = reinterpret_cast(_get_osfhandle(FD));
522512 if (!SetFileTime(FileHandle, NULL, &FT, &FT))
523513 return mapWindowsError(::GetLastError());
4848 using namespace llvm;
4949 using namespace sys;
5050
51 static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
52 ULARGE_INTEGER TimeInteger;
53 TimeInteger.LowPart = Time.dwLowDateTime;
54 TimeInteger.HighPart = Time.dwHighDateTime;
55
56 // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
57 return TimeValue(
58 static_cast(TimeInteger.QuadPart / 10000000),
59 static_cast(
60 (TimeInteger.QuadPart % 10000000) * 100));
61 }
62
6351 // This function retrieves the page size using GetNativeSystemInfo() and is
6452 // present solely so it can be called once to initialize the self_process member
6553 // below.
9280 return size;
9381 }
9482
95 void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
96 TimeValue &sys_time) {
97 elapsed = TimeValue::now();
83 void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
84 std::chrono::nanoseconds &sys_time) {
85 elapsed = std::chrono::system_clock::now();;
9886
9987 FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
10088 if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
10189 &UserTime) == 0)
10290 return;
10391
104 user_time = getTimeValueFromFILETIME(UserTime);
105 sys_time = getTimeValueFromFILETIME(KernelTime);
92 user_time = toDuration(UserTime);
93 sys_time = toDuration(KernelTime);
10694 }
10795
10896 // Some LLVM programs such as bugpoint produce core files as a normal part of
3838 #include "llvm/ADT/StringRef.h"
3939 #include "llvm/ADT/Twine.h"
4040 #include "llvm/Config/config.h" // Get build system configuration settings
41 #include "llvm/Support/Chrono.h"
4142 #include "llvm/Support/Compiler.h"
42 #include
43 #include
44 #include
4543 #include
4644 #include
45 #include
46 #include
47 #include
4748
4849 /// Determines if the program is running on Windows 8 or newer. This
4950 /// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
210211 }
211212
212213 namespace sys {
214
215 inline std::chrono::nanoseconds toDuration(FILETIME Time) {
216 ULARGE_INTEGER TimeInteger;
217 TimeInteger.LowPart = Time.dwLowDateTime;
218 TimeInteger.HighPart = Time.dwHighDateTime;
219
220 // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
221 return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
222 }
223
224 inline TimePoint<> toTimePoint(FILETIME Time) {
225 ULARGE_INTEGER TimeInteger;
226 TimeInteger.LowPart = Time.dwLowDateTime;
227 TimeInteger.HighPart = Time.dwHighDateTime;
228
229 // Adjust for different epoch
230 TimeInteger.QuadPart -= 11644473600ll * 10000000;
231
232 // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
233 return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
234 }
235
236 inline FILETIME toFILETIME(TimePoint<> TP) {
237 ULARGE_INTEGER TimeInteger;
238 TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
239 TimeInteger.QuadPart += 11644473600ll * 10000000;
240
241 FILETIME Time;
242 Time.dwLowDateTime = TimeInteger.LowPart;
243 Time.dwHighDateTime = TimeInteger.HighPart;
244 return Time;
245 }
246
213247 namespace path {
214248 std::error_code widenPath(const Twine &Path8,
215249 SmallVectorImpl &Path16);
2020 #include "llvm/Object/ArchiveWriter.h"
2121 #include "llvm/Object/MachO.h"
2222 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Support/Chrono.h"
2324 #include "llvm/Support/CommandLine.h"
2425 #include "llvm/Support/Errc.h"
2526 #include "llvm/Support/FileSystem.h"
352353 Expected Size = C.getSize();
353354 failIfError(Size.takeError());
354355 outs() << ' ' << format("%6llu", Size.get());
355 Expected ModTimeOrErr = C.getLastModified();
356 auto ModTimeOrErr = C.getLastModified();
356357 failIfError(ModTimeOrErr.takeError());
357 outs() << ' ' << ModTimeOrErr.get().str();
358 outs() << ' ' << ModTimeOrErr.get();
358359 outs() << ' ';
359360 }
360361 outs() << Name << "\n";
386387 // If we're supposed to retain the original modification times, etc. do so
387388 // now.
388389 if (OriginalDates) {
389 Expected ModTimeOrErr = C.getLastModified();
390 auto ModTimeOrErr = C.getLastModified();
390391 failIfError(ModTimeOrErr.takeError());
391392 failIfError(
392393 sys::fs::setLastModificationAndAccessTime(FD, ModTimeOrErr.get()));
524525 // operation.
525526 sys::fs::file_status Status;
526527 failIfError(sys::fs::status(*MI, Status), *MI);
527 Expected ModTimeOrErr = Member.getLastModified();
528 auto ModTimeOrErr = Member.getLastModified();
528529 failIfError(ModTimeOrErr.takeError());
529 if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
530 if (sys::TimeValue(Status.getLastModificationTime()) < ModTimeOrErr.get()) {
530531 if (PosName.empty())
531532 return IA_AddOldMember;
532533 return IA_MoveOldMember;
2929 #include "llvm/Support/Path.h"
3030 #include "llvm/Support/Process.h"
3131 #include "llvm/Support/Program.h"
32 #include "llvm/Support/ScopedPrinter.h"
3233 #include "llvm/Support/ThreadPool.h"
3334 #include "llvm/Support/ToolOutputFile.h"
3435 #include
733734 }
734735
735736 auto ModifiedTime = Status.getLastModificationTime();
736 std::string ModifiedTimeStr = ModifiedTime.str();
737 std::string ModifiedTimeStr = to_string(ModifiedTime);
737738 size_t found = ModifiedTimeStr.rfind(":");
738739 ViewOpts.CreatedTimeStr = (found != std::string::npos)
739740 ? "Created: " + ModifiedTimeStr.substr(0, found)