// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // `Time` represents an absolute point in coordinated universal time (UTC), // internally represented as microseconds (s/1,000,000) since the Windows epoch // (1601-01-01 00:00:00 UTC). System-dependent clock interface routines are // defined in time_PLATFORM.cc. Note that values for `Time` may skew and jump // around as the operating system makes adjustments to synchronize (e.g., with // NTP servers). Thus, client code that uses the `Time` class must account for // this. // // `TimeDelta` represents a duration of time, internally represented in // microseconds. // // `TimeTicks` and `ThreadTicks` represent an abstract time that is most of the // time incrementing, for use in measuring time durations. Internally, they are // represented in microseconds. They cannot be converted to a human-readable // time, but are guaranteed not to decrease (unlike the `Time` class). Note // that `TimeTicks` may "stand still" (e.g., if the computer is suspended), and // `ThreadTicks` will "stand still" whenever the thread has been de-scheduled // by the operating system. // // All time classes are copyable, assignable, and occupy 64 bits per instance. // Prefer to pass them by value, e.g.: // // void MyFunction(TimeDelta arg); // // All time classes support `operator<<` with logging streams, e.g. `LOG(INFO)`. // For human-readable formatting, use //base/i18n/time_formatting.h. // // Example use cases for different time classes: // // Time: Interpreting the wall-clock time provided by a remote system. // Detecting whether cached resources have expired. Providing the // user with a display of the current date and time. Determining // the amount of time between events across re-boots of the // machine. // // TimeTicks: Tracking the amount of time a task runs. Executing delayed // tasks at the right time. Computing presentation timestamps. // Synchronizing audio and video using TimeTicks as a common // reference clock (lip-sync). Measuring network round-trip // latency. // // ThreadTicks: Benchmarking how long the current thread has been doing actual // work. // // Serialization: // // Use the helpers in //base/json/values_util.h when serializing `Time` // or `TimeDelta` to/from `base::Value`. // // Otherwise: // // - Time: use `FromDeltaSinceWindowsEpoch()`/`ToDeltaSinceWindowsEpoch()`. // - TimeDelta: use `base::Microseconds()`/`InMicroseconds()`. // // `TimeTicks` and `ThreadTicks` do not have a stable origin; serialization for // the purpose of persistence is not supported. #ifndef BASE_TIME_TIME_H_ #define BASE_TIME_TIME_H_ #include <stdint.h> #include <time.h> #include <compare> #include <concepts> #include <iosfwd> #include <limits> #include <ostream> #include <type_traits> #include "base/base_export.h" #include "base/check.h" #include "base/check_op.h" #include "base/compiler_specific.h" #include "base/numerics/clamped_math.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #if BUILDFLAG(IS_FUCHSIA) #include <zircon/types.h> #endif #if BUILDFLAG(IS_APPLE) #include <CoreFoundation/CoreFoundation.h> #include <mach/mach_time.h> // Avoid Mac system header macro leak. #undef TYPE_BOOL #endif #if BUILDFLAG(IS_ANDROID) #include <jni.h> #endif #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) #include <unistd.h> #include <sys/time.h> #endif #if BUILDFLAG(IS_WIN) #include "base/gtest_prod_util.h" #include "base/win/windows_types.h" namespace ABI { namespace Windows { namespace Foundation { struct DateTime; struct TimeSpan; } // namespace Foundation } // namespace Windows } // namespace ABI #endif namespace base { #if BUILDFLAG(IS_WIN) class PlatformThreadHandle; #endif class TimeDelta; template <typename T> constexpr TimeDelta Microseconds(T n); namespace { // TODO: Replace usage of this with std::isnan() once Chromium uses C++23, // where that is constexpr. constexpr bool isnan(double d) { … } } // TimeDelta ------------------------------------------------------------------ class BASE_EXPORT TimeDelta { … }; constexpr TimeDelta TimeDelta::operator+(TimeDelta other) const { … } constexpr TimeDelta TimeDelta::operator-(TimeDelta other) const { … } template <typename T> constexpr TimeDelta operator*(T a, TimeDelta td) { … } // For logging use only. BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta); // TimeBase-------------------------------------------------------------------- // Do not reference the time_internal::TimeBase template class directly. Please // use one of the time subclasses instead, and only reference the public // TimeBase members via those classes. namespace time_internal { // Provides value storage and comparison/math operations common to all time // classes. Each subclass provides for strong type-checking to ensure // semantically meaningful comparison/math of time values from the same clock // source or timeline. template<class TimeClass> class TimeBase { … }; #if BUILDFLAG(IS_WIN) #if defined(ARCH_CPU_ARM64) // TSCTicksPerSecond is not supported on Windows on Arm systems because the // cycle-counting methods use the actual CPU cycle count, and not a consistent // incrementing counter. #else // Returns true if the CPU support constant rate TSC. [[nodiscard]] BASE_EXPORT bool HasConstantRateTSC(); // Returns the frequency of the TSC in ticks per second, or 0 if it hasn't // been measured yet. Needs to be guarded with a call to HasConstantRateTSC(). [[nodiscard]] BASE_EXPORT double TSCTicksPerSecond(); #endif #endif // BUILDFLAG(IS_WIN) } // namespace time_internal template <class TimeClass> inline constexpr TimeClass operator+(TimeDelta delta, TimeClass t) { … } // Time ----------------------------------------------------------------------- // Represents a wall clock time in UTC. Values are not guaranteed to be // monotonically non-decreasing and are subject to large amounts of skew. // Time is stored internally as microseconds since the Windows epoch (1601). class BASE_EXPORT Time : public time_internal::TimeBase<Time> { … }; // Factory methods that return a TimeDelta of the given unit. // WARNING: Floating point arithmetic is such that XXX(t.InXXXF()) may not // precisely equal |t|. Hence, floating point values should not be used for // storage. template <typename T> constexpr TimeDelta Days(T n) { … } template <typename T> constexpr TimeDelta Hours(T n) { … } template <typename T> constexpr TimeDelta Minutes(T n) { … } template <typename T> constexpr TimeDelta Seconds(T n) { … } template <typename T> constexpr TimeDelta Milliseconds(T n) { … } template <typename T> constexpr TimeDelta Microseconds(T n) { … } template <typename T> constexpr TimeDelta Nanoseconds(T n) { … } template <typename T> constexpr TimeDelta Hertz(T n) { … } // TimeDelta functions that must appear below the declarations of Time/TimeDelta constexpr double TimeDelta::ToHz() const { … } constexpr int TimeDelta::InDays() const { … } constexpr int TimeDelta::InDaysFloored() const { … } constexpr int TimeDelta::InHours() const { … } constexpr int TimeDelta::InMinutes() const { … } constexpr double TimeDelta::InSecondsF() const { … } constexpr int64_t TimeDelta::InSeconds() const { … } constexpr int64_t TimeDelta::InSecondsFloored() const { … } constexpr double TimeDelta::InMillisecondsF() const { … } constexpr int64_t TimeDelta::InMilliseconds() const { … } constexpr int64_t TimeDelta::InMillisecondsRoundedUp() const { … } constexpr double TimeDelta::InMicrosecondsF() const { … } constexpr int64_t TimeDelta::InNanoseconds() const { … } // static constexpr TimeDelta TimeDelta::Max() { … } // static constexpr TimeDelta TimeDelta::Min() { … } // static constexpr TimeDelta TimeDelta::FiniteMax() { … } // static constexpr TimeDelta TimeDelta::FiniteMin() { … } // TimeBase functions that must appear below the declarations of Time/TimeDelta namespace time_internal { template <class TimeClass> constexpr TimeDelta TimeBase<TimeClass>::since_origin() const { … } template <class TimeClass> constexpr TimeDelta TimeBase<TimeClass>::operator-( const TimeBase<TimeClass>& other) const { … } template <class TimeClass> constexpr TimeClass TimeBase<TimeClass>::operator+(TimeDelta delta) const { … } template <class TimeClass> constexpr TimeClass TimeBase<TimeClass>::operator-(TimeDelta delta) const { … } } // namespace time_internal // Time functions that must appear below the declarations of Time/TimeDelta // static constexpr Time Time::FromTimeT(time_t tt) { … } constexpr time_t Time::ToTimeT() const { … } // static constexpr Time Time::FromSecondsSinceUnixEpoch(double dt) { … } constexpr double Time::InSecondsFSinceUnixEpoch() const { … } #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) // static constexpr Time Time::FromTimeSpec(const timespec& ts) { … } #endif // static constexpr Time Time::FromMillisecondsSinceUnixEpoch(int64_t dt) { … } // static constexpr Time Time::FromMillisecondsSinceUnixEpoch(double dt) { … } constexpr int64_t Time::InMillisecondsSinceUnixEpoch() const { … } constexpr double Time::InMillisecondsFSinceUnixEpoch() const { … } constexpr double Time::InMillisecondsFSinceUnixEpochIgnoringNull() const { … } // For logging use only. BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time); // TimeTicks ------------------------------------------------------------------ // Represents monotonically non-decreasing clock time. class BASE_EXPORT TimeTicks : public time_internal::TimeBase<TimeTicks> { … }; // For logging use only. BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks); // LiveTicks ------------------------------------------------------------------ // Behaves similarly to `TimeTicks` (a monotonically non-decreasing clock time) // with the main difference being that `LiveTicks` is guaranteed not to advance // while the system is suspended. class BASE_EXPORT LiveTicks : public time_internal::TimeBase<LiveTicks> { … }; // For logging use only. BASE_EXPORT std::ostream& operator<<(std::ostream& os, LiveTicks live_ticks); // ThreadTicks ---------------------------------------------------------------- // Represents a thread-specific clock that runs only while the thread is // scheduled. This has the effect of counting time spent actually executing // code, but not time spent blocked (e.g. on I/O), or ready and waiting to be // run. // // Note: This is typically significantly more expensive than TimeTicks. For // instance, on Linux-based systems, it requires a true system call, whereas // TimeTicks::Now() calls are usually handled through the vDSO. This does not // matter if a couple us of overhead is not important to you, but do not call // this in a tight loop, or for sub-microsecond intervals. // // For instance, in 2024 on a Linux system, in a simple loop: // - TimeTicks::Now() takes 27ns per loop iteration // - ThreadTicks::Now() takes 875ns per loop iteration. Actual cost is likely // higher in Chromium due to the sandbox (seccomp-BPF). class BASE_EXPORT ThreadTicks : public time_internal::TimeBase<ThreadTicks> { … }; // For logging use only. BASE_EXPORT std::ostream& operator<<(std::ostream& os, ThreadTicks time_ticks); } // namespace base #endif // BASE_TIME_TIME_H_