// 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 PARTITION_ALLOC_PARTITION_ALLOC_BASE_TIME_TIME_H_ #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_TIME_TIME_H_ #include <cstdint> #include <ctime> #include <iosfwd> #include <limits> #include "partition_alloc/build_config.h" #include "partition_alloc/partition_alloc_base/check.h" #include "partition_alloc/partition_alloc_base/component_export.h" #include "partition_alloc/partition_alloc_base/numerics/clamped_math.h" #if PA_BUILDFLAG(IS_APPLE) #include "partition_alloc/buildflags.h" #endif // PA_BUILDFLAG(IS_APPLE) #if PA_BUILDFLAG(IS_FUCHSIA) #include <zircon/types.h> #endif #if PA_BUILDFLAG(IS_APPLE) #include <CoreFoundation/CoreFoundation.h> #include <mach/mach_time.h> // Avoid Mac system header macro leak. #undef TYPE_BOOL #endif #if PA_BUILDFLAG(IS_ANDROID) #include <jni.h> #endif #if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA) #include <sys/time.h> #include <unistd.h> #endif #if PA_BUILDFLAG(IS_WIN) #include "partition_alloc/partition_alloc_base/win/windows_types.h" namespace ABI { namespace Windows { namespace Foundation { struct DateTime; } // namespace Foundation } // namespace Windows } // namespace ABI #endif namespace partition_alloc::internal::base { class TimeDelta; template <typename T> constexpr TimeDelta Microseconds(T n); #if PA_BUILDFLAG(IS_WIN) class PlatformThreadHandle; #endif // TimeDelta ------------------------------------------------------------------ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 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) { … } // 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 PA_BUILDFLAG(IS_WIN) #if PA_BUILDFLAG(PA_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]] PA_COMPONENT_EXPORT( PARTITION_ALLOC_BASE) 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]] PA_COMPONENT_EXPORT( PARTITION_ALLOC_BASE) double TSCTicksPerSecond(); #endif #endif // PA_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 PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) 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::InHours() const { … } constexpr int TimeDelta::InMinutes() const { … } constexpr double TimeDelta::InSecondsF() const { … } constexpr int64_t TimeDelta::InSeconds() 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) { … } // TimeTicks ------------------------------------------------------------------ // Represents monotonically non-decreasing clock time. class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) TimeTicks : public time_internal::TimeBase<TimeTicks> { … }; // ThreadTicks ---------------------------------------------------------------- // Represents a clock, specific to a particular thread, than runs only while the // thread is running. class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ThreadTicks : public time_internal::TimeBase<ThreadTicks> { … }; } // namespace partition_alloc::internal::base #endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_TIME_TIME_H_