From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- security/sandbox/chromium/base/time/time.h | 1077 ++++++++++++++++++++++++++++ 1 file changed, 1077 insertions(+) create mode 100644 security/sandbox/chromium/base/time/time.h (limited to 'security/sandbox/chromium/base/time/time.h') diff --git a/security/sandbox/chromium/base/time/time.h b/security/sandbox/chromium/base/time/time.h new file mode 100644 index 0000000000..7214e000f0 --- /dev/null +++ b/security/sandbox/chromium/base/time/time.h @@ -0,0 +1,1077 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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. +// As a result, prefer passing them by value: +// void MyFunction(TimeDelta arg); +// If circumstances require, you may also pass by const reference: +// void MyFunction(const TimeDelta& arg); // Not preferred. +// +// Definitions of operator<< are provided to make these types work with +// DCHECK_EQ() and other log macros. For human-readable formatting, see +// "base/i18n/time_formatting.h". +// +// So many choices! Which time class should you use? Examples: +// +// 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. + +#ifndef BASE_TIME_TIME_H_ +#define BASE_TIME_TIME_H_ + +#include +#include + +#include +#include + +#include "base/base_export.h" +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/numerics/safe_math.h" +#include "build/build_config.h" + +#if defined(OS_FUCHSIA) +#include +#endif + +#if defined(OS_MACOSX) +#include +// Avoid Mac system header macro leak. +#undef TYPE_BOOL +#endif + +#if defined(OS_ANDROID) +#include +#endif + +#if defined(OS_POSIX) || defined(OS_FUCHSIA) +#include +#include +#endif + +#if defined(OS_WIN) +#include "base/gtest_prod_util.h" +#include "base/win/windows_types.h" +#endif + +namespace ABI { +namespace Windows { +namespace Foundation { +struct DateTime; +} // namespace Foundation +} // namespace Windows +} // namespace ABI + +namespace base { + +class PlatformThreadHandle; +class TimeDelta; + +// The functions in the time_internal namespace are meant to be used only by the +// time classes and functions. Please use the math operators defined in the +// time classes instead. +namespace time_internal { + +// Add or subtract a TimeDelta from |value|. TimeDelta::Min()/Max() are treated +// as infinity and will always saturate the return value (infinity math applies +// if |value| also is at either limit of its spectrum). The int64_t argument and +// return value are in terms of a microsecond timebase. +BASE_EXPORT constexpr int64_t SaturatedAdd(int64_t value, TimeDelta delta); +BASE_EXPORT constexpr int64_t SaturatedSub(int64_t value, TimeDelta delta); + +} // namespace time_internal + +// TimeDelta ------------------------------------------------------------------ + +class BASE_EXPORT TimeDelta { + public: + constexpr TimeDelta() : delta_(0) {} + + // Converts units of time to TimeDeltas. + // WARNING: Floating point arithmetic is such that FromXXXD(t.InXXXF()) may + // not precisely equal |t|. Hence, floating point values should not be used + // for storage. + static constexpr TimeDelta FromDays(int days); + static constexpr TimeDelta FromHours(int hours); + static constexpr TimeDelta FromMinutes(int minutes); + static constexpr TimeDelta FromSeconds(int64_t secs); + static constexpr TimeDelta FromMilliseconds(int64_t ms); + static constexpr TimeDelta FromMicroseconds(int64_t us); + static constexpr TimeDelta FromNanoseconds(int64_t ns); + static constexpr TimeDelta FromSecondsD(double secs); + static constexpr TimeDelta FromMillisecondsD(double ms); + static constexpr TimeDelta FromMicrosecondsD(double us); + static constexpr TimeDelta FromNanosecondsD(double ns); +#if defined(OS_WIN) + static TimeDelta FromQPCValue(LONGLONG qpc_value); + // TODO(crbug.com/989694): Avoid base::TimeDelta factory functions + // based on absolute time + static TimeDelta FromFileTime(FILETIME ft); + static TimeDelta FromWinrtDateTime(ABI::Windows::Foundation::DateTime dt); +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) + static TimeDelta FromTimeSpec(const timespec& ts); +#endif +#if defined(OS_FUCHSIA) + static TimeDelta FromZxDuration(zx_duration_t nanos); +#endif + + // Converts an integer value representing TimeDelta to a class. This is used + // when deserializing a |TimeDelta| structure, using a value known to be + // compatible. It is not provided as a constructor because the integer type + // may be unclear from the perspective of a caller. + // + // DEPRECATED - Do not use in new code. http://crbug.com/634507 + static constexpr TimeDelta FromInternalValue(int64_t delta) { + return TimeDelta(delta); + } + + // Returns the maximum time delta, which should be greater than any reasonable + // time delta we might compare it to. Adding or subtracting the maximum time + // delta to a time or another time delta has an undefined result. + static constexpr TimeDelta Max(); + + // Returns the minimum time delta, which should be less than than any + // reasonable time delta we might compare it to. Adding or subtracting the + // minimum time delta to a time or another time delta has an undefined result. + static constexpr TimeDelta Min(); + + // Returns the internal numeric value of the TimeDelta object. Please don't + // use this and do arithmetic on it, as it is more error prone than using the + // provided operators. + // For serializing, use FromInternalValue to reconstitute. + // + // DEPRECATED - Do not use in new code. http://crbug.com/634507 + constexpr int64_t ToInternalValue() const { return delta_; } + + // Returns the magnitude (absolute value) of this TimeDelta. + constexpr TimeDelta magnitude() const { + // Some toolchains provide an incomplete C++11 implementation and lack an + // int64_t overload for std::abs(). The following is a simple branchless + // implementation: + const int64_t mask = delta_ >> (sizeof(delta_) * 8 - 1); + return TimeDelta((delta_ + mask) ^ mask); + } + + // Returns true if the time delta is zero. + constexpr bool is_zero() const { return delta_ == 0; } + + // Returns true if the time delta is the maximum/minimum time delta. + constexpr bool is_max() const { + return delta_ == std::numeric_limits::max(); + } + constexpr bool is_min() const { + return delta_ == std::numeric_limits::min(); + } + +#if defined(OS_POSIX) || defined(OS_FUCHSIA) + struct timespec ToTimeSpec() const; +#endif +#if defined(OS_FUCHSIA) + zx_duration_t ToZxDuration() const; +#endif +#if defined(OS_WIN) + ABI::Windows::Foundation::DateTime ToWinrtDateTime() const; +#endif + + // Returns the time delta in some unit. The InXYZF versions return a floating + // point value. The InXYZ versions return a truncated value (aka rounded + // towards zero, std::trunc() behavior). The InXYZFloored() versions round to + // lesser integers (std::floor() behavior). The XYZRoundedUp() versions round + // up to greater integers (std::ceil() behavior). + // WARNING: Floating point arithmetic is such that FromXXXD(t.InXXXF()) may + // not precisely equal |t|. Hence, floating point values should not be used + // for storage. + int InDays() const; + int InDaysFloored() const; + int InHours() const; + int InMinutes() const; + double InSecondsF() const; + int64_t InSeconds() const; + double InMillisecondsF() const; + int64_t InMilliseconds() const; + int64_t InMillisecondsRoundedUp() const; + constexpr int64_t InMicroseconds() const { return delta_; } + double InMicrosecondsF() const; + int64_t InNanoseconds() const; + + // Computations with other deltas. + constexpr TimeDelta operator+(TimeDelta other) const { + return TimeDelta(time_internal::SaturatedAdd(delta_, other)); + } + constexpr TimeDelta operator-(TimeDelta other) const { + return TimeDelta(time_internal::SaturatedSub(delta_, other)); + } + + constexpr TimeDelta& operator+=(TimeDelta other) { + return *this = (*this + other); + } + constexpr TimeDelta& operator-=(TimeDelta other) { + return *this = (*this - other); + } + constexpr TimeDelta operator-() const { return TimeDelta(-delta_); } + + // Computations with numeric types. + template + constexpr TimeDelta operator*(T a) const { + CheckedNumeric rv(delta_); + rv *= a; + if (rv.IsValid()) + return TimeDelta(rv.ValueOrDie()); + // Matched sign overflows. Mismatched sign underflows. + if ((delta_ < 0) ^ (a < 0)) + return TimeDelta(std::numeric_limits::min()); + return TimeDelta(std::numeric_limits::max()); + } + template + constexpr TimeDelta operator/(T a) const { + CheckedNumeric rv(delta_); + rv /= a; + if (rv.IsValid()) + return TimeDelta(rv.ValueOrDie()); + // Matched sign overflows. Mismatched sign underflows. + // Special case to catch divide by zero. + if ((delta_ < 0) ^ (a <= 0)) + return TimeDelta(std::numeric_limits::min()); + return TimeDelta(std::numeric_limits::max()); + } + template + constexpr TimeDelta& operator*=(T a) { + return *this = (*this * a); + } + template + constexpr TimeDelta& operator/=(T a) { + return *this = (*this / a); + } + + constexpr int64_t operator/(TimeDelta a) const { return delta_ / a.delta_; } + + constexpr TimeDelta operator%(TimeDelta a) const { + return TimeDelta(delta_ % a.delta_); + } + TimeDelta& operator%=(TimeDelta other) { return *this = (*this % other); } + + // Comparison operators. + constexpr bool operator==(TimeDelta other) const { + return delta_ == other.delta_; + } + constexpr bool operator!=(TimeDelta other) const { + return delta_ != other.delta_; + } + constexpr bool operator<(TimeDelta other) const { + return delta_ < other.delta_; + } + constexpr bool operator<=(TimeDelta other) const { + return delta_ <= other.delta_; + } + constexpr bool operator>(TimeDelta other) const { + return delta_ > other.delta_; + } + constexpr bool operator>=(TimeDelta other) const { + return delta_ >= other.delta_; + } + + private: + friend constexpr int64_t time_internal::SaturatedAdd(int64_t value, + TimeDelta delta); + friend constexpr int64_t time_internal::SaturatedSub(int64_t value, + TimeDelta delta); + + // Constructs a delta given the duration in microseconds. This is private + // to avoid confusion by callers with an integer constructor. Use + // FromSeconds, FromMilliseconds, etc. instead. + constexpr explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {} + + // Private method to build a delta from a double. + static constexpr TimeDelta FromDouble(double value); + + // Private method to build a delta from the product of a user-provided value + // and a known-positive value. + static constexpr TimeDelta FromProduct(int64_t value, int64_t positive_value); + + // Delta in microseconds. + int64_t delta_; +}; + +template +constexpr TimeDelta operator*(T a, TimeDelta td) { + return td * a; +} + +// For logging use only. +BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta); + +// 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 { + +constexpr int64_t SaturatedAdd(int64_t value, TimeDelta delta) { + // Treat Min/Max() as +/- infinity (additions involving two infinities are + // only valid if signs match). + if (delta.is_max()) { + CHECK_GT(value, std::numeric_limits::min()); + return std::numeric_limits::max(); + } else if (delta.is_min()) { + CHECK_LT(value, std::numeric_limits::max()); + return std::numeric_limits::min(); + } + + return base::ClampAdd(value, delta.delta_); +} + +constexpr int64_t SaturatedSub(int64_t value, TimeDelta delta) { + // Treat Min/Max() as +/- infinity (subtractions involving two infinities are + // only valid if signs are opposite). + if (delta.is_max()) { + CHECK_LT(value, std::numeric_limits::max()); + return std::numeric_limits::min(); + } else if (delta.is_min()) { + CHECK_GT(value, std::numeric_limits::min()); + return std::numeric_limits::max(); + } + + return base::ClampSub(value, delta.delta_); +} + +// TimeBase-------------------------------------------------------------------- + +// 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 TimeBase { + public: + static constexpr int64_t kHoursPerDay = 24; + static constexpr int64_t kSecondsPerMinute = 60; + static constexpr int64_t kSecondsPerHour = 60 * kSecondsPerMinute; + static constexpr int64_t kMillisecondsPerSecond = 1000; + static constexpr int64_t kMillisecondsPerDay = + kMillisecondsPerSecond * 60 * 60 * kHoursPerDay; + static constexpr int64_t kMicrosecondsPerMillisecond = 1000; + static constexpr int64_t kMicrosecondsPerSecond = + kMicrosecondsPerMillisecond * kMillisecondsPerSecond; + static constexpr int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60; + static constexpr int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60; + static constexpr int64_t kMicrosecondsPerDay = + kMicrosecondsPerHour * kHoursPerDay; + static constexpr int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7; + static constexpr int64_t kNanosecondsPerMicrosecond = 1000; + static constexpr int64_t kNanosecondsPerSecond = + kNanosecondsPerMicrosecond * kMicrosecondsPerSecond; + + // Returns true if this object has not been initialized. + // + // Warning: Be careful when writing code that performs math on time values, + // since it's possible to produce a valid "zero" result that should not be + // interpreted as a "null" value. + constexpr bool is_null() const { return us_ == 0; } + + // Returns true if this object represents the maximum/minimum time. + constexpr bool is_max() const { + return us_ == std::numeric_limits::max(); + } + constexpr bool is_min() const { + return us_ == std::numeric_limits::min(); + } + + // Returns the maximum/minimum times, which should be greater/less than than + // any reasonable time with which we might compare it. + static constexpr TimeClass Max() { + return TimeClass(std::numeric_limits::max()); + } + + static constexpr TimeClass Min() { + return TimeClass(std::numeric_limits::min()); + } + + // For serializing only. Use FromInternalValue() to reconstitute. Please don't + // use this and do arithmetic on it, as it is more error prone than using the + // provided operators. + // + // DEPRECATED - Do not use in new code. For serializing Time values, prefer + // Time::ToDeltaSinceWindowsEpoch().InMicroseconds(). http://crbug.com/634507 + constexpr int64_t ToInternalValue() const { return us_; } + + // The amount of time since the origin (or "zero") point. This is a syntactic + // convenience to aid in code readability, mainly for debugging/testing use + // cases. + // + // Warning: While the Time subclass has a fixed origin point, the origin for + // the other subclasses can vary each time the application is restarted. + constexpr TimeDelta since_origin() const { + return TimeDelta::FromMicroseconds(us_); + } + + constexpr TimeClass& operator=(TimeClass other) { + us_ = other.us_; + return *(static_cast(this)); + } + + // Compute the difference between two times. + constexpr TimeDelta operator-(TimeClass other) const { + return TimeDelta::FromMicroseconds(us_ - other.us_); + } + + // Return a new time modified by some delta. + constexpr TimeClass operator+(TimeDelta delta) const { + return TimeClass(time_internal::SaturatedAdd(us_, delta)); + } + constexpr TimeClass operator-(TimeDelta delta) const { + return TimeClass(time_internal::SaturatedSub(us_, delta)); + } + + // Modify by some time delta. + constexpr TimeClass& operator+=(TimeDelta delta) { + return static_cast(*this = (*this + delta)); + } + constexpr TimeClass& operator-=(TimeDelta delta) { + return static_cast(*this = (*this - delta)); + } + + // Comparison operators + constexpr bool operator==(TimeClass other) const { return us_ == other.us_; } + constexpr bool operator!=(TimeClass other) const { return us_ != other.us_; } + constexpr bool operator<(TimeClass other) const { return us_ < other.us_; } + constexpr bool operator<=(TimeClass other) const { return us_ <= other.us_; } + constexpr bool operator>(TimeClass other) const { return us_ > other.us_; } + constexpr bool operator>=(TimeClass other) const { return us_ >= other.us_; } + + protected: + constexpr explicit TimeBase(int64_t us) : us_(us) {} + + // Time value in a microsecond timebase. + int64_t us_; +}; + +} // namespace time_internal + +template +inline constexpr TimeClass operator+(TimeDelta delta, TimeClass t) { + return t + delta; +} + +// 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