userver: userver/utils/statistics/relaxed_counter.hpp Source File
Loading...
Searching...
No Matches
relaxed_counter.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/statistics/relaxed_counter.hpp
4/// @brief @copybrief utils::statistics::RelaxedCounter
5
6#include <atomic>
7
8#include <userver/utils/statistics/fwd.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace utils::statistics {
13
14/// @brief Atomic counter of type T with relaxed memory ordering
15template <class T>
16class RelaxedCounter final {
17public:
18 using ValueType = T;
19
20 constexpr RelaxedCounter() noexcept = default;
21 constexpr RelaxedCounter(T desired) noexcept : val_(desired) {}
22
23 RelaxedCounter(const RelaxedCounter& other) noexcept : val_(other.Load()) {}
24
25 RelaxedCounter& operator=(const RelaxedCounter& other) noexcept {
26 if (this == &other) return *this;
27
28 Store(other.Load());
29 return *this;
30 }
31
32 RelaxedCounter& operator=(T desired) noexcept {
33 Store(desired);
34 return *this;
35 }
36
37 void Store(T desired) noexcept { val_.store(desired, std::memory_order_relaxed); }
38
39 T Load() const noexcept { return val_.load(std::memory_order_relaxed); }
40
41 operator T() const noexcept { return Load(); }
42
43 RelaxedCounter& operator++() noexcept {
44 val_.fetch_add(1, std::memory_order_relaxed);
45 return *this;
46 }
47
48 T operator++(int) noexcept { return val_.fetch_add(1, std::memory_order_relaxed); }
49
50 RelaxedCounter& operator--() noexcept {
51 val_.fetch_sub(1, std::memory_order_relaxed);
52 return *this;
53 }
54
55 T operator--(int) noexcept { return val_.fetch_sub(1, std::memory_order_relaxed); }
56
57 RelaxedCounter& operator+=(T arg) noexcept {
58 val_.fetch_add(arg, std::memory_order_relaxed);
59 return *this;
60 }
61
62 RelaxedCounter& operator-=(T arg) noexcept {
63 val_.fetch_sub(arg, std::memory_order_relaxed);
64 return *this;
65 }
66
67private:
68 static_assert(std::atomic<T>::is_always_lock_free);
69
70 std::atomic<T> val_{T{}};
71};
72
73template <typename T>
74void DumpMetric(Writer& writer, const RelaxedCounter<T>& value) {
75 writer = value.Load();
76}
77
78} // namespace utils::statistics
79
80USERVER_NAMESPACE_END