15 #include "absl/time/clock.h"
17 #include "absl/base/attributes.h"
18 #include "absl/base/optimization.h"
31 #include "absl/base/internal/spinlock.h"
32 #include "absl/base/internal/unscaledcycleclock.h"
33 #include "absl/base/macros.h"
34 #include "absl/base/port.h"
35 #include "absl/base/thread_annotations.h"
55 #ifndef ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
56 #if ABSL_USE_UNSCALED_CYCLECLOCK
57 #define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 1
59 #define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 0
63 #if defined(__APPLE__) || defined(_WIN32)
64 #include "absl/time/internal/get_current_time_chrono.inc"
66 #include "absl/time/internal/get_current_time_posix.inc"
70 #ifndef GET_CURRENT_TIME_NANOS_FROM_SYSTEM
71 #define GET_CURRENT_TIME_NANOS_FROM_SYSTEM() \
72 ::absl::time_internal::GetCurrentTimeNanosFromSystem()
75 #if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
81 #else // Use the cyclecounter-based implementation below.
84 #ifndef GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW
85 #define GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW() \
86 ::absl::time_internal::UnscaledCycleClockWrapperForGetCurrentTime::Now()
91 namespace time_internal {
94 class UnscaledCycleClockWrapperForGetCurrentTime {
115 static inline uint64_t SeqAcquire(std::atomic<uint64_t> *seq) {
116 uint64_t x = seq->fetch_add(1, std::memory_order_relaxed);
123 std::atomic_thread_fence(std::memory_order_release);
130 static inline void SeqRelease(std::atomic<uint64_t> *seq,
uint64_t x) {
133 seq->store(x, std::memory_order_release);
139 enum { kScale = 30 };
145 static const uint64_t kMinNSBetweenSamples = 2000 << 20;
149 static_assert(((kMinNSBetweenSamples << (kScale + 1)) >> (kScale + 1)) ==
150 kMinNSBetweenSamples,
151 "cannot represent kMaxBetweenSamplesNSScaled");
154 struct TimeSampleAtomic {
155 std::atomic<uint64_t> raw_ns{0};
156 std::atomic<uint64_t> base_ns{0};
157 std::atomic<uint64_t> base_cycles{0};
158 std::atomic<uint64_t> nsscaled_per_cycle{0};
161 std::atomic<uint64_t> min_cycles_per_sample{0};
173 std::atomic<uint64_t> seq{0};
174 TimeSampleAtomic last_sample;
177 int64_t stats_initializations{0};
178 int64_t stats_reinitializations{0};
181 int64_t stats_fast_slow_paths{0};
189 std::atomic<uint64_t> approx_syscall_time_in_cycles{10 * 1000};
192 std::atomic<uint32_t> kernel_time_seen_smaller{0};
211 uint64_t local_approx_syscall_time_in_cycles =
212 time_state.approx_syscall_time_in_cycles.load(std::memory_order_relaxed);
214 int64_t current_time_nanos_from_system;
220 before_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW();
222 after_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW();
224 elapsed_cycles = after_cycles - before_cycles;
225 if (elapsed_cycles >= local_approx_syscall_time_in_cycles &&
228 if (local_approx_syscall_time_in_cycles < 1000 * 1000) {
229 local_approx_syscall_time_in_cycles =
230 (local_approx_syscall_time_in_cycles + 1) << 1;
232 time_state.approx_syscall_time_in_cycles.store(
233 local_approx_syscall_time_in_cycles, std::memory_order_relaxed);
235 }
while (elapsed_cycles >= local_approx_syscall_time_in_cycles ||
236 last_cycleclock - after_cycles < (
static_cast<uint64_t>(1) << 16));
240 if ((local_approx_syscall_time_in_cycles >> 1) < elapsed_cycles) {
242 time_state.kernel_time_seen_smaller.store(0, std::memory_order_relaxed);
243 }
else if (time_state.kernel_time_seen_smaller.fetch_add(
244 1, std::memory_order_relaxed) >= 3) {
247 local_approx_syscall_time_in_cycles -
248 (local_approx_syscall_time_in_cycles >> 3);
249 time_state.approx_syscall_time_in_cycles.store(new_approximation,
250 std::memory_order_relaxed);
251 time_state.kernel_time_seen_smaller.store(0, std::memory_order_relaxed);
254 *cycleclock = after_cycles;
255 return current_time_nanos_from_system;
263 static
void ReadTimeSampleAtomic(
const struct TimeSampleAtomic *atomic,
264 struct TimeSample *sample) {
265 sample->base_ns = atomic->base_ns.load(std::memory_order_relaxed);
266 sample->base_cycles = atomic->base_cycles.load(std::memory_order_relaxed);
267 sample->nsscaled_per_cycle =
268 atomic->nsscaled_per_cycle.load(std::memory_order_relaxed);
269 sample->min_cycles_per_sample =
270 atomic->min_cycles_per_sample.load(std::memory_order_relaxed);
271 sample->raw_ns = atomic->raw_ns.load(std::memory_order_relaxed);
319 uint64_t now_cycles = GET_CURRENT_TIME_NANOS_CYCLECLOCK_NOW();
324 seq_read0 = time_state.seq.load(std::memory_order_acquire);
326 base_ns = time_state.last_sample.base_ns.load(std::memory_order_relaxed);
328 time_state.last_sample.base_cycles.load(std::memory_order_relaxed);
330 time_state.last_sample.nsscaled_per_cycle.load(std::memory_order_relaxed);
331 min_cycles_per_sample = time_state.last_sample.min_cycles_per_sample.load(
332 std::memory_order_relaxed);
337 std::atomic_thread_fence(std::memory_order_acquire);
343 seq_read1 = time_state.seq.load(std::memory_order_relaxed);
357 if (seq_read0 == seq_read1 && (seq_read0 & 1) == 0 &&
358 (delta_cycles = now_cycles - base_cycles) < min_cycles_per_sample) {
359 return base_ns + ((delta_cycles * nsscaled_per_cycle) >> kScale);
361 return GetCurrentTimeNanosSlowPath();
370 int safe_shift = kScale;
371 while (((a << safe_shift) >> safe_shift) != a) {
374 uint64_t scaled_b =
b >> (kScale - safe_shift);
377 quotient = (
a << safe_shift) / scaled_b;
398 static int64_t GetCurrentTimeNanosSlowPath()
402 time_state.lock.Lock();
408 GetCurrentTimeNanosFromKernel(time_state.last_now_cycles, &now_cycles);
409 time_state.last_now_cycles = now_cycles;
415 struct TimeSample sample;
416 ReadTimeSampleAtomic(&time_state.last_sample, &sample);
421 uint64_t delta_cycles = now_cycles - sample.base_cycles;
422 if (delta_cycles < sample.min_cycles_per_sample) {
425 estimated_base_ns = sample.base_ns +
426 ((delta_cycles * sample.nsscaled_per_cycle) >> kScale);
427 time_state.stats_fast_slow_paths++;
430 UpdateLastSample(now_cycles, now_ns, delta_cycles, &sample);
433 time_state.lock.Unlock();
435 return estimated_base_ns;
443 const struct TimeSample *sample)
445 uint64_t estimated_base_ns = now_ns;
447 SeqAcquire(&time_state.seq);
453 if (sample->raw_ns == 0 ||
454 sample->raw_ns +
static_cast<uint64_t>(5) * 1000 * 1000 * 1000 < now_ns ||
455 now_ns < sample->raw_ns || now_cycles < sample->base_cycles) {
457 time_state.last_sample.raw_ns.store(now_ns, std::memory_order_relaxed);
458 time_state.last_sample.base_ns.store(estimated_base_ns,
459 std::memory_order_relaxed);
460 time_state.last_sample.base_cycles.store(now_cycles,
461 std::memory_order_relaxed);
462 time_state.last_sample.nsscaled_per_cycle.store(0,
463 std::memory_order_relaxed);
464 time_state.last_sample.min_cycles_per_sample.store(
465 0, std::memory_order_relaxed);
466 time_state.stats_initializations++;
467 }
else if (sample->raw_ns + 500 * 1000 * 1000 < now_ns &&
468 sample->base_cycles + 50 < now_cycles) {
470 if (sample->nsscaled_per_cycle != 0) {
477 estimated_scaled_ns = (delta_cycles >>
s) * sample->nsscaled_per_cycle;
478 }
while (estimated_scaled_ns / sample->nsscaled_per_cycle !=
479 (delta_cycles >> s));
480 estimated_base_ns = sample->base_ns +
481 (estimated_scaled_ns >> (kScale -
s));
487 uint64_t measured_nsscaled_per_cycle = SafeDivideAndScale(
ns, delta_cycles);
489 uint64_t assumed_next_sample_delta_cycles =
490 SafeDivideAndScale(kMinNSBetweenSamples, measured_nsscaled_per_cycle);
492 int64_t diff_ns = now_ns - estimated_base_ns;
503 ns = kMinNSBetweenSamples + diff_ns - (diff_ns / 16);
505 SafeDivideAndScale(
ns, assumed_next_sample_delta_cycles);
506 if (new_nsscaled_per_cycle != 0 &&
507 diff_ns < 100 * 1000 * 1000 && -diff_ns < 100 * 1000 * 1000) {
509 time_state.last_sample.nsscaled_per_cycle.store(
510 new_nsscaled_per_cycle, std::memory_order_relaxed);
511 uint64_t new_min_cycles_per_sample =
512 SafeDivideAndScale(kMinNSBetweenSamples, new_nsscaled_per_cycle);
513 time_state.last_sample.min_cycles_per_sample.store(
514 new_min_cycles_per_sample, std::memory_order_relaxed);
515 time_state.stats_calibrations++;
517 time_state.last_sample.nsscaled_per_cycle.store(
518 0, std::memory_order_relaxed);
519 time_state.last_sample.min_cycles_per_sample.store(
520 0, std::memory_order_relaxed);
521 estimated_base_ns = now_ns;
522 time_state.stats_reinitializations++;
524 time_state.last_sample.raw_ns.store(now_ns, std::memory_order_relaxed);
525 time_state.last_sample.base_ns.store(estimated_base_ns,
526 std::memory_order_relaxed);
527 time_state.last_sample.base_cycles.store(now_cycles,
528 std::memory_order_relaxed);
531 time_state.stats_slow_paths++;
534 SeqRelease(&time_state.seq, lock_value);
536 return estimated_base_ns;
540 #endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS
564 while (
nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) {
581 duration -= to_sleep;