]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/Cycles.h
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / common / Cycles.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2014 UnitedStack <haomai@unitedstack.com>
7 *
8 * Author: Haomai Wang <haomaiwang@gmail.com>
9 *
10 * This is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License version 2.1, as published by the Free Software
13 * Foundation. See file COPYING.
14 *
15 */
16 /* Copyright (c) 2011-2014 Stanford University
17 *
18 * Permission to use, copy, modify, and distribute this software for any
19 * purpose with or without fee is hereby granted, provided that the above
20 * copyright notice and this permission notice appear in all copies.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
23 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
25 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 */
30
31
32 #ifndef CEPH_CYCLES_H
33 #define CEPH_CYCLES_H
34
35 #include <cstdint>
36
37 /**
38 * This class provides static methods that read the fine-grain CPU
39 * cycle counter and translate between cycle-level times and absolute
40 * times.
41 */
42 class Cycles {
43 public:
44 static void init();
45
46 /**
47 * Return the current value of the fine-grain CPU cycle counter
48 * (accessed via the RDTSC instruction).
49 */
50 static __inline __attribute__((always_inline)) uint64_t rdtsc() {
51 #if defined(__i386__)
52 int64_t ret;
53 __asm__ volatile ("rdtsc" : "=A" (ret) );
54 return ret;
55 #elif defined(__x86_64__) || defined(__amd64__)
56 uint32_t lo, hi;
57 __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));
58 return (((uint64_t)hi << 32) | lo);
59 #elif defined(__aarch64__)
60 //
61 // arch/arm64/include/asm/arch_timer.h
62 //
63 // static inline u64 arch_counter_get_cntvct(void)
64 // {
65 // u64 cval;
66 //
67 // isb();
68 // asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
69 //
70 // return cval;
71 // }
72 //
73 // https://github.com/cloudius-systems/osv/blob/master/arch/aarch64/arm-clock.cc
74 uint64_t cntvct;
75 asm volatile ("isb; mrs %0, cntvct_el0; isb; " : "=r" (cntvct) :: "memory");
76 return cntvct;
77 #elif defined(__powerpc__) || defined (__powerpc64__)
78 // Based on:
79 // https://github.com/randombit/botan/blob/net.randombit.botan/src/lib/entropy/hres_timer/hres_timer.cpp
80 uint32_t lo = 0, hi = 0;
81 asm volatile("mftbu %0; mftb %1" : "=r" (hi), "=r" (lo));
82 return (((uint64_t)hi << 32) | lo);
83 #elif defined(__s390__)
84 uint64_t tsc;
85 asm volatile("stck %0" : "=Q" (tsc) : : "cc");
86 return tsc;
87 #else
88 #warning No high-precision counter available for your OS/arch
89 return 0;
90 #endif
91 }
92
93 static double per_second();
94 static double to_seconds(uint64_t cycles, double cycles_per_sec = 0);
95 static uint64_t from_seconds(double seconds, double cycles_per_sec = 0);
96 static uint64_t to_microseconds(uint64_t cycles, double cycles_per_sec = 0);
97 static uint64_t to_nanoseconds(uint64_t cycles, double cycles_per_sec = 0);
98 static uint64_t from_nanoseconds(uint64_t ns, double cycles_per_sec = 0);
99 static void sleep(uint64_t us);
100
101 private:
102 Cycles();
103
104 /// Conversion factor between cycles and the seconds; computed by
105 /// Cycles::init.
106 static double cycles_per_sec;
107
108 /**
109 * Returns the conversion factor between cycles in seconds, using
110 * a mock value for testing when appropriate.
111 */
112 static __inline __attribute__((always_inline)) double get_cycles_per_sec() {
113 return cycles_per_sec;
114 }
115 };
116
117 #endif // CEPH_CYCLES_H