chromium/base/time/time.h

// 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_