forked from OSchip/llvm-project
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 llvm-svn: 284966
This commit is contained in:
parent
407fd070b7
commit
757ca886cd
|
@ -18,10 +18,11 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/TimeValue.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define LLVM_SUPPORT_CACHE_PRUNING_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <chrono>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -29,7 +30,7 @@ public:
|
|||
/// Define the pruning interval. This is intended to be used to avoid scanning
|
||||
/// the directory too often. It does not impact the decision of which file to
|
||||
/// prune. A value of 0 forces the scan to occurs.
|
||||
CachePruning &setPruningInterval(int PruningInterval) {
|
||||
CachePruning &setPruningInterval(std::chrono::seconds PruningInterval) {
|
||||
Interval = PruningInterval;
|
||||
return *this;
|
||||
}
|
||||
|
@ -37,7 +38,7 @@ public:
|
|||
/// Define the expiration for a file. When a file hasn't been accessed for
|
||||
/// \p ExpireAfter seconds, it is removed from the cache. A value of 0 disable
|
||||
/// the expiration-based pruning.
|
||||
CachePruning &setEntryExpiration(unsigned ExpireAfter) {
|
||||
CachePruning &setEntryExpiration(std::chrono::seconds ExpireAfter) {
|
||||
Expiration = ExpireAfter;
|
||||
return *this;
|
||||
}
|
||||
|
@ -59,11 +60,11 @@ public:
|
|||
private:
|
||||
// Options that matches the setters above.
|
||||
std::string Path;
|
||||
unsigned Expiration = 0;
|
||||
unsigned Interval = 0;
|
||||
std::chrono::seconds Expiration;
|
||||
std::chrono::seconds Interval;
|
||||
unsigned PercentageOfAvailableSpace = 0;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/TimeValue.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
|
@ -209,8 +209,8 @@ public:
|
|||
// getters
|
||||
file_type type() const { return Type; }
|
||||
perms permissions() const { return Perms; }
|
||||
TimeValue getLastAccessedTime() const;
|
||||
TimeValue getLastModificationTime() const;
|
||||
TimePoint<> getLastAccessedTime() const;
|
||||
TimePoint<> getLastModificationTime() const;
|
||||
UniqueID getUniqueID() const;
|
||||
|
||||
#if defined(LLVM_ON_UNIX)
|
||||
|
@ -540,7 +540,7 @@ inline std::error_code file_size(const Twine &Path, uint64_t &Result) {
|
|||
/// @returns errc::success if the file times were successfully set, otherwise a
|
||||
/// platform-specific error_code or errc::function_not_supported on
|
||||
/// platforms where the functionality isn't available.
|
||||
std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
|
||||
std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time);
|
||||
|
||||
/// @brief Is status available?
|
||||
///
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/TimeValue.h"
|
||||
#include <system_error>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -55,13 +55,14 @@ public:
|
|||
/// This static function will set \p user_time to the amount of CPU time
|
||||
/// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
|
||||
/// time spent in system (kernel) mode. If the operating system does not
|
||||
/// support collection of these metrics, a zero TimeValue will be for both
|
||||
/// support collection of these metrics, a zero duration will be for both
|
||||
/// values.
|
||||
/// \param elapsed Returns the TimeValue::now() giving current time
|
||||
/// \param elapsed Returns the system_clock::now() giving current time
|
||||
/// \param user_time Returns the current amount of user time for the process
|
||||
/// \param sys_time Returns the current amount of system time for the process
|
||||
static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
|
||||
TimeValue &sys_time);
|
||||
static void GetTimeUsage(TimePoint<> &elapsed,
|
||||
std::chrono::nanoseconds &user_time,
|
||||
std::chrono::nanoseconds &sys_time);
|
||||
|
||||
/// This function makes the necessary calls to the operating system to
|
||||
/// prevent core files or any other kind of large memory dumps that can
|
||||
|
|
|
@ -836,8 +836,8 @@ void ThinLTOCodeGenerator::run() {
|
|||
}
|
||||
|
||||
CachePruning(CacheOptions.Path)
|
||||
.setPruningInterval(CacheOptions.PruningInterval)
|
||||
.setEntryExpiration(CacheOptions.Expiration)
|
||||
.setPruningInterval(std::chrono::seconds(CacheOptions.PruningInterval))
|
||||
.setEntryExpiration(std::chrono::seconds(CacheOptions.Expiration))
|
||||
.setMaxSize(CacheOptions.MaxPercentageOfAvailableSpace)
|
||||
.prune();
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ static void writeTimestampFile(StringRef TimestampFile) {
|
|||
|
||||
/// Prune the cache of files that haven't been accessed in a long time.
|
||||
bool CachePruning::prune() {
|
||||
using namespace std::chrono;
|
||||
|
||||
if (Path.empty())
|
||||
return false;
|
||||
|
||||
|
@ -45,7 +47,7 @@ bool CachePruning::prune() {
|
|||
if (!isPathDir)
|
||||
return false;
|
||||
|
||||
if (Expiration == 0 && PercentageOfAvailableSpace == 0) {
|
||||
if (Expiration == seconds(0) && PercentageOfAvailableSpace == 0) {
|
||||
DEBUG(dbgs() << "No pruning settings set, exit early\n");
|
||||
// Nothing will be pruned, early exit
|
||||
return false;
|
||||
|
@ -55,7 +57,7 @@ bool CachePruning::prune() {
|
|||
SmallString<128> TimestampFile(Path);
|
||||
sys::path::append(TimestampFile, "llvmcache.timestamp");
|
||||
sys::fs::file_status FileStatus;
|
||||
sys::TimeValue CurrentTime = sys::TimeValue::now();
|
||||
const auto CurrentTime = system_clock::now();
|
||||
if (auto EC = sys::fs::status(TimestampFile, FileStatus)) {
|
||||
if (EC == errc::no_such_file_or_directory) {
|
||||
// If the timestamp file wasn't there, create one now.
|
||||
|
@ -65,14 +67,14 @@ bool CachePruning::prune() {
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
if (Interval) {
|
||||
if (Interval == seconds(0)) {
|
||||
// Check whether the time stamp is older than our pruning interval.
|
||||
// If not, do nothing.
|
||||
sys::TimeValue TimeStampModTime = FileStatus.getLastModificationTime();
|
||||
auto TimeInterval = sys::TimeValue(sys::TimeValue::SecondsType(Interval));
|
||||
const auto TimeStampModTime = FileStatus.getLastModificationTime();
|
||||
auto TimeStampAge = CurrentTime - TimeStampModTime;
|
||||
if (TimeStampAge <= TimeInterval) {
|
||||
DEBUG(dbgs() << "Timestamp file too recent (" << TimeStampAge.seconds()
|
||||
if (TimeStampAge <= Interval) {
|
||||
DEBUG(dbgs() << "Timestamp file too recent ("
|
||||
<< duration_cast<seconds>(TimeStampAge).count()
|
||||
<< "s old), do not prune.\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -103,7 +105,6 @@ bool CachePruning::prune() {
|
|||
std::error_code EC;
|
||||
SmallString<128> CachePathNative;
|
||||
sys::path::native(Path, CachePathNative);
|
||||
auto TimeExpiration = sys::TimeValue(sys::TimeValue::SecondsType(Expiration));
|
||||
// Walk all of the files within this directory.
|
||||
for (sys::fs::directory_iterator File(CachePathNative, EC), FileEnd;
|
||||
File != FileEnd && !EC; File.increment(EC)) {
|
||||
|
@ -119,11 +120,11 @@ bool CachePruning::prune() {
|
|||
}
|
||||
|
||||
// If the file hasn't been used recently enough, delete it
|
||||
sys::TimeValue FileAccessTime = FileStatus.getLastAccessedTime();
|
||||
const auto FileAccessTime = FileStatus.getLastAccessedTime();
|
||||
auto FileAge = CurrentTime - FileAccessTime;
|
||||
if (FileAge > TimeExpiration) {
|
||||
DEBUG(dbgs() << "Remove " << File->path() << " (" << FileAge.seconds()
|
||||
<< "s old)\n");
|
||||
if (FileAge > Expiration) {
|
||||
DEBUG(dbgs() << "Remove " << File->path() << " ("
|
||||
<< duration_cast<seconds>(FileAge).count() << "s old)\n");
|
||||
sys::fs::remove(File->path());
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -116,8 +116,10 @@ static inline size_t getMemUsage() {
|
|||
}
|
||||
|
||||
TimeRecord TimeRecord::getCurrentTime(bool Start) {
|
||||
using Seconds = std::chrono::duration<double, std::ratio<1>>;
|
||||
TimeRecord Result;
|
||||
sys::TimeValue now(0,0), user(0,0), sys(0,0);
|
||||
sys::TimePoint<> now;
|
||||
std::chrono::nanoseconds user, sys;
|
||||
|
||||
if (Start) {
|
||||
Result.MemUsed = getMemUsage();
|
||||
|
@ -127,9 +129,9 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
|
|||
Result.MemUsed = getMemUsage();
|
||||
}
|
||||
|
||||
Result.WallTime = now.seconds() + now.microseconds() / 1000000.0;
|
||||
Result.UserTime = user.seconds() + user.microseconds() / 1000000.0;
|
||||
Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0;
|
||||
Result.WallTime = Seconds(now.time_since_epoch()).count();
|
||||
Result.UserTime = Seconds(user).count();
|
||||
Result.SystemTime = Seconds(sys).count();
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,16 +198,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
|
|||
return "";
|
||||
}
|
||||
|
||||
TimeValue file_status::getLastAccessedTime() const {
|
||||
TimeValue Ret;
|
||||
Ret.fromEpochTime(fs_st_atime);
|
||||
return Ret;
|
||||
TimePoint<> file_status::getLastAccessedTime() const {
|
||||
return toTimePoint(fs_st_atime);
|
||||
}
|
||||
|
||||
TimeValue file_status::getLastModificationTime() const {
|
||||
TimeValue Ret;
|
||||
Ret.fromEpochTime(fs_st_mtime);
|
||||
return Ret;
|
||||
TimePoint<> file_status::getLastModificationTime() const {
|
||||
return toTimePoint(fs_st_mtime);
|
||||
}
|
||||
|
||||
UniqueID file_status::getUniqueID() const {
|
||||
|
@ -446,20 +442,16 @@ std::error_code status(int FD, file_status &Result) {
|
|||
return fillStatus(StatRet, Status, Result);
|
||||
}
|
||||
|
||||
std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
|
||||
std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
|
||||
#if defined(HAVE_FUTIMENS)
|
||||
timespec Times[2];
|
||||
Times[0].tv_sec = Time.toEpochTime();
|
||||
Times[0].tv_nsec = 0;
|
||||
Times[1] = Times[0];
|
||||
Times[0] = Times[1] = sys::toTimeSpec(Time);
|
||||
if (::futimens(FD, Times))
|
||||
return std::error_code(errno, std::generic_category());
|
||||
return std::error_code();
|
||||
#elif defined(HAVE_FUTIMES)
|
||||
timeval Times[2];
|
||||
Times[0].tv_sec = Time.toEpochTime();
|
||||
Times[0].tv_usec = 0;
|
||||
Times[1] = Times[0];
|
||||
Times[0] = Times[1] = sys::toTimeVal(Time);
|
||||
if (::futimes(FD, Times))
|
||||
return std::error_code(errno, std::generic_category());
|
||||
return std::error_code();
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
#include "llvm/Support/MutexGuard.h"
|
||||
#include "llvm/Support/TimeValue.h"
|
||||
#if HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
@ -60,22 +59,14 @@
|
|||
using namespace llvm;
|
||||
using namespace sys;
|
||||
|
||||
static std::pair<TimeValue, TimeValue> getRUsageTimes() {
|
||||
static std::pair<std::chrono::microseconds, std::chrono::microseconds> getRUsageTimes() {
|
||||
#if defined(HAVE_GETRUSAGE)
|
||||
struct rusage RU;
|
||||
::getrusage(RUSAGE_SELF, &RU);
|
||||
return std::make_pair(
|
||||
TimeValue(
|
||||
static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
|
||||
static_cast<TimeValue::NanoSecondsType>(
|
||||
RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
|
||||
TimeValue(
|
||||
static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
|
||||
static_cast<TimeValue::NanoSecondsType>(
|
||||
RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
|
||||
return { toDuration(RU.ru_utime), toDuration(RU.ru_stime) };
|
||||
#else
|
||||
#warning Cannot get usage times on this platform
|
||||
return std::make_pair(TimeValue(), TimeValue());
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -121,9 +112,9 @@ size_t Process::GetMallocUsage() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
|
||||
TimeValue &sys_time) {
|
||||
elapsed = TimeValue::now();
|
||||
void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
|
||||
std::chrono::nanoseconds &sys_time) {
|
||||
elapsed = std::chrono::system_clock::now();
|
||||
std::tie(user_time, sys_time) = getRUsageTimes();
|
||||
}
|
||||
|
||||
|
@ -449,8 +440,8 @@ static unsigned GetRandomNumberSeed() {
|
|||
|
||||
// Otherwise, swizzle the current time and the process ID to form a reasonable
|
||||
// seed.
|
||||
TimeValue Now = TimeValue::now();
|
||||
return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
|
||||
const auto Now = std::chrono::high_resolution_clock::now();
|
||||
return hash_combine(Now.time_since_epoch().count(), ::getpid());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
//=== is guaranteed to work on all UNIX variants.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Config/config.h" // Get autoconf configuration settings
|
||||
#include "llvm/Config/config.h" // Get autoconf configuration settings
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/Errno.h"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
@ -69,4 +70,37 @@ static inline bool MakeErrMsg(
|
|||
return true;
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// Convert a struct timeval to a duration. Note that timeval can be used both
|
||||
/// as a time point and a duration. Be sure to check what the input represents.
|
||||
inline std::chrono::microseconds toDuration(const struct timeval &TV) {
|
||||
return std::chrono::seconds(TV.tv_sec) +
|
||||
std::chrono::microseconds(TV.tv_usec);
|
||||
}
|
||||
|
||||
/// Convert a time point to struct timespec.
|
||||
inline struct timespec toTimeSpec(TimePoint<> TP) {
|
||||
using namespace std::chrono;
|
||||
|
||||
struct timespec RetVal;
|
||||
RetVal.tv_sec = toTimeT(TP);
|
||||
RetVal.tv_nsec = (TP.time_since_epoch() % seconds(1)).count();
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/// Convert a time point to struct timeval.
|
||||
inline struct timeval toTimeVal(TimePoint<std::chrono::microseconds> TP) {
|
||||
using namespace std::chrono;
|
||||
|
||||
struct timeval RetVal;
|
||||
RetVal.tv_sec = toTimeT(TP);
|
||||
RetVal.tv_usec = (TP.time_since_epoch() % seconds(1)).count();
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
} // namespace sys
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
|
|
@ -164,24 +164,18 @@ ErrorOr<space_info> disk_space(const Twine &Path) {
|
|||
return SpaceInfo;
|
||||
}
|
||||
|
||||
TimeValue file_status::getLastAccessedTime() const {
|
||||
ULARGE_INTEGER UI;
|
||||
UI.LowPart = LastAccessedTimeLow;
|
||||
UI.HighPart = LastAccessedTimeHigh;
|
||||
|
||||
TimeValue Ret;
|
||||
Ret.fromWin32Time(UI.QuadPart);
|
||||
return Ret;
|
||||
TimePoint<> file_status::getLastAccessedTime() const {
|
||||
FILETIME Time;
|
||||
Time.dwLowDateTime = LastAccessedTimeLow;
|
||||
Time.dwHighDateTime = LastAccessedTimeHigh;
|
||||
return toTimePoint(Time);
|
||||
}
|
||||
|
||||
TimeValue file_status::getLastModificationTime() const {
|
||||
ULARGE_INTEGER UI;
|
||||
UI.LowPart = LastWriteTimeLow;
|
||||
UI.HighPart = LastWriteTimeHigh;
|
||||
|
||||
TimeValue Ret;
|
||||
Ret.fromWin32Time(UI.QuadPart);
|
||||
return Ret;
|
||||
TimePoint<> file_status::getLastModificationTime() const {
|
||||
FILETIME Time;
|
||||
Time.dwLowDateTime = LastWriteTimeLow;
|
||||
Time.dwHighDateTime = LastWriteTimeHigh;
|
||||
return toTimePoint(Time);
|
||||
}
|
||||
|
||||
std::error_code current_path(SmallVectorImpl<char> &result) {
|
||||
|
@ -513,12 +507,8 @@ std::error_code status(int FD, file_status &Result) {
|
|||
return getStatus(FileHandle, Result);
|
||||
}
|
||||
|
||||
std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
|
||||
ULARGE_INTEGER UI;
|
||||
UI.QuadPart = Time.toWin32Time();
|
||||
FILETIME FT;
|
||||
FT.dwLowDateTime = UI.LowPart;
|
||||
FT.dwHighDateTime = UI.HighPart;
|
||||
std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
|
||||
FILETIME FT = toFILETIME(Time);
|
||||
HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
|
||||
if (!SetFileTime(FileHandle, NULL, &FT, &FT))
|
||||
return mapWindowsError(::GetLastError());
|
||||
|
|
|
@ -49,18 +49,6 @@
|
|||
using namespace llvm;
|
||||
using namespace sys;
|
||||
|
||||
static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.LowPart = Time.dwLowDateTime;
|
||||
TimeInteger.HighPart = Time.dwHighDateTime;
|
||||
|
||||
// FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
|
||||
return TimeValue(
|
||||
static_cast<TimeValue::SecondsType>(TimeInteger.QuadPart / 10000000),
|
||||
static_cast<TimeValue::NanoSecondsType>(
|
||||
(TimeInteger.QuadPart % 10000000) * 100));
|
||||
}
|
||||
|
||||
// This function retrieves the page size using GetNativeSystemInfo() and is
|
||||
// present solely so it can be called once to initialize the self_process member
|
||||
// below.
|
||||
|
@ -93,17 +81,17 @@ Process::GetMallocUsage()
|
|||
return size;
|
||||
}
|
||||
|
||||
void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
|
||||
TimeValue &sys_time) {
|
||||
elapsed = TimeValue::now();
|
||||
void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
|
||||
std::chrono::nanoseconds &sys_time) {
|
||||
elapsed = std::chrono::system_clock::now();;
|
||||
|
||||
FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
|
||||
if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
|
||||
&UserTime) == 0)
|
||||
return;
|
||||
|
||||
user_time = getTimeValueFromFILETIME(UserTime);
|
||||
sys_time = getTimeValueFromFILETIME(KernelTime);
|
||||
user_time = toDuration(UserTime);
|
||||
sys_time = toDuration(KernelTime);
|
||||
}
|
||||
|
||||
// Some LLVM programs such as bugpoint produce core files as a normal part of
|
||||
|
|
|
@ -39,12 +39,13 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Config/config.h" // Get build system configuration settings
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <system_error>
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <wincrypt.h>
|
||||
#include <windows.h>
|
||||
|
||||
/// Determines if the program is running on Windows 8 or newer. This
|
||||
/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
|
||||
|
@ -211,6 +212,39 @@ c_str(SmallVectorImpl<T> &str) {
|
|||
}
|
||||
|
||||
namespace sys {
|
||||
|
||||
inline std::chrono::nanoseconds toDuration(FILETIME Time) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.LowPart = Time.dwLowDateTime;
|
||||
TimeInteger.HighPart = Time.dwHighDateTime;
|
||||
|
||||
// FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
|
||||
return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
|
||||
}
|
||||
|
||||
inline TimePoint<> toTimePoint(FILETIME Time) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.LowPart = Time.dwLowDateTime;
|
||||
TimeInteger.HighPart = Time.dwHighDateTime;
|
||||
|
||||
// Adjust for different epoch
|
||||
TimeInteger.QuadPart -= 11644473600ll * 10000000;
|
||||
|
||||
// FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
|
||||
return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
|
||||
}
|
||||
|
||||
inline FILETIME toFILETIME(TimePoint<> TP) {
|
||||
ULARGE_INTEGER TimeInteger;
|
||||
TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
|
||||
TimeInteger.QuadPart += 11644473600ll * 10000000;
|
||||
|
||||
FILETIME Time;
|
||||
Time.dwLowDateTime = TimeInteger.LowPart;
|
||||
Time.dwHighDateTime = TimeInteger.HighPart;
|
||||
return Time;
|
||||
}
|
||||
|
||||
namespace path {
|
||||
std::error_code widenPath(const Twine &Path8,
|
||||
SmallVectorImpl<wchar_t> &Path16);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/Object/ArchiveWriter.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
@ -353,9 +354,9 @@ static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
|
|||
Expected<uint64_t> Size = C.getSize();
|
||||
failIfError(Size.takeError());
|
||||
outs() << ' ' << format("%6llu", Size.get());
|
||||
Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
|
||||
auto ModTimeOrErr = C.getLastModified();
|
||||
failIfError(ModTimeOrErr.takeError());
|
||||
outs() << ' ' << ModTimeOrErr.get().str();
|
||||
outs() << ' ' << ModTimeOrErr.get();
|
||||
outs() << ' ';
|
||||
}
|
||||
outs() << Name << "\n";
|
||||
|
@ -387,7 +388,7 @@ static void doExtract(StringRef Name, const object::Archive::Child &C) {
|
|||
// If we're supposed to retain the original modification times, etc. do so
|
||||
// now.
|
||||
if (OriginalDates) {
|
||||
Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
|
||||
auto ModTimeOrErr = C.getLastModified();
|
||||
failIfError(ModTimeOrErr.takeError());
|
||||
failIfError(
|
||||
sys::fs::setLastModificationAndAccessTime(FD, ModTimeOrErr.get()));
|
||||
|
@ -525,9 +526,9 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
|
|||
// operation.
|
||||
sys::fs::file_status Status;
|
||||
failIfError(sys::fs::status(*MI, Status), *MI);
|
||||
Expected<sys::TimeValue> ModTimeOrErr = Member.getLastModified();
|
||||
auto ModTimeOrErr = Member.getLastModified();
|
||||
failIfError(ModTimeOrErr.takeError());
|
||||
if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
|
||||
if (sys::TimeValue(Status.getLastModificationTime()) < ModTimeOrErr.get()) {
|
||||
if (PosName.empty())
|
||||
return IA_AddOldMember;
|
||||
return IA_MoveOldMember;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/ScopedPrinter.h"
|
||||
#include "llvm/Support/ThreadPool.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
#include <functional>
|
||||
|
@ -734,7 +735,7 @@ int CodeCoverageTool::show(int argc, const char **argv,
|
|||
}
|
||||
|
||||
auto ModifiedTime = Status.getLastModificationTime();
|
||||
std::string ModifiedTimeStr = ModifiedTime.str();
|
||||
std::string ModifiedTimeStr = to_string(ModifiedTime);
|
||||
size_t found = ModifiedTimeStr.rfind(":");
|
||||
ViewOpts.CreatedTimeStr = (found != std::string::npos)
|
||||
? "Created: " + ModifiedTimeStr.substr(0, found)
|
||||
|
|
Loading…
Reference in New Issue