]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | /** | |
36 | * This class provides static methods that read the fine-grain CPU | |
37 | * cycle counter and translate between cycle-level times and absolute | |
38 | * times. | |
39 | */ | |
40 | class Cycles { | |
41 | public: | |
42 | static void init(); | |
43 | ||
44 | /** | |
45 | * Return the current value of the fine-grain CPU cycle counter | |
46 | * (accessed via the RDTSC instruction). | |
47 | */ | |
48 | static __inline __attribute__((always_inline)) uint64_t rdtsc() { | |
49 | #if defined(__i386__) | |
50 | int64_t ret; | |
51 | __asm__ volatile ("rdtsc" : "=A" (ret) ); | |
52 | return ret; | |
53 | #elif defined(__x86_64__) || defined(__amd64__) | |
54 | uint32_t lo, hi; | |
55 | __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi)); | |
56 | return (((uint64_t)hi << 32) | lo); | |
57 | #elif defined(__aarch64__) | |
58 | // | |
59 | // arch/arm64/include/asm/arch_timer.h | |
60 | // | |
61 | // static inline u64 arch_counter_get_cntvct(void) | |
62 | // { | |
63 | // u64 cval; | |
64 | // | |
65 | // isb(); | |
66 | // asm volatile("mrs %0, cntvct_el0" : "=r" (cval)); | |
67 | // | |
68 | // return cval; | |
69 | // } | |
70 | // | |
71 | // https://github.com/cloudius-systems/osv/blob/master/arch/aarch64/arm-clock.cc | |
72 | uint64_t cntvct; | |
73 | asm volatile ("isb; mrs %0, cntvct_el0; isb; " : "=r" (cntvct) :: "memory"); | |
74 | return cntvct; | |
75 | #elif defined(__powerpc__) || defined (__powerpc64__) | |
76 | // Based on: | |
77 | // https://github.com/randombit/botan/blob/net.randombit.botan/src/lib/entropy/hres_timer/hres_timer.cpp | |
78 | uint32_t lo = 0, hi = 0; | |
79 | asm volatile("mftbu %0; mftb %1" : "=r" (hi), "=r" (lo)); | |
80 | return (((uint64_t)hi << 32) | lo); | |
9f95a23c TL |
81 | #elif defined(__s390__) |
82 | uint64_t tsc; | |
83 | asm volatile("stck %0" : "=Q" (tsc) : : "cc"); | |
84 | return tsc; | |
7c673cae FG |
85 | #else |
86 | #warning No high-precision counter available for your OS/arch | |
87 | return 0; | |
88 | #endif | |
89 | } | |
90 | ||
91 | static double per_second(); | |
92 | static double to_seconds(uint64_t cycles, double cycles_per_sec = 0); | |
93 | static uint64_t from_seconds(double seconds, double cycles_per_sec = 0); | |
94 | static uint64_t to_microseconds(uint64_t cycles, double cycles_per_sec = 0); | |
95 | static uint64_t to_nanoseconds(uint64_t cycles, double cycles_per_sec = 0); | |
96 | static uint64_t from_nanoseconds(uint64_t ns, double cycles_per_sec = 0); | |
97 | static void sleep(uint64_t us); | |
98 | ||
99 | private: | |
100 | Cycles(); | |
101 | ||
102 | /// Conversion factor between cycles and the seconds; computed by | |
103 | /// Cycles::init. | |
104 | static double cycles_per_sec; | |
105 | ||
106 | /** | |
107 | * Returns the conversion factor between cycles in seconds, using | |
108 | * a mock value for testing when appropriate. | |
109 | */ | |
110 | static __inline __attribute__((always_inline)) double get_cycles_per_sec() { | |
111 | return cycles_per_sec; | |
112 | } | |
113 | }; | |
114 | ||
115 | #endif // CEPH_CYCLES_H |