llvm.org GIT mirror llvm / 911bb94
Reapply "Add Chrono.h - std::chrono support header" This is a resubmission of r284590. The mingw build should be fixed now. The problem was we were matching time_t with _localtime_64s, which was incorrect on _USE_32BIT_TIME_T systems. Instead I use localtime_s, which should always evaluate to the correct function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284720 91177308-0d34-0410-b5e6-96231b3b80d8 Pavel Labath 4 years ago
10 changed file(s) with 212 addition(s) and 124 deletion(s). Raw diff Collapse all Expand all
0 //===- llvm/Support/Chrono.h - Utilities for Timing Manipulation-*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_CHRONO_H
10 #define LLVM_SUPPORT_CHRONO_H
11
12 #include "llvm/Support/Compiler.h"
13
14 #include
15 #include
16
17 namespace llvm {
18
19 class raw_ostream;
20
21 namespace sys {
22
23 /// A time point on the system clock. This is provided for two reasons:
24 /// - to insulate us agains subtle differences in behavoir to differences in
25 /// system clock precision (which is implementation-defined and differs between
26 /// platforms).
27 /// - to shorten the type name
28 /// The default precision is nanoseconds. If need a specific precision specify
29 /// it explicitly. If unsure, use the default. If you need a time point on a
30 /// clock other than the system_clock, use std::chrono directly.
31 template
32 using TimePoint = std::chrono::time_point;
33
34 /// Convert a TimePoint to std::time_t
35 LLVM_ATTRIBUTE_ALWAYS_INLINE inline std::time_t toTimeT(TimePoint<> TP) {
36 using namespace std::chrono;
37 return system_clock::to_time_t(
38 time_point_cast(TP));
39 }
40
41 /// Convert a std::time_t to a TimePoint
42 LLVM_ATTRIBUTE_ALWAYS_INLINE inline TimePoint
43 toTimePoint(std::time_t T) {
44 using namespace std::chrono;
45 return time_point_cast(system_clock::from_time_t(T));
46 }
47
48 } // namespace sys
49
50 raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);
51
52 } // namespace llvm
53
54 #endif // LLVM_SUPPORT_CHRONO_H
1313 #ifndef LLVM_SUPPORT_TIMEVALUE_H
1414 #define LLVM_SUPPORT_TIMEVALUE_H
1515
16 #include "llvm/Support/Chrono.h"
1617 #include "llvm/Support/DataTypes.h"
1718 #include
1819
111112 this->normalize();
112113 }
113114
115 template
116 TimeValue(TimePoint TP)
117 : seconds_(sys::toTimeT(TP) + PosixZeroTimeSeconds),
118 nanos_((TimePoint<>(TP).time_since_epoch() % std::chrono::seconds(1)).count()) {}
119
114120 /// This is a static constructor that returns a TimeValue that represents
115121 /// the current time.
116122 /// @brief Creates a TimeValue with the current time (UTC).
120126 /// @name Operators
121127 /// @{
122128 public:
129 operator TimePoint<>() const {
130 return toTimePoint(seconds_ - PosixZeroTimeSeconds) +
131 std::chrono::nanoseconds(nanos_);
132 }
133
123134 /// Add \p that to \p this.
124135 /// @returns this
125136 /// @brief Incrementing assignment operator.
3636 BranchProbability.cpp
3737 CachePruning.cpp
3838 circular_raw_ostream.cpp
39 Chrono.cpp
3940 COM.cpp
4041 CommandLine.cpp
4142 Compression.cpp
0 //===- Support/Chrono.cpp - Utilities for Timing Manipulation ---*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/Chrono.h"
10 #include "llvm/Config/config.h"
11 #include "llvm/Support/Format.h"
12 #include "llvm/Support/raw_ostream.h"
13
14 namespace llvm {
15
16 using namespace sys;
17
18 static inline struct tm getStructTM(TimePoint<> TP) {
19 struct tm Storage;
20 std::time_t OurTime = toTimeT(TP);
21
22 #if defined(LLVM_ON_UNIX)
23 struct tm *LT = ::localtime_r(&OurTime, &Storage);
24 assert(LT);
25 (void)LT;
26 #endif
27 #if defined(LLVM_ON_WIN32)
28 int Error = ::localtime_s(&Storage, &OurTime);
29 assert(!Error);
30 (void)Error;
31 #endif
32
33 return Storage;
34 }
35
36 raw_ostream &operator<<(raw_ostream &OS, TimePoint<> TP) {
37 struct tm LT = getStructTM(TP);
38 char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
39 strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", <);
40 return OS << Buffer << '.'
41 << format("%.9lu",
42 long((TP.time_since_epoch() % std::chrono::seconds(1))
43 .count()));
44 }
45
46 } // namespace llvm
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "llvm/Support/TimeValue.h"
14 #include "llvm/Config/config.h"
14 #include "llvm/Support/Chrono.h"
15 #include "llvm/Support/ScopedPrinter.h"
1516
1617 namespace llvm {
1718
4445 }
4546 }
4647
48 std::string TimeValue::str() const { return to_string(TimePoint<>(*this)); }
49
50 TimeValue TimeValue::now() {
51 return TimePoint<>(std::chrono::system_clock::now());
52 }
53
4754 } // namespace llvm
48
49 /// Include the platform-specific portion of TimeValue class
50 #ifdef LLVM_ON_UNIX
51 #include "Unix/TimeValue.inc"
52 #endif
53 #ifdef LLVM_ON_WIN32
54 #include "Windows/TimeValue.inc"
55 #endif
+0
-54
lib/Support/Unix/TimeValue.inc less more
None //===- Unix/TimeValue.cpp - Unix TimeValue Implementation -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Unix specific portion of the TimeValue class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 //===----------------------------------------------------------------------===//
14 //=== WARNING: Implementation here must contain only generic UNIX code that
15 //=== is guaranteed to work on *all* UNIX variants.
16 //===----------------------------------------------------------------------===//
17
18 #include "Unix.h"
19
20 namespace llvm {
21 using namespace sys;
22
23 std::string TimeValue::str() const {
24 time_t OurTime = time_t(this->toEpochTime());
25 struct tm Storage;
26 struct tm *LT = ::localtime_r(&OurTime, &Storage);
27 assert(LT);
28 char Buffer1[sizeof("YYYY-MM-DD HH:MM:SS")];
29 strftime(Buffer1, sizeof(Buffer1), "%Y-%m-%d %H:%M:%S", LT);
30 char Buffer2[sizeof("YYYY-MM-DD HH:MM:SS.MMMUUUNNN")];
31 snprintf(Buffer2, sizeof(Buffer2), "%s.%.9u", Buffer1, this->nanoseconds());
32 return std::string(Buffer2);
33 }
34
35 TimeValue TimeValue::now() {
36 struct timeval the_time;
37 timerclear(&the_time);
38 if (0 != ::gettimeofday(&the_time,nullptr)) {
39 // This is *really* unlikely to occur because the only gettimeofday
40 // errors concern the timezone parameter which we're passing in as 0.
41 // In the unlikely case it does happen, just return MinTime, no error
42 // message needed.
43 return MinTime();
44 }
45
46 return TimeValue(
47 static_cast( the_time.tv_sec +
48 PosixZeroTimeSeconds ),
49 static_cast( the_time.tv_usec *
50 NANOSECONDS_PER_MICROSECOND ) );
51 }
52
53 }
+0
-61
lib/Support/Windows/TimeValue.inc less more
None //===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides the Win32 implementation of the TimeValue class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "WindowsSupport.h"
14 #include "llvm/Support/Format.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include
17 #include
18
19 using namespace llvm;
20 using namespace llvm::sys;
21
22 //===----------------------------------------------------------------------===//
23 //=== WARNING: Implementation here must contain only Win32 specific code.
24 //===----------------------------------------------------------------------===//
25
26 TimeValue TimeValue::now() {
27 uint64_t ft;
28 GetSystemTimeAsFileTime(reinterpret_cast(&ft));
29
30 TimeValue t(0, 0);
31 t.fromWin32Time(ft);
32 return t;
33 }
34
35 std::string TimeValue::str() const {
36 std::string S;
37 struct tm *LT;
38 #ifdef __MINGW32__
39 // Old versions of mingw don't have _localtime64_s. Remove this once we drop support
40 // for them.
41 time_t OurTime = time_t(this->toEpochTime());
42 LT = ::localtime(&OurTime);
43 assert(LT);
44 #else
45 struct tm Storage;
46 __time64_t OurTime = this->toEpochTime();
47 int Error = ::_localtime64_s(&Storage, &OurTime);
48 assert(!Error);
49 (void)Error;
50 LT = &Storage;
51 #endif
52
53 char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
54 strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", LT);
55 raw_string_ostream OS(S);
56 OS << format("%s.%.9u", static_cast(Buffer),
57 this->nanoseconds());
58 OS.flush();
59 return S;
60 }
88 BlockFrequencyTest.cpp
99 BranchProbabilityTest.cpp
1010 Casting.cpp
11 Chrono.cpp
1112 CommandLineTest.cpp
1213 CompressionTest.cpp
1314 ConvertUTFTest.cpp
0 //===- llvm/unittest/Support/Chrono.cpp - Time utilities tests ------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/Chrono.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "gtest/gtest.h"
12
13 using namespace llvm;
14 using namespace llvm::sys;
15 using namespace std::chrono;
16
17 namespace {
18
19 TEST(Chrono, TimeTConversion) {
20 EXPECT_EQ(time_t(0), toTimeT(toTimePoint(time_t(0))));
21 EXPECT_EQ(time_t(1), toTimeT(toTimePoint(time_t(1))));
22 EXPECT_EQ(time_t(47), toTimeT(toTimePoint(time_t(47))));
23
24 TimePoint<> TP;
25 EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
26 TP += seconds(1);
27 EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
28 TP += hours(47);
29 EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
30 }
31
32 TEST(Chrono, StringConversion) {
33 std::string S;
34 raw_string_ostream OS(S);
35 OS << system_clock::now();
36
37 // Do a basic sanity check on the output.
38 // The format we expect is YYYY-MM-DD HH:MM:SS.MMMUUUNNN
39 StringRef Date, Time;
40 std::tie(Date, Time) = StringRef(OS.str()).split(' ');
41
42 SmallVector Components;
43 Date.split(Components, '-');
44 ASSERT_EQ(3u, Components.size());
45 EXPECT_EQ(4u, Components[0].size());
46 EXPECT_EQ(2u, Components[1].size());
47 EXPECT_EQ(2u, Components[2].size());
48
49 StringRef Sec, Nano;
50 std::tie(Sec, Nano) = Time.split('.');
51
52 Components.clear();
53 Sec.split(Components, ':');
54 ASSERT_EQ(3u, Components.size());
55 EXPECT_EQ(2u, Components[0].size());
56 EXPECT_EQ(2u, Components[1].size());
57 EXPECT_EQ(2u, Components[2].size());
58 EXPECT_EQ(9u, Nano.size());
59 }
60
61 // Test that toTimePoint and toTimeT can be called with a arguments with varying
62 // precisions.
63 TEST(Chrono, ImplicitConversions) {
64 std::time_t TimeT = 47;
65 TimePoint Sec = toTimePoint(TimeT);
66 TimePoint Milli = toTimePoint(TimeT);
67 TimePoint Micro = toTimePoint(TimeT);
68 TimePoint Nano = toTimePoint(TimeT);
69 EXPECT_EQ(Sec, Milli);
70 EXPECT_EQ(Sec, Micro);
71 EXPECT_EQ(Sec, Nano);
72 EXPECT_EQ(TimeT, toTimeT(Sec));
73 EXPECT_EQ(TimeT, toTimeT(Milli));
74 EXPECT_EQ(TimeT, toTimeT(Micro));
75 EXPECT_EQ(TimeT, toTimeT(Nano));
76 }
77
78 } // anonymous namespace
3636 EXPECT_EQ(ft1970, epoch.toWin32Time());
3737 }
3838
39 TEST(TimeValue, Chrono) {
40 sys::TimeValue TV;
41 TV.fromEpochTime(0);
42 sys::TimePoint<> TP = TV;
43 EXPECT_EQ(0u, sys::toTimeT(TP));
44
45 TP += std::chrono::seconds(47);
46 TV = TP;
47 EXPECT_EQ(47u, TV.toEpochTime());
3948 }
49 }