]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/include/seastar/core/lowres_clock.hh
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / seastar / include / seastar / core / lowres_clock.hh
CommitLineData
11fdf7f2
TL
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright (C) 2016 ScyllaDB
20 */
21
22#pragma once
23
24#include <seastar/core/cacheline.hh>
25#include <seastar/core/timer.hh>
26
27#include <cstdint>
28
29#include <atomic>
30#include <chrono>
31
32namespace seastar {
33
34//
35// Forward declarations.
36//
37
38class lowres_clock;
39class lowres_system_clock;
40
41/// \cond internal
42
43class lowres_clock_impl final {
44public:
45 using base_steady_clock = std::chrono::steady_clock;
46 using base_system_clock = std::chrono::system_clock;
47
48 // The clocks' resolutions are 10 ms. However, to make it is easier to do calculations with
49 // `std::chrono::milliseconds`, we make the clock period 1 ms instead of 10 ms.
50 using period = std::ratio<1, 1000>;
51
52 using steady_rep = base_steady_clock::rep;
53 using steady_duration = std::chrono::duration<steady_rep, period>;
54 using steady_time_point = std::chrono::time_point<lowres_clock, steady_duration>;
55
56 using system_rep = base_system_clock::rep;
57 using system_duration = std::chrono::duration<system_rep, period>;
58 using system_time_point = std::chrono::time_point<lowres_system_clock, system_duration>;
59
f67539c2 60 static steady_time_point steady_now() noexcept {
11fdf7f2
TL
61 auto const nr = counters::_steady_now.load(std::memory_order_relaxed);
62 return steady_time_point(steady_duration(nr));
63 }
64
f67539c2 65 static system_time_point system_now() noexcept {
11fdf7f2
TL
66 auto const nr = counters::_system_now.load(std::memory_order_relaxed);
67 return system_time_point(system_duration(nr));
68 }
69
70 // For construction.
71 friend class smp;
72private:
73 // Both counters are updated by cpu0 and read by other cpus. Place them on their own cache line to avoid false
74 // sharing.
75 struct alignas(seastar::cache_line_size) counters final {
76 static std::atomic<steady_rep> _steady_now;
77 static std::atomic<system_rep> _system_now;
78 };
79
80 // The timer expires every 10 ms.
81 static constexpr std::chrono::milliseconds _granularity{10};
82
83 // High-resolution timer to drive these low-resolution clocks.
84 timer<> _timer{};
85
f67539c2 86 static void update() noexcept;
11fdf7f2
TL
87
88 // Private to ensure that static variables are only initialized once.
f67539c2 89 // might throw when arming timer.
11fdf7f2
TL
90 lowres_clock_impl();
91};
92
93/// \endcond
94
95//
96/// \brief Low-resolution and efficient steady clock.
97///
98/// This is a monotonic clock with a granularity of 10 ms. Time points from this clock do not correspond to system
99/// time.
100///
101/// The primary benefit of this clock is that invoking \c now() is inexpensive compared to
102/// \c std::chrono::steady_clock::now().
103///
104/// \see \c lowres_system_clock for a low-resolution clock which produces time points corresponding to system time.
105///
106class lowres_clock final {
107public:
108 using rep = lowres_clock_impl::steady_rep;
109 using period = lowres_clock_impl::period;
110 using duration = lowres_clock_impl::steady_duration;
111 using time_point = lowres_clock_impl::steady_time_point;
112
113 static constexpr bool is_steady = true;
114
115 ///
116 /// \note Outside of a Seastar application, the result is undefined.
117 ///
f67539c2 118 static time_point now() noexcept {
11fdf7f2
TL
119 return lowres_clock_impl::steady_now();
120 }
121};
122
123///
124/// \brief Low-resolution and efficient system clock.
125///
126/// This clock has the same granularity as \c lowres_clock, but it is not required to be monotonic and its time points
127/// correspond to system time.
128///
129/// The primary benefit of this clock is that invoking \c now() is inexpensive compared to
130/// \c std::chrono::system_clock::now().
131///
132class lowres_system_clock final {
133public:
134 using rep = lowres_clock_impl::system_rep;
135 using period = lowres_clock_impl::period;
136 using duration = lowres_clock_impl::system_duration;
137 using time_point = lowres_clock_impl::system_time_point;
138
139 static constexpr bool is_steady = lowres_clock_impl::base_system_clock::is_steady;
140
141 ///
142 /// \note Outside of a Seastar application, the result is undefined.
143 ///
f67539c2 144 static time_point now() noexcept {
11fdf7f2
TL
145 return lowres_clock_impl::system_now();
146 }
147
f67539c2 148 static std::time_t to_time_t(time_point t) noexcept {
11fdf7f2
TL
149 return std::chrono::duration_cast<std::chrono::seconds>(t.time_since_epoch()).count();
150 }
151
f67539c2 152 static time_point from_time_t(std::time_t t) noexcept {
11fdf7f2
TL
153 return time_point(std::chrono::duration_cast<duration>(std::chrono::seconds(t)));
154 }
155};
156
9f95a23c
TL
157extern template class timer<lowres_clock>;
158
11fdf7f2
TL
159}
160