summaryrefslogtreecommitdiff
path: root/gn/util/ticks.cc
blob: 2a90c90e310189f4c33f9b28633f6f0537badca4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// 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) || defined(OS_AIX)
#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) || defined(OS_AIX)
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) || defined(OS_AIX)
  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) || defined(OS_AIX)
  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);
}