@@ -107,6 +107,15 @@ double GetCpuTime(preferred_implementation,
107
107
using count_t = std::int64_t ;
108
108
using unsigned_count_t = std::uint64_t ;
109
109
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
+
110
119
// Computes HUGE(INT(0,kind)) as an unsigned integer value.
111
120
static constexpr inline unsigned_count_t GetHUGE (int kind) {
112
121
if (kind > 8 ) {
@@ -118,21 +127,29 @@ static constexpr inline unsigned_count_t GetHUGE(int kind) {
118
127
// This is the fallback implementation, which should work everywhere.
119
128
template <typename Unused = void >
120
129
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 ) {
125
133
// Return -HUGE(COUNT) to represent failure.
126
134
return -static_cast <count_t >(GetHUGE (kind));
127
135
}
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
+ }
131
148
}
132
149
133
150
template <typename Unused = void >
134
151
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 ;
136
153
}
137
154
138
155
template <typename Unused = void >
@@ -143,15 +160,6 @@ count_t GetSystemClockCountMax(int kind, fallback_implementation) {
143
160
: static_cast <count_t >(maxCount);
144
161
}
145
162
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
-
155
163
#ifdef CLOCKID_ELAPSED_TIME
156
164
template <typename T = int , typename U = struct timespec >
157
165
count_t GetSystemClockCount (int kind, preferred_implementation,
0 commit comments