1// Copyright 2018 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ticks.h" 6 7#include "base/logging.h" 8#include "build_config.h" 9 10#if defined(OS_WIN) 11#include <windows.h> 12#elif defined(OS_MACOSX) 13#include <mach/mach_time.h> 14#elif defined(OS_POSIX) 15#include <time.h> 16#else 17#error Port. 18#endif 19 20namespace { 21 22bool g_initialized; 23 24#if defined(OS_WIN) 25LARGE_INTEGER g_frequency; 26LARGE_INTEGER g_start; 27#elif defined(OS_MACOSX) 28mach_timebase_info_data_t g_timebase; 29uint64_t g_start; 30#elif defined(OS_POSIX) 31uint64_t g_start; 32#else 33#error Port. 34#endif 35 36#if !defined(OS_MACOSX) 37constexpr uint64_t kNano = 1'000'000'000; 38#endif 39 40void Init() { 41 DCHECK(!g_initialized); 42 43#if defined(OS_WIN) 44 QueryPerformanceFrequency(&g_frequency); 45 QueryPerformanceCounter(&g_start); 46#elif defined(OS_MACOSX) 47 mach_timebase_info(&g_timebase); 48 g_start = (mach_absolute_time() * g_timebase.numer) / g_timebase.denom; 49#elif defined(OS_POSIX) 50 struct timespec ts; 51 clock_gettime(CLOCK_MONOTONIC, &ts); 52 g_start = static_cast<uint64_t>(ts.tv_sec) * kNano + 53 static_cast<uint64_t>(ts.tv_nsec); 54#else 55#error Port. 56#endif 57 58 g_initialized = true; 59} 60 61} // namespace 62 63Ticks TicksNow() { 64 static bool initialized = []() { 65 Init(); 66 return true; 67 }(); 68 DCHECK(initialized); 69 70 Ticks now; 71 72#if defined(OS_WIN) 73 LARGE_INTEGER t; 74 QueryPerformanceCounter(&t); 75 now = ((t.QuadPart - g_start.QuadPart) * kNano) / g_frequency.QuadPart; 76#elif defined(OS_MACOSX) 77 now = 78 ((mach_absolute_time() * g_timebase.numer) / g_timebase.denom) - g_start; 79#elif defined(OS_POSIX) 80 struct timespec ts; 81 clock_gettime(CLOCK_MONOTONIC, &ts); 82 now = (static_cast<uint64_t>(ts.tv_sec) * kNano + 83 static_cast<uint64_t>(ts.tv_nsec)) - 84 g_start; 85#else 86#error Port. 87#endif 88 89 return now; 90} 91 92TickDelta TicksDelta(Ticks new_ticks, Ticks old_ticks) { 93 DCHECK(new_ticks >= old_ticks); 94 return TickDelta(new_ticks - old_ticks); 95} 96