| // Copyright 2017 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 <zircon/syscalls.h> | 
 |  | 
 | #include "base/compiler_specific.h" | 
 | #include "base/numerics/checked_math.h" | 
 | #include "base/time/time_override.h" | 
 |  | 
 | namespace base { | 
 |  | 
 | namespace { | 
 |  | 
 | // Helper function to map an unsigned integer with nanosecond timebase to a | 
 | // signed integer with microsecond timebase. | 
 | ALWAYS_INLINE int64_t ZxTimeToMicroseconds(zx_time_t nanos) { | 
 |   const zx_time_t micros = | 
 |       nanos / static_cast<zx_time_t>(base::Time::kNanosecondsPerMicrosecond); | 
 |   return static_cast<int64_t>(micros); | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | // Time ----------------------------------------------------------------------- | 
 |  | 
 | namespace subtle { | 
 | Time TimeNowIgnoringOverride() { | 
 |   const zx_time_t nanos_since_unix_epoch = zx_clock_get(ZX_CLOCK_UTC); | 
 |   CHECK(nanos_since_unix_epoch != 0); | 
 |   // The following expression will overflow in the year 289938 A.D.: | 
 |   return Time() + TimeDelta::FromMicroseconds( | 
 |                       ZxTimeToMicroseconds(nanos_since_unix_epoch) + | 
 |                       Time::kTimeTToMicrosecondsOffset); | 
 | } | 
 |  | 
 | Time TimeNowFromSystemTimeIgnoringOverride() { | 
 |   // Just use TimeNowIgnoringOverride() because it returns the system time. | 
 |   return TimeNowIgnoringOverride(); | 
 | } | 
 | }  // namespace subtle | 
 |  | 
 | // TimeTicks ------------------------------------------------------------------ | 
 |  | 
 | namespace subtle { | 
 | TimeTicks TimeTicksNowIgnoringOverride() { | 
 |   const zx_time_t nanos_since_boot = zx_clock_get(ZX_CLOCK_MONOTONIC); | 
 |   CHECK(nanos_since_boot != 0); | 
 |   return TimeTicks() + | 
 |          TimeDelta::FromMicroseconds(ZxTimeToMicroseconds(nanos_since_boot)); | 
 | } | 
 | }  // namespace subtle | 
 |  | 
 | // static | 
 | TimeTicks::Clock TimeTicks::GetClock() { | 
 |   return Clock::FUCHSIA_ZX_CLOCK_MONOTONIC; | 
 | } | 
 |  | 
 | // static | 
 | bool TimeTicks::IsHighResolution() { | 
 |   return true; | 
 | } | 
 |  | 
 | // static | 
 | bool TimeTicks::IsConsistentAcrossProcesses() { | 
 |   return true; | 
 | } | 
 |  | 
 | // static | 
 | TimeTicks TimeTicks::FromZxTime(zx_time_t nanos_since_boot) { | 
 |   return TimeTicks(ZxTimeToMicroseconds(nanos_since_boot)); | 
 | } | 
 |  | 
 | zx_time_t TimeTicks::ToZxTime() const { | 
 |   CheckedNumeric<zx_time_t> result(base::Time::kNanosecondsPerMicrosecond); | 
 |   result *= us_; | 
 |   return result.ValueOrDie(); | 
 | } | 
 |  | 
 | // ThreadTicks ---------------------------------------------------------------- | 
 |  | 
 | namespace subtle { | 
 | ThreadTicks ThreadTicksNowIgnoringOverride() { | 
 |   const zx_time_t nanos_since_thread_started = zx_clock_get(ZX_CLOCK_THREAD); | 
 |   CHECK(nanos_since_thread_started != 0); | 
 |   return ThreadTicks() + TimeDelta::FromMicroseconds( | 
 |                              ZxTimeToMicroseconds(nanos_since_thread_started)); | 
 | } | 
 | }  // namespace subtle | 
 |  | 
 | }  // namespace base |