|  | // Copyright 2018 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 "ticks.h" | 
|  |  | 
|  | #include "base/logging.h" | 
|  | #include "build_config.h" | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | #include <windows.h> | 
|  | #elif defined(OS_MACOSX) | 
|  | #include <mach/mach_time.h> | 
|  | #elif defined(OS_LINUX) | 
|  | #include <time.h> | 
|  | #else | 
|  | #error Port. | 
|  | #endif | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | bool g_initialized; | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | LARGE_INTEGER g_frequency; | 
|  | LARGE_INTEGER g_start; | 
|  | #elif defined(OS_MACOSX) | 
|  | mach_timebase_info_data_t g_timebase; | 
|  | uint64_t g_start; | 
|  | #elif defined(OS_LINUX) | 
|  | uint64_t g_start; | 
|  | #else | 
|  | #error Port. | 
|  | #endif | 
|  |  | 
|  | constexpr uint64_t kNano = 1'000'000'000; | 
|  |  | 
|  | void Init() { | 
|  | DCHECK(!g_initialized); | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | QueryPerformanceFrequency(&g_frequency); | 
|  | QueryPerformanceCounter(&g_start); | 
|  | #elif defined(OS_MACOSX) | 
|  | mach_timebase_info(&g_timebase); | 
|  | g_start = (mach_absolute_time() * g_timebase.numer) / g_timebase.denom; | 
|  | #elif defined(OS_LINUX) | 
|  | struct timespec ts; | 
|  | clock_gettime(CLOCK_MONOTONIC, &ts); | 
|  | g_start = static_cast<uint64_t>(ts.tv_sec) * kNano + | 
|  | static_cast<uint64_t>(ts.tv_nsec); | 
|  | #else | 
|  | #error Port. | 
|  | #endif | 
|  |  | 
|  | g_initialized = true; | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | Ticks TicksNow() { | 
|  | static bool initialized = []() { | 
|  | Init(); | 
|  | return true; | 
|  | }(); | 
|  | DCHECK(initialized); | 
|  |  | 
|  | Ticks now; | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | LARGE_INTEGER t; | 
|  | QueryPerformanceCounter(&t); | 
|  | now = ((t.QuadPart - g_start.QuadPart) * kNano) / g_frequency.QuadPart; | 
|  | #elif defined(OS_MACOSX) | 
|  | now = | 
|  | ((mach_absolute_time() * g_timebase.numer) / g_timebase.denom) - g_start; | 
|  | #elif defined(OS_LINUX) | 
|  | struct timespec ts; | 
|  | clock_gettime(CLOCK_MONOTONIC, &ts); | 
|  | now = (static_cast<uint64_t>(ts.tv_sec) * kNano + | 
|  | static_cast<uint64_t>(ts.tv_nsec)) - | 
|  | g_start; | 
|  | #else | 
|  | #error Port. | 
|  | #endif | 
|  |  | 
|  | return now; | 
|  | } | 
|  |  | 
|  | TickDelta TicksDelta(Ticks new_ticks, Ticks old_ticks) { | 
|  | DCHECK(new_ticks >= old_ticks); | 
|  | return TickDelta(new_ticks - old_ticks); | 
|  | } |