diff options
Diffstat (limited to 'security/sandbox/chromium/base/time')
-rw-r--r-- | security/sandbox/chromium/base/time/time.cc | 349 | ||||
-rw-r--r-- | security/sandbox/chromium/base/time/time.h | 768 | ||||
-rw-r--r-- | security/sandbox/chromium/base/time/time_posix.cc | 363 | ||||
-rw-r--r-- | security/sandbox/chromium/base/time/time_win.cc | 616 |
4 files changed, 0 insertions, 2096 deletions
diff --git a/security/sandbox/chromium/base/time/time.cc b/security/sandbox/chromium/base/time/time.cc deleted file mode 100644 index 9188887e2..000000000 --- a/security/sandbox/chromium/base/time/time.cc +++ /dev/null @@ -1,349 +0,0 @@ -// 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. - -#include "base/time/time.h" - -#include <cmath> -#include <ios> -#include <limits> -#include <ostream> -#include <sstream> - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/stringprintf.h" -#include "base/third_party/nspr/prtime.h" -#include "build/build_config.h" - -namespace base { - -// TimeDelta ------------------------------------------------------------------ - -// static -TimeDelta TimeDelta::Max() { - return TimeDelta(std::numeric_limits<int64_t>::max()); -} - -int TimeDelta::InDays() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int>::max(); - } - return static_cast<int>(delta_ / Time::kMicrosecondsPerDay); -} - -int TimeDelta::InHours() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int>::max(); - } - return static_cast<int>(delta_ / Time::kMicrosecondsPerHour); -} - -int TimeDelta::InMinutes() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int>::max(); - } - return static_cast<int>(delta_ / Time::kMicrosecondsPerMinute); -} - -double TimeDelta::InSecondsF() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond; -} - -int64_t TimeDelta::InSeconds() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return delta_ / Time::kMicrosecondsPerSecond; -} - -double TimeDelta::InMillisecondsF() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond; -} - -int64_t TimeDelta::InMilliseconds() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return delta_ / Time::kMicrosecondsPerMillisecond; -} - -int64_t TimeDelta::InMillisecondsRoundedUp() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return (delta_ + Time::kMicrosecondsPerMillisecond - 1) / - Time::kMicrosecondsPerMillisecond; -} - -int64_t TimeDelta::InMicroseconds() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return delta_; -} - -namespace time_internal { - -int64_t SaturatedAdd(TimeDelta delta, int64_t value) { - CheckedNumeric<int64_t> rv(delta.delta_); - rv += value; - return FromCheckedNumeric(rv); -} - -int64_t SaturatedSub(TimeDelta delta, int64_t value) { - CheckedNumeric<int64_t> rv(delta.delta_); - rv -= value; - return FromCheckedNumeric(rv); -} - -int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value) { - if (value.IsValid()) - return value.ValueUnsafe(); - - // We could return max/min but we don't really expose what the maximum delta - // is. Instead, return max/(-max), which is something that clients can reason - // about. - // TODO(rvargas) crbug.com/332611: don't use internal values. - int64_t limit = std::numeric_limits<int64_t>::max(); - if (value.validity() == internal::RANGE_UNDERFLOW) - limit = -limit; - return value.ValueOrDefault(limit); -} - -} // namespace time_internal - -std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) { - return os << time_delta.InSecondsF() << "s"; -} - -// Time ----------------------------------------------------------------------- - -// static -Time Time::Max() { - return Time(std::numeric_limits<int64_t>::max()); -} - -// static -Time Time::FromTimeT(time_t tt) { - if (tt == 0) - return Time(); // Preserve 0 so we can tell it doesn't exist. - if (tt == std::numeric_limits<time_t>::max()) - return Max(); - return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSeconds(tt); -} - -time_t Time::ToTimeT() const { - if (is_null()) - return 0; // Preserve 0 so we can tell it doesn't exist. - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<time_t>::max(); - } - if (std::numeric_limits<int64_t>::max() - kTimeTToMicrosecondsOffset <= us_) { - DLOG(WARNING) << "Overflow when converting base::Time with internal " << - "value " << us_ << " to time_t."; - return std::numeric_limits<time_t>::max(); - } - return (us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerSecond; -} - -// static -Time Time::FromDoubleT(double dt) { - if (dt == 0 || std::isnan(dt)) - return Time(); // Preserve 0 so we can tell it doesn't exist. - return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSecondsD(dt); -} - -double Time::ToDoubleT() const { - if (is_null()) - return 0; // Preserve 0 so we can tell it doesn't exist. - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) / - static_cast<double>(kMicrosecondsPerSecond)); -} - -#if defined(OS_POSIX) -// static -Time Time::FromTimeSpec(const timespec& ts) { - return FromDoubleT(ts.tv_sec + - static_cast<double>(ts.tv_nsec) / - base::Time::kNanosecondsPerSecond); -} -#endif - -// static -Time Time::FromJsTime(double ms_since_epoch) { - // The epoch is a valid time, so this constructor doesn't interpret - // 0 as the null time. - return Time(kTimeTToMicrosecondsOffset) + - TimeDelta::FromMillisecondsD(ms_since_epoch); -} - -double Time::ToJsTime() const { - if (is_null()) { - // Preserve 0 so the invalid result doesn't depend on the platform. - return 0; - } - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) / - kMicrosecondsPerMillisecond); -} - -int64_t Time::ToJavaTime() const { - if (is_null()) { - // Preserve 0 so the invalid result doesn't depend on the platform. - return 0; - } - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return ((us_ - kTimeTToMicrosecondsOffset) / - kMicrosecondsPerMillisecond); -} - -// static -Time Time::UnixEpoch() { - Time time; - time.us_ = kTimeTToMicrosecondsOffset; - return time; -} - -Time Time::LocalMidnight() const { - Exploded exploded; - LocalExplode(&exploded); - exploded.hour = 0; - exploded.minute = 0; - exploded.second = 0; - exploded.millisecond = 0; - return FromLocalExploded(exploded); -} - -#if !defined(MOZ_SANDBOX) -// static -bool Time::FromStringInternal(const char* time_string, - bool is_local, - Time* parsed_time) { - DCHECK((time_string != NULL) && (parsed_time != NULL)); - - if (time_string[0] == '\0') - return false; - - PRTime result_time = 0; - PRStatus result = PR_ParseTimeString(time_string, - is_local ? PR_FALSE : PR_TRUE, - &result_time); - if (PR_SUCCESS != result) - return false; - - result_time += kTimeTToMicrosecondsOffset; - *parsed_time = Time(result_time); - return true; -} -#endif - -std::ostream& operator<<(std::ostream& os, Time time) { - Time::Exploded exploded; - time.UTCExplode(&exploded); - // Use StringPrintf because iostreams formatting is painful. - return os << StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%03d UTC", - exploded.year, - exploded.month, - exploded.day_of_month, - exploded.hour, - exploded.minute, - exploded.second, - exploded.millisecond); -} - -// Local helper class to hold the conversion from Time to TickTime at the -// time of the Unix epoch. -class UnixEpochSingleton { - public: - UnixEpochSingleton() - : unix_epoch_(TimeTicks::Now() - (Time::Now() - Time::UnixEpoch())) {} - - TimeTicks unix_epoch() const { return unix_epoch_; } - - private: - const TimeTicks unix_epoch_; - - DISALLOW_COPY_AND_ASSIGN(UnixEpochSingleton); -}; - -static LazyInstance<UnixEpochSingleton>::Leaky - leaky_unix_epoch_singleton_instance = LAZY_INSTANCE_INITIALIZER; - -// Static -TimeTicks TimeTicks::UnixEpoch() { - return leaky_unix_epoch_singleton_instance.Get().unix_epoch(); -} - -TimeTicks TimeTicks::SnappedToNextTick(TimeTicks tick_phase, - TimeDelta tick_interval) const { - // |interval_offset| is the offset from |this| to the next multiple of - // |tick_interval| after |tick_phase|, possibly negative if in the past. - TimeDelta interval_offset = (tick_phase - *this) % tick_interval; - // If |this| is exactly on the interval (i.e. offset==0), don't adjust. - // Otherwise, if |tick_phase| was in the past, adjust forward to the next - // tick after |this|. - if (!interval_offset.is_zero() && tick_phase < *this) - interval_offset += tick_interval; - return *this + interval_offset; -} - -std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks) { - // This function formats a TimeTicks object as "bogo-microseconds". - // The origin and granularity of the count are platform-specific, and may very - // from run to run. Although bogo-microseconds usually roughly correspond to - // real microseconds, the only real guarantee is that the number never goes - // down during a single run. - const TimeDelta as_time_delta = time_ticks - TimeTicks(); - return os << as_time_delta.InMicroseconds() << " bogo-microseconds"; -} - -std::ostream& operator<<(std::ostream& os, ThreadTicks thread_ticks) { - const TimeDelta as_time_delta = thread_ticks - ThreadTicks(); - return os << as_time_delta.InMicroseconds() << " bogo-thread-microseconds"; -} - -// Time::Exploded ------------------------------------------------------------- - -inline bool is_in_range(int value, int lo, int hi) { - return lo <= value && value <= hi; -} - -bool Time::Exploded::HasValidValues() const { - return is_in_range(month, 1, 12) && - is_in_range(day_of_week, 0, 6) && - is_in_range(day_of_month, 1, 31) && - is_in_range(hour, 0, 23) && - is_in_range(minute, 0, 59) && - is_in_range(second, 0, 60) && - is_in_range(millisecond, 0, 999); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/time/time.h b/security/sandbox/chromium/base/time/time.h deleted file mode 100644 index ea19d7ed9..000000000 --- a/security/sandbox/chromium/base/time/time.h +++ /dev/null @@ -1,768 +0,0 @@ -// 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 can not 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. Thus, they can be efficiently passed by-value (as opposed to -// by-reference). -// -// 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 <stdint.h> -#include <time.h> - -#include <iosfwd> -#include <limits> - -#include "base/base_export.h" -#include "base/numerics/safe_math.h" -#include "build/build_config.h" - -#if defined(OS_MACOSX) -#include <CoreFoundation/CoreFoundation.h> -// Avoid Mac system header macro leak. -#undef TYPE_BOOL -#endif - -#if defined(OS_POSIX) -#include <unistd.h> -#include <sys/time.h> -#endif - -#if defined(OS_WIN) -// For FILETIME in FromFileTime, until it moves to a new converter class. -// See TODO(iyengar) below. -#include <windows.h> - -#include "base/gtest_prod_util.h" -#endif - -namespace base { - -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 |value| from a TimeDelta. The int64_t argument and return -// value are in terms of a microsecond timebase. -BASE_EXPORT int64_t SaturatedAdd(TimeDelta delta, int64_t value); -BASE_EXPORT int64_t SaturatedSub(TimeDelta delta, int64_t value); - -// Clamp |value| on overflow and underflow conditions. The int64_t argument and -// return value are in terms of a microsecond timebase. -BASE_EXPORT int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value); - -} // namespace time_internal - -// TimeDelta ------------------------------------------------------------------ - -class BASE_EXPORT TimeDelta { - public: - TimeDelta() : delta_(0) { - } - - // Converts units of time to TimeDeltas. - static TimeDelta FromDays(int days); - static TimeDelta FromHours(int hours); - static TimeDelta FromMinutes(int minutes); - static TimeDelta FromSeconds(int64_t secs); - static TimeDelta FromMilliseconds(int64_t ms); - static TimeDelta FromSecondsD(double secs); - static TimeDelta FromMillisecondsD(double ms); - static TimeDelta FromMicroseconds(int64_t us); -#if defined(OS_WIN) - static TimeDelta FromQPCValue(LONGLONG qpc_value); -#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. - static 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 TimeDelta Max(); - - // 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. - int64_t ToInternalValue() const { return delta_; } - - // Returns the magnitude (absolute value) of this TimeDelta. - 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. - bool is_zero() const { - return delta_ == 0; - } - - // Returns true if the time delta is the maximum time delta. - bool is_max() const { return delta_ == std::numeric_limits<int64_t>::max(); } - -#if defined(OS_POSIX) - struct timespec ToTimeSpec() const; -#endif - - // Returns the time delta in some unit. The F versions return a floating - // point value, the "regular" versions return a rounded-down value. - // - // InMillisecondsRoundedUp() instead returns an integer that is rounded up - // to the next full millisecond. - int InDays() 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; - int64_t InMicroseconds() const; - - TimeDelta& operator=(TimeDelta other) { - delta_ = other.delta_; - return *this; - } - - // Computations with other deltas. - TimeDelta operator+(TimeDelta other) const { - return TimeDelta(time_internal::SaturatedAdd(*this, other.delta_)); - } - TimeDelta operator-(TimeDelta other) const { - return TimeDelta(time_internal::SaturatedSub(*this, other.delta_)); - } - - TimeDelta& operator+=(TimeDelta other) { - return *this = (*this + other); - } - TimeDelta& operator-=(TimeDelta other) { - return *this = (*this - other); - } - TimeDelta operator-() const { - return TimeDelta(-delta_); - } - - // Computations with numeric types. - template<typename T> - TimeDelta operator*(T a) const { - CheckedNumeric<int64_t> rv(delta_); - rv *= a; - return TimeDelta(time_internal::FromCheckedNumeric(rv)); - } - template<typename T> - TimeDelta operator/(T a) const { - CheckedNumeric<int64_t> rv(delta_); - rv /= a; - return TimeDelta(time_internal::FromCheckedNumeric(rv)); - } - template<typename T> - TimeDelta& operator*=(T a) { - return *this = (*this * a); - } - template<typename T> - TimeDelta& operator/=(T a) { - return *this = (*this / a); - } - - int64_t operator/(TimeDelta a) const { return delta_ / a.delta_; } - TimeDelta operator%(TimeDelta a) const { - return TimeDelta(delta_ % a.delta_); - } - - // Comparison operators. - bool operator==(TimeDelta other) const { - return delta_ == other.delta_; - } - bool operator!=(TimeDelta other) const { - return delta_ != other.delta_; - } - bool operator<(TimeDelta other) const { - return delta_ < other.delta_; - } - bool operator<=(TimeDelta other) const { - return delta_ <= other.delta_; - } - bool operator>(TimeDelta other) const { - return delta_ > other.delta_; - } - bool operator>=(TimeDelta other) const { - return delta_ >= other.delta_; - } - - private: - friend int64_t time_internal::SaturatedAdd(TimeDelta delta, int64_t value); - friend int64_t time_internal::SaturatedSub(TimeDelta delta, int64_t value); - - // 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. - explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {} - - // Private method to build a delta from a double. - static TimeDelta FromDouble(double value); - - // Delta in microseconds. - int64_t delta_; -}; - -template<typename T> -inline 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 { - -// 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 TimeClass> -class TimeBase { - public: - static const int64_t kHoursPerDay = 24; - static const int64_t kMillisecondsPerSecond = 1000; - static const int64_t kMillisecondsPerDay = - kMillisecondsPerSecond * 60 * 60 * kHoursPerDay; - static const int64_t kMicrosecondsPerMillisecond = 1000; - static const int64_t kMicrosecondsPerSecond = - kMicrosecondsPerMillisecond * kMillisecondsPerSecond; - static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60; - static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60; - static const int64_t kMicrosecondsPerDay = - kMicrosecondsPerHour * kHoursPerDay; - static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7; - static const int64_t kNanosecondsPerMicrosecond = 1000; - static const 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. - bool is_null() const { - return us_ == 0; - } - - // Returns true if this object represents the maximum time. - bool is_max() const { return us_ == std::numeric_limits<int64_t>::max(); } - - // 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. - int64_t ToInternalValue() const { return us_; } - - TimeClass& operator=(TimeClass other) { - us_ = other.us_; - return *(static_cast<TimeClass*>(this)); - } - - // Compute the difference between two times. - TimeDelta operator-(TimeClass other) const { - return TimeDelta::FromMicroseconds(us_ - other.us_); - } - - // Return a new time modified by some delta. - TimeClass operator+(TimeDelta delta) const { - return TimeClass(time_internal::SaturatedAdd(delta, us_)); - } - TimeClass operator-(TimeDelta delta) const { - return TimeClass(-time_internal::SaturatedSub(delta, us_)); - } - - // Modify by some time delta. - TimeClass& operator+=(TimeDelta delta) { - return static_cast<TimeClass&>(*this = (*this + delta)); - } - TimeClass& operator-=(TimeDelta delta) { - return static_cast<TimeClass&>(*this = (*this - delta)); - } - - // Comparison operators - bool operator==(TimeClass other) const { - return us_ == other.us_; - } - bool operator!=(TimeClass other) const { - return us_ != other.us_; - } - bool operator<(TimeClass other) const { - return us_ < other.us_; - } - bool operator<=(TimeClass other) const { - return us_ <= other.us_; - } - bool operator>(TimeClass other) const { - return us_ > other.us_; - } - bool operator>=(TimeClass other) const { - return us_ >= other.us_; - } - - // Converts an integer value representing TimeClass to a class. This is used - // when deserializing a |TimeClass| 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. - static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); } - - protected: - explicit TimeBase(int64_t us) : us_(us) {} - - // Time value in a microsecond timebase. - int64_t us_; -}; - -} // namespace time_internal - -template<class TimeClass> -inline 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. -class BASE_EXPORT Time : public time_internal::TimeBase<Time> { - public: - // The representation of Jan 1, 1970 UTC in microseconds since the - // platform-dependent epoch. - static const int64_t kTimeTToMicrosecondsOffset; - -#if !defined(OS_WIN) - // On Mac & Linux, this value is the delta from the Windows epoch of 1601 to - // the Posix delta of 1970. This is used for migrating between the old - // 1970-based epochs to the new 1601-based ones. It should be removed from - // this global header and put in the platform-specific ones when we remove the - // migration code. - static const int64_t kWindowsEpochDeltaMicroseconds; -#else - // To avoid overflow in QPC to Microseconds calculations, since we multiply - // by kMicrosecondsPerSecond, then the QPC value should not exceed - // (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply. - enum : int64_t{kQPCOverflowThreshold = 0x8637BD05AF7}; -#endif - - // Represents an exploded time that can be formatted nicely. This is kind of - // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few - // additions and changes to prevent errors. - struct BASE_EXPORT Exploded { - int year; // Four digit year "2007" - int month; // 1-based month (values 1 = January, etc.) - int day_of_week; // 0-based day of week (0 = Sunday, etc.) - int day_of_month; // 1-based day of month (1-31) - int hour; // Hour within the current day (0-23) - int minute; // Minute within the current hour (0-59) - int second; // Second within the current minute (0-59 plus leap - // seconds which may take it up to 60). - int millisecond; // Milliseconds within the current second (0-999) - - // A cursory test for whether the data members are within their - // respective ranges. A 'true' return value does not guarantee the - // Exploded value can be successfully converted to a Time value. - bool HasValidValues() const; - }; - - // Contains the NULL time. Use Time::Now() to get the current time. - Time() : TimeBase(0) { - } - - // Returns the time for epoch in Unix-like system (Jan 1, 1970). - static Time UnixEpoch(); - - // Returns the current time. Watch out, the system might adjust its clock - // in which case time will actually go backwards. We don't guarantee that - // times are increasing, or that two calls to Now() won't be the same. - static Time Now(); - - // Returns the maximum time, which should be greater than any reasonable time - // with which we might compare it. - static Time Max(); - - // Returns the current time. Same as Now() except that this function always - // uses system time so that there are no discrepancies between the returned - // time and system time even on virtual environments including our test bot. - // For timing sensitive unittests, this function should be used. - static Time NowFromSystemTime(); - - // Converts to/from time_t in UTC and a Time class. - // TODO(brettw) this should be removed once everybody starts using the |Time| - // class. - static Time FromTimeT(time_t tt); - time_t ToTimeT() const; - - // Converts time to/from a double which is the number of seconds since epoch - // (Jan 1, 1970). Webkit uses this format to represent time. - // Because WebKit initializes double time value to 0 to indicate "not - // initialized", we map it to empty Time object that also means "not - // initialized". - static Time FromDoubleT(double dt); - double ToDoubleT() const; - -#if defined(OS_POSIX) - // Converts the timespec structure to time. MacOS X 10.8.3 (and tentatively, - // earlier versions) will have the |ts|'s tv_nsec component zeroed out, - // having a 1 second resolution, which agrees with - // https://developer.apple.com/legacy/library/#technotes/tn/tn1150.html#HFSPlusDates. - static Time FromTimeSpec(const timespec& ts); -#endif - - // Converts to/from the Javascript convention for times, a number of - // milliseconds since the epoch: - // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getTime. - static Time FromJsTime(double ms_since_epoch); - double ToJsTime() const; - - // Converts to Java convention for times, a number of - // milliseconds since the epoch. - int64_t ToJavaTime() const; - -#if defined(OS_POSIX) - static Time FromTimeVal(struct timeval t); - struct timeval ToTimeVal() const; -#endif - -#if defined(OS_MACOSX) - static Time FromCFAbsoluteTime(CFAbsoluteTime t); - CFAbsoluteTime ToCFAbsoluteTime() const; -#endif - -#if defined(OS_WIN) - static Time FromFileTime(FILETIME ft); - FILETIME ToFileTime() const; - - // The minimum time of a low resolution timer. This is basically a windows - // constant of ~15.6ms. While it does vary on some older OS versions, we'll - // treat it as static across all windows versions. - static const int kMinLowResolutionThresholdMs = 16; - - // Enable or disable Windows high resolution timer. - static void EnableHighResolutionTimer(bool enable); - - // Activates or deactivates the high resolution timer based on the |activate| - // flag. If the HighResolutionTimer is not Enabled (see - // EnableHighResolutionTimer), this function will return false. Otherwise - // returns true. Each successful activate call must be paired with a - // subsequent deactivate call. - // All callers to activate the high resolution timer must eventually call - // this function to deactivate the high resolution timer. - static bool ActivateHighResolutionTimer(bool activate); - - // Returns true if the high resolution timer is both enabled and activated. - // This is provided for testing only, and is not tracked in a thread-safe - // way. - static bool IsHighResolutionTimerInUse(); -#endif - - // Converts an exploded structure representing either the local time or UTC - // into a Time class. - static Time FromUTCExploded(const Exploded& exploded) { - return FromExploded(false, exploded); - } - static Time FromLocalExploded(const Exploded& exploded) { - return FromExploded(true, exploded); - } - -#if !defined(MOZ_SANDBOX) - // Converts a string representation of time to a Time object. - // An example of a time string which is converted is as below:- - // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified - // in the input string, FromString assumes local time and FromUTCString - // assumes UTC. A timezone that cannot be parsed (e.g. "UTC" which is not - // specified in RFC822) is treated as if the timezone is not specified. - // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to - // a new time converter class. - static bool FromString(const char* time_string, Time* parsed_time) { - return FromStringInternal(time_string, true, parsed_time); - } - static bool FromUTCString(const char* time_string, Time* parsed_time) { - return FromStringInternal(time_string, false, parsed_time); - } -#endif - - // Fills the given exploded structure with either the local time or UTC from - // this time structure (containing UTC). - void UTCExplode(Exploded* exploded) const { - return Explode(false, exploded); - } - void LocalExplode(Exploded* exploded) const { - return Explode(true, exploded); - } - - // Rounds this time down to the nearest day in local time. It will represent - // midnight on that day. - Time LocalMidnight() const; - - private: - friend class time_internal::TimeBase<Time>; - - explicit Time(int64_t us) : TimeBase(us) {} - - // Explodes the given time to either local time |is_local = true| or UTC - // |is_local = false|. - void Explode(bool is_local, Exploded* exploded) const; - - // Unexplodes a given time assuming the source is either local time - // |is_local = true| or UTC |is_local = false|. - static Time FromExploded(bool is_local, const Exploded& exploded); - -#if !defined(MOZ_SANDBOX) - // Converts a string representation of time to a Time object. - // An example of a time string which is converted is as below:- - // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified - // in the input string, local time |is_local = true| or - // UTC |is_local = false| is assumed. A timezone that cannot be parsed - // (e.g. "UTC" which is not specified in RFC822) is treated as if the - // timezone is not specified. - static bool FromStringInternal(const char* time_string, - bool is_local, - Time* parsed_time); -#endif -}; - -// Inline the TimeDelta factory methods, for fast TimeDelta construction. - -// static -inline TimeDelta TimeDelta::FromDays(int days) { - if (days == std::numeric_limits<int>::max()) - return Max(); - return TimeDelta(days * Time::kMicrosecondsPerDay); -} - -// static -inline TimeDelta TimeDelta::FromHours(int hours) { - if (hours == std::numeric_limits<int>::max()) - return Max(); - return TimeDelta(hours * Time::kMicrosecondsPerHour); -} - -// static -inline TimeDelta TimeDelta::FromMinutes(int minutes) { - if (minutes == std::numeric_limits<int>::max()) - return Max(); - return TimeDelta(minutes * Time::kMicrosecondsPerMinute); -} - -// static -inline TimeDelta TimeDelta::FromSeconds(int64_t secs) { - return TimeDelta(secs) * Time::kMicrosecondsPerSecond; -} - -// static -inline TimeDelta TimeDelta::FromMilliseconds(int64_t ms) { - return TimeDelta(ms) * Time::kMicrosecondsPerMillisecond; -} - -// static -inline TimeDelta TimeDelta::FromSecondsD(double secs) { - return FromDouble(secs * Time::kMicrosecondsPerSecond); -} - -// static -inline TimeDelta TimeDelta::FromMillisecondsD(double ms) { - return FromDouble(ms * Time::kMicrosecondsPerMillisecond); -} - -// static -inline TimeDelta TimeDelta::FromMicroseconds(int64_t us) { - return TimeDelta(us); -} - -// static -inline TimeDelta TimeDelta::FromDouble(double value) { - double max_magnitude = std::numeric_limits<int64_t>::max(); - TimeDelta delta = TimeDelta(static_cast<int64_t>(value)); - if (value > max_magnitude) - delta = Max(); - else if (value < -max_magnitude) - delta = -Max(); - return delta; -} - -// 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> { - public: - TimeTicks() : TimeBase(0) { - } - - // Platform-dependent tick count representing "right now." When - // IsHighResolution() returns false, the resolution of the clock could be - // as coarse as ~15.6ms. Otherwise, the resolution should be no worse than one - // microsecond. - static TimeTicks Now(); - - // Returns true if the high resolution clock is working on this system and - // Now() will return high resolution values. Note that, on systems where the - // high resolution clock works but is deemed inefficient, the low resolution - // clock will be used instead. - static bool IsHighResolution(); - -#if defined(OS_WIN) - // Translates an absolute QPC timestamp into a TimeTicks value. The returned - // value has the same origin as Now(). Do NOT attempt to use this if - // IsHighResolution() returns false. - static TimeTicks FromQPCValue(LONGLONG qpc_value); -#endif - - // Get an estimate of the TimeTick value at the time of the UnixEpoch. Because - // Time and TimeTicks respond differently to user-set time and NTP - // adjustments, this number is only an estimate. Nevertheless, this can be - // useful when you need to relate the value of TimeTicks to a real time and - // date. Note: Upon first invocation, this function takes a snapshot of the - // realtime clock to establish a reference point. This function will return - // the same value for the duration of the application, but will be different - // in future application runs. - static TimeTicks UnixEpoch(); - - // Returns |this| snapped to the next tick, given a |tick_phase| and - // repeating |tick_interval| in both directions. |this| may be before, - // after, or equal to the |tick_phase|. - TimeTicks SnappedToNextTick(TimeTicks tick_phase, - TimeDelta tick_interval) const; - -#if defined(OS_WIN) - protected: - typedef DWORD (*TickFunctionType)(void); - static TickFunctionType SetMockTickFunction(TickFunctionType ticker); -#endif - - private: - friend class time_internal::TimeBase<TimeTicks>; - - // Please use Now() to create a new object. This is for internal use - // and testing. - explicit TimeTicks(int64_t us) : TimeBase(us) {} -}; - -// For logging use only. -BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks); - -// ThreadTicks ---------------------------------------------------------------- - -// Represents a clock, specific to a particular thread, than runs only while the -// thread is running. -class BASE_EXPORT ThreadTicks : public time_internal::TimeBase<ThreadTicks> { - public: - ThreadTicks() : TimeBase(0) { - } - - // Returns true if ThreadTicks::Now() is supported on this system. - static bool IsSupported() { -#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ - (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID) - return true; -#elif defined(OS_WIN) - return IsSupportedWin(); -#else - return false; -#endif - } - - // Waits until the initialization is completed. Needs to be guarded with a - // call to IsSupported(). - static void WaitUntilInitialized() { -#if defined(OS_WIN) - WaitUntilInitializedWin(); -#endif - } - - // Returns thread-specific CPU-time on systems that support this feature. - // Needs to be guarded with a call to IsSupported(). Use this timer - // to (approximately) measure how much time the calling thread spent doing - // actual work vs. being de-scheduled. May return bogus results if the thread - // migrates to another CPU between two calls. Returns an empty ThreadTicks - // object until the initialization is completed. If a clock reading is - // absolutely needed, call WaitUntilInitialized() before this method. - static ThreadTicks Now(); - - private: - friend class time_internal::TimeBase<ThreadTicks>; - - // Please use Now() to create a new object. This is for internal use - // and testing. - explicit ThreadTicks(int64_t us) : TimeBase(us) {} - -#if defined(OS_WIN) - FRIEND_TEST_ALL_PREFIXES(TimeTicks, TSCTicksPerSecond); - - // 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 IsSupported(). - // This method is declared here rather than in the anonymous namespace to - // allow testing. - static double TSCTicksPerSecond(); - - static bool IsSupportedWin(); - static void WaitUntilInitializedWin(); -#endif -}; - -// For logging use only. -BASE_EXPORT std::ostream& operator<<(std::ostream& os, ThreadTicks time_ticks); - -} // namespace base - -#endif // BASE_TIME_TIME_H_ diff --git a/security/sandbox/chromium/base/time/time_posix.cc b/security/sandbox/chromium/base/time/time_posix.cc deleted file mode 100644 index 4aadee618..000000000 --- a/security/sandbox/chromium/base/time/time_posix.cc +++ /dev/null @@ -1,363 +0,0 @@ -// 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. - -#include "base/time/time.h" - -#include <stdint.h> -#include <sys/time.h> -#include <time.h> -#if defined(OS_ANDROID) && !defined(__LP64__) -#include <time64.h> -#endif -#include <unistd.h> - -#include <limits> -#include <ostream> - -#include "base/logging.h" -#include "build/build_config.h" - -#if defined(OS_ANDROID) -#include "base/os_compat_android.h" -#elif defined(OS_NACL) -#include "base/os_compat_nacl.h" -#endif - -#if !defined(OS_MACOSX) -#include "base/lazy_instance.h" -#include "base/synchronization/lock.h" -#endif - -namespace { - -#if !defined(OS_MACOSX) -// This prevents a crash on traversing the environment global and looking up -// the 'TZ' variable in libc. See: crbug.com/390567. -base::LazyInstance<base::Lock>::Leaky - g_sys_time_to_time_struct_lock = LAZY_INSTANCE_INITIALIZER; - -// Define a system-specific SysTime that wraps either to a time_t or -// a time64_t depending on the host system, and associated convertion. -// See crbug.com/162007 -#if defined(OS_ANDROID) && !defined(__LP64__) -typedef time64_t SysTime; - -SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - return mktime64(timestruct); - else - return timegm64(timestruct); -} - -void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - localtime64_r(&t, timestruct); - else - gmtime64_r(&t, timestruct); -} - -#else // OS_ANDROID && !__LP64__ -typedef time_t SysTime; - -SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - return mktime(timestruct); - else - return timegm(timestruct); -} - -void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - localtime_r(&t, timestruct); - else - gmtime_r(&t, timestruct); -} -#endif // OS_ANDROID - -int64_t ConvertTimespecToMicros(const struct timespec& ts) { - base::CheckedNumeric<int64_t> result(ts.tv_sec); - result *= base::Time::kMicrosecondsPerSecond; - result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond); - return result.ValueOrDie(); -} - -// Helper function to get results from clock_gettime() and convert to a -// microsecond timebase. Minimum requirement is MONOTONIC_CLOCK to be supported -// on the system. FreeBSD 6 has CLOCK_MONOTONIC but defines -// _POSIX_MONOTONIC_CLOCK to -1. -#if (defined(OS_POSIX) && \ - defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0) || \ - defined(OS_BSD) || defined(OS_ANDROID) -int64_t ClockNow(clockid_t clk_id) { - struct timespec ts; - if (clock_gettime(clk_id, &ts) != 0) { - NOTREACHED() << "clock_gettime(" << clk_id << ") failed."; - return 0; - } - return ConvertTimespecToMicros(ts); -} -#else // _POSIX_MONOTONIC_CLOCK -#error No usable tick clock function on this platform. -#endif // _POSIX_MONOTONIC_CLOCK -#endif // !defined(OS_MACOSX) - -} // namespace - -namespace base { - -struct timespec TimeDelta::ToTimeSpec() const { - int64_t microseconds = InMicroseconds(); - time_t seconds = 0; - if (microseconds >= Time::kMicrosecondsPerSecond) { - seconds = InSeconds(); - microseconds -= seconds * Time::kMicrosecondsPerSecond; - } - struct timespec result = - {seconds, - static_cast<long>(microseconds * Time::kNanosecondsPerMicrosecond)}; - return result; -} - -#if !defined(OS_MACOSX) -// The Time routines in this file use standard POSIX routines, or almost- -// standard routines in the case of timegm. We need to use a Mach-specific -// function for TimeTicks::Now() on Mac OS X. - -// Time ----------------------------------------------------------------------- - -// Windows uses a Gregorian epoch of 1601. We need to match this internally -// so that our time representations match across all platforms. See bug 14734. -// irb(main):010:0> Time.at(0).getutc() -// => Thu Jan 01 00:00:00 UTC 1970 -// irb(main):011:0> Time.at(-11644473600).getutc() -// => Mon Jan 01 00:00:00 UTC 1601 -static const int64_t kWindowsEpochDeltaSeconds = INT64_C(11644473600); - -// static -const int64_t Time::kWindowsEpochDeltaMicroseconds = - kWindowsEpochDeltaSeconds * Time::kMicrosecondsPerSecond; - -// Some functions in time.cc use time_t directly, so we provide an offset -// to convert from time_t (Unix epoch) and internal (Windows epoch). -// static -const int64_t Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds; - -// static -Time Time::Now() { - struct timeval tv; - struct timezone tz = { 0, 0 }; // UTC - if (gettimeofday(&tv, &tz) != 0) { - DCHECK(0) << "Could not determine time of day"; - PLOG(ERROR) << "Call to gettimeofday failed."; - // Return null instead of uninitialized |tv| value, which contains random - // garbage data. This may result in the crash seen in crbug.com/147570. - return Time(); - } - // Combine seconds and microseconds in a 64-bit field containing microseconds - // since the epoch. That's enough for nearly 600 centuries. Adjust from - // Unix (1970) to Windows (1601) epoch. - return Time((tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec) + - kWindowsEpochDeltaMicroseconds); -} - -// static -Time Time::NowFromSystemTime() { - // Just use Now() because Now() returns the system time. - return Now(); -} - -void Time::Explode(bool is_local, Exploded* exploded) const { - // Time stores times with microsecond resolution, but Exploded only carries - // millisecond resolution, so begin by being lossy. Adjust from Windows - // epoch (1601) to Unix epoch (1970); - int64_t microseconds = us_ - kWindowsEpochDeltaMicroseconds; - // The following values are all rounded towards -infinity. - int64_t milliseconds; // Milliseconds since epoch. - SysTime seconds; // Seconds since epoch. - int millisecond; // Exploded millisecond value (0-999). - if (microseconds >= 0) { - // Rounding towards -infinity <=> rounding towards 0, in this case. - milliseconds = microseconds / kMicrosecondsPerMillisecond; - seconds = milliseconds / kMillisecondsPerSecond; - millisecond = milliseconds % kMillisecondsPerSecond; - } else { - // Round these *down* (towards -infinity). - milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) / - kMicrosecondsPerMillisecond; - seconds = (milliseconds - kMillisecondsPerSecond + 1) / - kMillisecondsPerSecond; - // Make this nonnegative (and between 0 and 999 inclusive). - millisecond = milliseconds % kMillisecondsPerSecond; - if (millisecond < 0) - millisecond += kMillisecondsPerSecond; - } - - struct tm timestruct; - SysTimeToTimeStruct(seconds, ×truct, is_local); - - exploded->year = timestruct.tm_year + 1900; - exploded->month = timestruct.tm_mon + 1; - exploded->day_of_week = timestruct.tm_wday; - exploded->day_of_month = timestruct.tm_mday; - exploded->hour = timestruct.tm_hour; - exploded->minute = timestruct.tm_min; - exploded->second = timestruct.tm_sec; - exploded->millisecond = millisecond; -} - -// static -Time Time::FromExploded(bool is_local, const Exploded& exploded) { - struct tm timestruct; - timestruct.tm_sec = exploded.second; - timestruct.tm_min = exploded.minute; - timestruct.tm_hour = exploded.hour; - timestruct.tm_mday = exploded.day_of_month; - timestruct.tm_mon = exploded.month - 1; - timestruct.tm_year = exploded.year - 1900; - timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this - timestruct.tm_yday = 0; // mktime/timegm ignore this - timestruct.tm_isdst = -1; // attempt to figure it out -#if !defined(OS_NACL) && !defined(OS_SOLARIS) - timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore - timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore -#endif - - int64_t milliseconds; - SysTime seconds; - - // Certain exploded dates do not really exist due to daylight saving times, - // and this causes mktime() to return implementation-defined values when - // tm_isdst is set to -1. On Android, the function will return -1, while the - // C libraries of other platforms typically return a liberally-chosen value. - // Handling this requires the special code below. - - // SysTimeFromTimeStruct() modifies the input structure, save current value. - struct tm timestruct0 = timestruct; - - seconds = SysTimeFromTimeStruct(×truct, is_local); - if (seconds == -1) { - // Get the time values with tm_isdst == 0 and 1, then select the closest one - // to UTC 00:00:00 that isn't -1. - timestruct = timestruct0; - timestruct.tm_isdst = 0; - int64_t seconds_isdst0 = SysTimeFromTimeStruct(×truct, is_local); - - timestruct = timestruct0; - timestruct.tm_isdst = 1; - int64_t seconds_isdst1 = SysTimeFromTimeStruct(×truct, is_local); - - // seconds_isdst0 or seconds_isdst1 can be -1 for some timezones. - // E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'. - if (seconds_isdst0 < 0) - seconds = seconds_isdst1; - else if (seconds_isdst1 < 0) - seconds = seconds_isdst0; - else - seconds = std::min(seconds_isdst0, seconds_isdst1); - } - - // Handle overflow. Clamping the range to what mktime and timegm might - // return is the best that can be done here. It's not ideal, but it's better - // than failing here or ignoring the overflow case and treating each time - // overflow as one second prior to the epoch. - if (seconds == -1 && - (exploded.year < 1969 || exploded.year > 1970)) { - // If exploded.year is 1969 or 1970, take -1 as correct, with the - // time indicating 1 second prior to the epoch. (1970 is allowed to handle - // time zone and DST offsets.) Otherwise, return the most future or past - // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. - // - // The minimum and maximum representible times that mktime and timegm could - // return are used here instead of values outside that range to allow for - // proper round-tripping between exploded and counter-type time - // representations in the presence of possible truncation to time_t by - // division and use with other functions that accept time_t. - // - // When representing the most distant time in the future, add in an extra - // 999ms to avoid the time being less than any other possible value that - // this function can return. - - // On Android, SysTime is int64_t, special care must be taken to avoid - // overflows. - const int64_t min_seconds = (sizeof(SysTime) < sizeof(int64_t)) - ? std::numeric_limits<SysTime>::min() - : std::numeric_limits<int32_t>::min(); - const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t)) - ? std::numeric_limits<SysTime>::max() - : std::numeric_limits<int32_t>::max(); - if (exploded.year < 1969) { - milliseconds = min_seconds * kMillisecondsPerSecond; - } else { - milliseconds = max_seconds * kMillisecondsPerSecond; - milliseconds += (kMillisecondsPerSecond - 1); - } - } else { - milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; - } - - // Adjust from Unix (1970) to Windows (1601) epoch. - return Time((milliseconds * kMicrosecondsPerMillisecond) + - kWindowsEpochDeltaMicroseconds); -} - -// TimeTicks ------------------------------------------------------------------ -// static -TimeTicks TimeTicks::Now() { - return TimeTicks(ClockNow(CLOCK_MONOTONIC)); -} - -// static -bool TimeTicks::IsHighResolution() { - return true; -} - -// static -ThreadTicks ThreadTicks::Now() { -#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ - defined(OS_ANDROID) - return ThreadTicks(ClockNow(CLOCK_THREAD_CPUTIME_ID)); -#else - NOTREACHED(); - return ThreadTicks(); -#endif -} - -#endif // !OS_MACOSX - -// static -Time Time::FromTimeVal(struct timeval t) { - DCHECK_LT(t.tv_usec, static_cast<int>(Time::kMicrosecondsPerSecond)); - DCHECK_GE(t.tv_usec, 0); - if (t.tv_usec == 0 && t.tv_sec == 0) - return Time(); - if (t.tv_usec == static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1 && - t.tv_sec == std::numeric_limits<time_t>::max()) - return Max(); - return Time((static_cast<int64_t>(t.tv_sec) * Time::kMicrosecondsPerSecond) + - t.tv_usec + kTimeTToMicrosecondsOffset); -} - -struct timeval Time::ToTimeVal() const { - struct timeval result; - if (is_null()) { - result.tv_sec = 0; - result.tv_usec = 0; - return result; - } - if (is_max()) { - result.tv_sec = std::numeric_limits<time_t>::max(); - result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; - return result; - } - int64_t us = us_ - kTimeTToMicrosecondsOffset; - result.tv_sec = us / Time::kMicrosecondsPerSecond; - result.tv_usec = us % Time::kMicrosecondsPerSecond; - return result; -} - -} // namespace base diff --git a/security/sandbox/chromium/base/time/time_win.cc b/security/sandbox/chromium/base/time/time_win.cc deleted file mode 100644 index dc968ad63..000000000 --- a/security/sandbox/chromium/base/time/time_win.cc +++ /dev/null @@ -1,616 +0,0 @@ -// 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. - - -// Windows Timer Primer -// -// A good article: http://www.ddj.com/windows/184416651 -// A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258 -// -// The default windows timer, GetSystemTimeAsFileTime is not very precise. -// It is only good to ~15.5ms. -// -// QueryPerformanceCounter is the logical choice for a high-precision timer. -// However, it is known to be buggy on some hardware. Specifically, it can -// sometimes "jump". On laptops, QPC can also be very expensive to call. -// It's 3-4x slower than timeGetTime() on desktops, but can be 10x slower -// on laptops. A unittest exists which will show the relative cost of various -// timers on any system. -// -// The next logical choice is timeGetTime(). timeGetTime has a precision of -// 1ms, but only if you call APIs (timeBeginPeriod()) which affect all other -// applications on the system. By default, precision is only 15.5ms. -// Unfortunately, we don't want to call timeBeginPeriod because we don't -// want to affect other applications. Further, on mobile platforms, use of -// faster multimedia timers can hurt battery life. See the intel -// article about this here: -// http://softwarecommunity.intel.com/articles/eng/1086.htm -// -// To work around all this, we're going to generally use timeGetTime(). We -// will only increase the system-wide timer if we're not running on battery -// power. - -#include "base/time/time.h" - -#pragma comment(lib, "winmm.lib") -#include <windows.h> -#include <mmsystem.h> -#include <stdint.h> - -#include "base/bit_cast.h" -#include "base/cpu.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/synchronization/lock.h" - -using base::ThreadTicks; -using base::Time; -using base::TimeDelta; -using base::TimeTicks; - -namespace { - -// From MSDN, FILETIME "Contains a 64-bit value representing the number of -// 100-nanosecond intervals since January 1, 1601 (UTC)." -int64_t FileTimeToMicroseconds(const FILETIME& ft) { - // Need to bit_cast to fix alignment, then divide by 10 to convert - // 100-nanoseconds to microseconds. This only works on little-endian - // machines. - return bit_cast<int64_t, FILETIME>(ft) / 10; -} - -void MicrosecondsToFileTime(int64_t us, FILETIME* ft) { - DCHECK_GE(us, 0LL) << "Time is less than 0, negative values are not " - "representable in FILETIME"; - - // Multiply by 10 to convert microseconds to 100-nanoseconds. Bit_cast will - // handle alignment problems. This only works on little-endian machines. - *ft = bit_cast<FILETIME, int64_t>(us * 10); -} - -int64_t CurrentWallclockMicroseconds() { - FILETIME ft; - ::GetSystemTimeAsFileTime(&ft); - return FileTimeToMicroseconds(ft); -} - -// Time between resampling the un-granular clock for this API. 60 seconds. -const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; - -int64_t initial_time = 0; -TimeTicks initial_ticks; - -void InitializeClock() { - initial_ticks = TimeTicks::Now(); - initial_time = CurrentWallclockMicroseconds(); -} - -// The two values that ActivateHighResolutionTimer uses to set the systemwide -// timer interrupt frequency on Windows. It controls how precise timers are -// but also has a big impact on battery life. -const int kMinTimerIntervalHighResMs = 1; -const int kMinTimerIntervalLowResMs = 4; -// Track if kMinTimerIntervalHighResMs or kMinTimerIntervalLowResMs is active. -bool g_high_res_timer_enabled = false; -// How many times the high resolution timer has been called. -uint32_t g_high_res_timer_count = 0; -// The lock to control access to the above two variables. -base::LazyInstance<base::Lock>::Leaky g_high_res_lock = - LAZY_INSTANCE_INITIALIZER; - -// Returns a pointer to the QueryThreadCycleTime() function from Windows. -// Can't statically link to it because it is not available on XP. -using QueryThreadCycleTimePtr = decltype(::QueryThreadCycleTime)*; -QueryThreadCycleTimePtr GetQueryThreadCycleTimeFunction() { - static const QueryThreadCycleTimePtr query_thread_cycle_time_fn = - reinterpret_cast<QueryThreadCycleTimePtr>(::GetProcAddress( - ::GetModuleHandle(L"kernel32.dll"), "QueryThreadCycleTime")); - return query_thread_cycle_time_fn; -} - -// Returns the current value of the performance counter. -uint64_t QPCNowRaw() { - LARGE_INTEGER perf_counter_now = {}; - // According to the MSDN documentation for QueryPerformanceCounter(), this - // will never fail on systems that run XP or later. - // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx - ::QueryPerformanceCounter(&perf_counter_now); - return perf_counter_now.QuadPart; -} - -} // namespace - -// Time ----------------------------------------------------------------------- - -// The internal representation of Time uses FILETIME, whose epoch is 1601-01-01 -// 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the -// number of leap year days between 1601 and 1970: (1970-1601)/4 excluding -// 1700, 1800, and 1900. -// static -const int64_t Time::kTimeTToMicrosecondsOffset = INT64_C(11644473600000000); - -// static -Time Time::Now() { - if (initial_time == 0) - InitializeClock(); - - // We implement time using the high-resolution timers so that we can get - // timeouts which are smaller than 10-15ms. If we just used - // CurrentWallclockMicroseconds(), we'd have the less-granular timer. - // - // To make this work, we initialize the clock (initial_time) and the - // counter (initial_ctr). To compute the initial time, we can check - // the number of ticks that have elapsed, and compute the delta. - // - // To avoid any drift, we periodically resync the counters to the system - // clock. - while (true) { - TimeTicks ticks = TimeTicks::Now(); - - // Calculate the time elapsed since we started our timer - TimeDelta elapsed = ticks - initial_ticks; - - // Check if enough time has elapsed that we need to resync the clock. - if (elapsed.InMilliseconds() > kMaxMillisecondsToAvoidDrift) { - InitializeClock(); - continue; - } - - return Time(elapsed + Time(initial_time)); - } -} - -// static -Time Time::NowFromSystemTime() { - // Force resync. - InitializeClock(); - return Time(initial_time); -} - -// static -Time Time::FromFileTime(FILETIME ft) { - if (bit_cast<int64_t, FILETIME>(ft) == 0) - return Time(); - if (ft.dwHighDateTime == std::numeric_limits<DWORD>::max() && - ft.dwLowDateTime == std::numeric_limits<DWORD>::max()) - return Max(); - return Time(FileTimeToMicroseconds(ft)); -} - -FILETIME Time::ToFileTime() const { - if (is_null()) - return bit_cast<FILETIME, int64_t>(0); - if (is_max()) { - FILETIME result; - result.dwHighDateTime = std::numeric_limits<DWORD>::max(); - result.dwLowDateTime = std::numeric_limits<DWORD>::max(); - return result; - } - FILETIME utc_ft; - MicrosecondsToFileTime(us_, &utc_ft); - return utc_ft; -} - -// static -void Time::EnableHighResolutionTimer(bool enable) { - base::AutoLock lock(g_high_res_lock.Get()); - if (g_high_res_timer_enabled == enable) - return; - g_high_res_timer_enabled = enable; - if (!g_high_res_timer_count) - return; - // Since g_high_res_timer_count != 0, an ActivateHighResolutionTimer(true) - // was called which called timeBeginPeriod with g_high_res_timer_enabled - // with a value which is the opposite of |enable|. With that information we - // call timeEndPeriod with the same value used in timeBeginPeriod and - // therefore undo the period effect. - if (enable) { - timeEndPeriod(kMinTimerIntervalLowResMs); - timeBeginPeriod(kMinTimerIntervalHighResMs); - } else { - timeEndPeriod(kMinTimerIntervalHighResMs); - timeBeginPeriod(kMinTimerIntervalLowResMs); - } -} - -// static -bool Time::ActivateHighResolutionTimer(bool activating) { - // We only do work on the transition from zero to one or one to zero so we - // can easily undo the effect (if necessary) when EnableHighResolutionTimer is - // called. - const uint32_t max = std::numeric_limits<uint32_t>::max(); - - base::AutoLock lock(g_high_res_lock.Get()); - UINT period = g_high_res_timer_enabled ? kMinTimerIntervalHighResMs - : kMinTimerIntervalLowResMs; - if (activating) { - DCHECK_NE(g_high_res_timer_count, max); - ++g_high_res_timer_count; - if (g_high_res_timer_count == 1) - timeBeginPeriod(period); - } else { - DCHECK_NE(g_high_res_timer_count, 0u); - --g_high_res_timer_count; - if (g_high_res_timer_count == 0) - timeEndPeriod(period); - } - return (period == kMinTimerIntervalHighResMs); -} - -// static -bool Time::IsHighResolutionTimerInUse() { - base::AutoLock lock(g_high_res_lock.Get()); - return g_high_res_timer_enabled && g_high_res_timer_count > 0; -} - -// static -Time Time::FromExploded(bool is_local, const Exploded& exploded) { - // Create the system struct representing our exploded time. It will either be - // in local time or UTC. - SYSTEMTIME st; - st.wYear = static_cast<WORD>(exploded.year); - st.wMonth = static_cast<WORD>(exploded.month); - st.wDayOfWeek = static_cast<WORD>(exploded.day_of_week); - st.wDay = static_cast<WORD>(exploded.day_of_month); - st.wHour = static_cast<WORD>(exploded.hour); - st.wMinute = static_cast<WORD>(exploded.minute); - st.wSecond = static_cast<WORD>(exploded.second); - st.wMilliseconds = static_cast<WORD>(exploded.millisecond); - - FILETIME ft; - bool success = true; - // Ensure that it's in UTC. - if (is_local) { - SYSTEMTIME utc_st; - success = TzSpecificLocalTimeToSystemTime(NULL, &st, &utc_st) && - SystemTimeToFileTime(&utc_st, &ft); - } else { - success = !!SystemTimeToFileTime(&st, &ft); - } - - if (!success) { - NOTREACHED() << "Unable to convert time"; - return Time(0); - } - return Time(FileTimeToMicroseconds(ft)); -} - -void Time::Explode(bool is_local, Exploded* exploded) const { - if (us_ < 0LL) { - // We are not able to convert it to FILETIME. - ZeroMemory(exploded, sizeof(*exploded)); - return; - } - - // FILETIME in UTC. - FILETIME utc_ft; - MicrosecondsToFileTime(us_, &utc_ft); - - // FILETIME in local time if necessary. - bool success = true; - // FILETIME in SYSTEMTIME (exploded). - SYSTEMTIME st = {0}; - if (is_local) { - SYSTEMTIME utc_st; - // We don't use FileTimeToLocalFileTime here, since it uses the current - // settings for the time zone and daylight saving time. Therefore, if it is - // daylight saving time, it will take daylight saving time into account, - // even if the time you are converting is in standard time. - success = FileTimeToSystemTime(&utc_ft, &utc_st) && - SystemTimeToTzSpecificLocalTime(NULL, &utc_st, &st); - } else { - success = !!FileTimeToSystemTime(&utc_ft, &st); - } - - if (!success) { - NOTREACHED() << "Unable to convert time, don't know why"; - ZeroMemory(exploded, sizeof(*exploded)); - return; - } - - exploded->year = st.wYear; - exploded->month = st.wMonth; - exploded->day_of_week = st.wDayOfWeek; - exploded->day_of_month = st.wDay; - exploded->hour = st.wHour; - exploded->minute = st.wMinute; - exploded->second = st.wSecond; - exploded->millisecond = st.wMilliseconds; -} - -// TimeTicks ------------------------------------------------------------------ -namespace { - -// We define a wrapper to adapt between the __stdcall and __cdecl call of the -// mock function, and to avoid a static constructor. Assigning an import to a -// function pointer directly would require setup code to fetch from the IAT. -DWORD timeGetTimeWrapper() { - return timeGetTime(); -} - -DWORD (*g_tick_function)(void) = &timeGetTimeWrapper; - -// Accumulation of time lost due to rollover (in milliseconds). -int64_t g_rollover_ms = 0; - -// The last timeGetTime value we saw, to detect rollover. -DWORD g_last_seen_now = 0; - -// Lock protecting rollover_ms and last_seen_now. -// Note: this is a global object, and we usually avoid these. However, the time -// code is low-level, and we don't want to use Singletons here (it would be too -// easy to use a Singleton without even knowing it, and that may lead to many -// gotchas). Its impact on startup time should be negligible due to low-level -// nature of time code. -base::Lock g_rollover_lock; - -// We use timeGetTime() to implement TimeTicks::Now(). This can be problematic -// because it returns the number of milliseconds since Windows has started, -// which will roll over the 32-bit value every ~49 days. We try to track -// rollover ourselves, which works if TimeTicks::Now() is called at least every -// 49 days. -TimeDelta RolloverProtectedNow() { - base::AutoLock locked(g_rollover_lock); - // We should hold the lock while calling tick_function to make sure that - // we keep last_seen_now stay correctly in sync. - DWORD now = g_tick_function(); - if (now < g_last_seen_now) - g_rollover_ms += 0x100000000I64; // ~49.7 days. - g_last_seen_now = now; - return TimeDelta::FromMilliseconds(now + g_rollover_ms); -} - -// Discussion of tick counter options on Windows: -// -// (1) CPU cycle counter. (Retrieved via RDTSC) -// The CPU counter provides the highest resolution time stamp and is the least -// expensive to retrieve. However, on older CPUs, two issues can affect its -// reliability: First it is maintained per processor and not synchronized -// between processors. Also, the counters will change frequency due to thermal -// and power changes, and stop in some states. -// -// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high- -// resolution (<1 microsecond) time stamp. On most hardware running today, it -// auto-detects and uses the constant-rate RDTSC counter to provide extremely -// efficient and reliable time stamps. -// -// On older CPUs where RDTSC is unreliable, it falls back to using more -// expensive (20X to 40X more costly) alternate clocks, such as HPET or the ACPI -// PM timer, and can involve system calls; and all this is up to the HAL (with -// some help from ACPI). According to -// http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx, in the -// worst case, it gets the counter from the rollover interrupt on the -// programmable interrupt timer. In best cases, the HAL may conclude that the -// RDTSC counter runs at a constant frequency, then it uses that instead. On -// multiprocessor machines, it will try to verify the values returned from -// RDTSC on each processor are consistent with each other, and apply a handful -// of workarounds for known buggy hardware. In other words, QPC is supposed to -// give consistent results on a multiprocessor computer, but for older CPUs it -// can be unreliable due bugs in BIOS or HAL. -// -// (3) System time. The system time provides a low-resolution (from ~1 to ~15.6 -// milliseconds) time stamp but is comparatively less expensive to retrieve and -// more reliable. Time::EnableHighResolutionTimer() and -// Time::ActivateHighResolutionTimer() can be called to alter the resolution of -// this timer; and also other Windows applications can alter it, affecting this -// one. - -using NowFunction = TimeDelta (*)(void); - -TimeDelta InitialNowFunction(); - -// See "threading notes" in InitializeNowFunctionPointer() for details on how -// concurrent reads/writes to these globals has been made safe. -NowFunction g_now_function = &InitialNowFunction; -int64_t g_qpc_ticks_per_second = 0; - -// As of January 2015, use of <atomic> is forbidden in Chromium code. This is -// what std::atomic_thread_fence does on Windows on all Intel architectures when -// the memory_order argument is anything but std::memory_order_seq_cst: -#define ATOMIC_THREAD_FENCE(memory_order) _ReadWriteBarrier(); - -TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) { - // Ensure that the assignment to |g_qpc_ticks_per_second|, made in - // InitializeNowFunctionPointer(), has happened by this point. - ATOMIC_THREAD_FENCE(memory_order_acquire); - - DCHECK_GT(g_qpc_ticks_per_second, 0); - - // If the QPC Value is below the overflow threshold, we proceed with - // simple multiply and divide. - if (qpc_value < Time::kQPCOverflowThreshold) { - return TimeDelta::FromMicroseconds( - qpc_value * Time::kMicrosecondsPerSecond / g_qpc_ticks_per_second); - } - // Otherwise, calculate microseconds in a round about manner to avoid - // overflow and precision issues. - int64_t whole_seconds = qpc_value / g_qpc_ticks_per_second; - int64_t leftover_ticks = qpc_value - (whole_seconds * g_qpc_ticks_per_second); - return TimeDelta::FromMicroseconds( - (whole_seconds * Time::kMicrosecondsPerSecond) + - ((leftover_ticks * Time::kMicrosecondsPerSecond) / - g_qpc_ticks_per_second)); -} - -TimeDelta QPCNow() { - return QPCValueToTimeDelta(QPCNowRaw()); -} - -bool IsBuggyAthlon(const base::CPU& cpu) { - // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is unreliable. - return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15; -} - -void InitializeNowFunctionPointer() { - LARGE_INTEGER ticks_per_sec = {}; - if (!QueryPerformanceFrequency(&ticks_per_sec)) - ticks_per_sec.QuadPart = 0; - - // If Windows cannot provide a QPC implementation, TimeTicks::Now() must use - // the low-resolution clock. - // - // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now() - // will still use the low-resolution clock. A CPU lacking a non-stop time - // counter will cause Windows to provide an alternate QPC implementation that - // works, but is expensive to use. Certain Athlon CPUs are known to make the - // QPC implementation unreliable. - // - // Otherwise, Now uses the high-resolution QPC clock. As of 21 August 2015, - // ~72% of users fall within this category. - NowFunction now_function; - base::CPU cpu; - if (ticks_per_sec.QuadPart <= 0 || - !cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) { - now_function = &RolloverProtectedNow; - } else { - now_function = &QPCNow; - } - - // Threading note 1: In an unlikely race condition, it's possible for two or - // more threads to enter InitializeNowFunctionPointer() in parallel. This is - // not a problem since all threads should end up writing out the same values - // to the global variables. - // - // Threading note 2: A release fence is placed here to ensure, from the - // perspective of other threads using the function pointers, that the - // assignment to |g_qpc_ticks_per_second| happens before the function pointers - // are changed. - g_qpc_ticks_per_second = ticks_per_sec.QuadPart; - ATOMIC_THREAD_FENCE(memory_order_release); - g_now_function = now_function; -} - -TimeDelta InitialNowFunction() { - InitializeNowFunctionPointer(); - return g_now_function(); -} - -} // namespace - -// static -TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction( - TickFunctionType ticker) { - base::AutoLock locked(g_rollover_lock); - TickFunctionType old = g_tick_function; - g_tick_function = ticker; - g_rollover_ms = 0; - g_last_seen_now = 0; - return old; -} - -// static -TimeTicks TimeTicks::Now() { - return TimeTicks() + g_now_function(); -} - -// static -bool TimeTicks::IsHighResolution() { - if (g_now_function == &InitialNowFunction) - InitializeNowFunctionPointer(); - return g_now_function == &QPCNow; -} - -// static -ThreadTicks ThreadTicks::Now() { - DCHECK(IsSupported()); - - // Get the number of TSC ticks used by the current thread. - ULONG64 thread_cycle_time = 0; - GetQueryThreadCycleTimeFunction()(::GetCurrentThread(), &thread_cycle_time); - - // Get the frequency of the TSC. - double tsc_ticks_per_second = TSCTicksPerSecond(); - if (tsc_ticks_per_second == 0) - return ThreadTicks(); - - // Return the CPU time of the current thread. - double thread_time_seconds = thread_cycle_time / tsc_ticks_per_second; - return ThreadTicks( - static_cast<int64_t>(thread_time_seconds * Time::kMicrosecondsPerSecond)); -} - -// static -bool ThreadTicks::IsSupportedWin() { - static bool is_supported = GetQueryThreadCycleTimeFunction() && - base::CPU().has_non_stop_time_stamp_counter() && - !IsBuggyAthlon(base::CPU()); - return is_supported; -} - -// static -void ThreadTicks::WaitUntilInitializedWin() { - while (TSCTicksPerSecond() == 0) - ::Sleep(10); -} - -double ThreadTicks::TSCTicksPerSecond() { - DCHECK(IsSupported()); - - // The value returned by QueryPerformanceFrequency() cannot be used as the TSC - // frequency, because there is no guarantee that the TSC frequency is equal to - // the performance counter frequency. - - // The TSC frequency is cached in a static variable because it takes some time - // to compute it. - static double tsc_ticks_per_second = 0; - if (tsc_ticks_per_second != 0) - return tsc_ticks_per_second; - - // Increase the thread priority to reduces the chances of having a context - // switch during a reading of the TSC and the performance counter. - int previous_priority = ::GetThreadPriority(::GetCurrentThread()); - ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - - // The first time that this function is called, make an initial reading of the - // TSC and the performance counter. - static const uint64_t tsc_initial = __rdtsc(); - static const uint64_t perf_counter_initial = QPCNowRaw(); - - // Make a another reading of the TSC and the performance counter every time - // that this function is called. - uint64_t tsc_now = __rdtsc(); - uint64_t perf_counter_now = QPCNowRaw(); - - // Reset the thread priority. - ::SetThreadPriority(::GetCurrentThread(), previous_priority); - - // Make sure that at least 50 ms elapsed between the 2 readings. The first - // time that this function is called, we don't expect this to be the case. - // Note: The longer the elapsed time between the 2 readings is, the more - // accurate the computed TSC frequency will be. The 50 ms value was - // chosen because local benchmarks show that it allows us to get a - // stddev of less than 1 tick/us between multiple runs. - // Note: According to the MSDN documentation for QueryPerformanceFrequency(), - // this will never fail on systems that run XP or later. - // https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx - LARGE_INTEGER perf_counter_frequency = {}; - ::QueryPerformanceFrequency(&perf_counter_frequency); - DCHECK_GE(perf_counter_now, perf_counter_initial); - uint64_t perf_counter_ticks = perf_counter_now - perf_counter_initial; - double elapsed_time_seconds = - perf_counter_ticks / static_cast<double>(perf_counter_frequency.QuadPart); - - const double kMinimumEvaluationPeriodSeconds = 0.05; - if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds) - return 0; - - // Compute the frequency of the TSC. - DCHECK_GE(tsc_now, tsc_initial); - uint64_t tsc_ticks = tsc_now - tsc_initial; - tsc_ticks_per_second = tsc_ticks / elapsed_time_seconds; - - return tsc_ticks_per_second; -} - -// static -TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { - return TimeTicks() + QPCValueToTimeDelta(qpc_value); -} - -// TimeDelta ------------------------------------------------------------------ - -// static -TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { - return QPCValueToTimeDelta(qpc_value); -} |