6#include <userver/concurrent/striped_counter.hpp>
7#include <userver/utils/assert.hpp>
13class StripedReadIndicatorLock;
31class StripedReadIndicator
final {
34 StripedReadIndicator();
36 StripedReadIndicator(StripedReadIndicator&&) =
delete;
37 StripedReadIndicator& operator=(StripedReadIndicator&&) =
delete;
38 ~StripedReadIndicator();
53 StripedReadIndicatorLock Lock()
noexcept;
62 bool IsFree()
const noexcept;
66 template <
typename StripedReadIndicatorRange>
67 static bool AreAllFree(StripedReadIndicatorRange&& indicators) {
69 std::uintptr_t released = 0;
70 for (
const auto& indicator : indicators) {
71 released += indicator.released_count_.Read();
74 std::uintptr_t acquired = 0;
75 for (
const auto& indicator : indicators) {
76 acquired += indicator.acquired_count_.Read();
80 std::numeric_limits<std::uintptr_t>::max() / 2);
81 return acquired == released;
85 std::uintptr_t GetAcquireCountApprox()
const noexcept;
88 std::uintptr_t GetReleaseCountApprox()
const noexcept;
91 std::uintptr_t GetActiveCountApprox()
const noexcept;
94 friend class StripedReadIndicatorLock;
96 void DoLock()
noexcept;
97 void DoUnlock()
noexcept;
99 StripedCounter acquired_count_;
100 StripedCounter released_count_;
104class [[nodiscard]] StripedReadIndicatorLock
final {
107 StripedReadIndicatorLock()
noexcept =
default;
109 StripedReadIndicatorLock(StripedReadIndicatorLock&&)
noexcept;
110 StripedReadIndicatorLock(
const StripedReadIndicatorLock&)
noexcept;
111 StripedReadIndicatorLock& operator=(StripedReadIndicatorLock&&)
noexcept;
112 StripedReadIndicatorLock& operator=(
const StripedReadIndicatorLock&)
noexcept;
113 ~StripedReadIndicatorLock();
116 explicit StripedReadIndicatorLock(StripedReadIndicator& indicator)
noexcept;
118 friend class StripedReadIndicator;
120 StripedReadIndicator* indicator_{
nullptr};