Skip to content

Commit a742c2f

Browse files
committed
Dump std::chrono and use timespec_get instead
With commit, some functions seem to be very close to each other, so some cleanup might be desired.
1 parent c9d0959 commit a742c2f

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

flang/runtime/time-intrinsic.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ double GetCpuTime(preferred_implementation,
107107
using count_t = std::int64_t;
108108
using unsigned_count_t = std::uint64_t;
109109

110+
// POSIX implementation using clock_gettime where available. The clock_gettime
111+
// result is in nanoseconds, which is converted as necessary to
112+
// - deciseconds for kind 1
113+
// - milliseconds for kinds 2, 4
114+
// - nanoseconds for kinds 8, 16
115+
constexpr unsigned_count_t DS_PER_SEC{10u};
116+
constexpr unsigned_count_t MS_PER_SEC{1'000u};
117+
constexpr unsigned_count_t NS_PER_SEC{1'000'000'000u};
118+
110119
// Computes HUGE(INT(0,kind)) as an unsigned integer value.
111120
static constexpr inline unsigned_count_t GetHUGE(int kind) {
112121
if (kind > 8) {
@@ -118,21 +127,29 @@ static constexpr inline unsigned_count_t GetHUGE(int kind) {
118127
// This is the fallback implementation, which should work everywhere.
119128
template <typename Unused = void>
120129
count_t GetSystemClockCount(int kind, fallback_implementation) {
121-
unsigned_count_t timestamp;
122-
timestamp =
123-
std::chrono::high_resolution_clock::now().time_since_epoch().count();
124-
if (timestamp == static_cast<unsigned_count_t>(-1)) {
130+
std::timespec tspec;
131+
132+
if (std::timespec_get(&tspec, TIME_UTC) < 0) {
125133
// Return -HUGE(COUNT) to represent failure.
126134
return -static_cast<count_t>(GetHUGE(kind));
127135
}
128-
// Return the modulus of the unsigned integral count with HUGE(COUNT)+1.
129-
// The result is a signed integer but never negative.
130-
return static_cast<count_t>(timestamp % (GetHUGE(kind) + 1));
136+
137+
// compute the timestamp as seconds plus nanoseconds
138+
const unsigned_count_t huge{GetHUGE(kind)};
139+
unsigned_count_t sec{static_cast<unsigned_count_t>(tspec.tv_sec)};
140+
unsigned_count_t nsec{static_cast<unsigned_count_t>(tspec.tv_nsec)};
141+
if (kind >= 8) {
142+
return (sec * NS_PER_SEC + nsec) % (huge + 1);
143+
} else if (kind >= 2) {
144+
return (sec * MS_PER_SEC + (nsec / (NS_PER_SEC / MS_PER_SEC))) % (huge + 1);
145+
} else { // kind == 1
146+
return (sec * DS_PER_SEC + (nsec / (NS_PER_SEC / DS_PER_SEC))) % (huge + 1);
147+
}
131148
}
132149

133150
template <typename Unused = void>
134151
count_t GetSystemClockCountRate(int kind, fallback_implementation) {
135-
return std::chrono::high_resolution_clock::period::den;
152+
return kind >= 8 ? NS_PER_SEC : kind >= 2 ? MS_PER_SEC : DS_PER_SEC;
136153
}
137154

138155
template <typename Unused = void>
@@ -143,15 +160,6 @@ count_t GetSystemClockCountMax(int kind, fallback_implementation) {
143160
: static_cast<count_t>(maxCount);
144161
}
145162

146-
// POSIX implementation using clock_gettime where available. The clock_gettime
147-
// result is in nanoseconds, which is converted as necessary to
148-
// - deciseconds for kind 1
149-
// - milliseconds for kinds 2, 4
150-
// - nanoseconds for kinds 8, 16
151-
constexpr unsigned_count_t DS_PER_SEC{10u};
152-
constexpr unsigned_count_t MS_PER_SEC{1'000u};
153-
constexpr unsigned_count_t NS_PER_SEC{1'000'000'000u};
154-
155163
#ifdef CLOCKID_ELAPSED_TIME
156164
template <typename T = int, typename U = struct timespec>
157165
count_t GetSystemClockCount(int kind, preferred_implementation,

0 commit comments

Comments
 (0)