11 using Snapshot = uint64_t;
14 Snapshot state = __atomic_load_n(&m_State, __ATOMIC_RELAXED);
16 if ((state & DepthMask) == DepthMask) {
17 panic(
"RCU reader nesting overflow.");
19 }
while (!__atomic_compare_exchange_n(&m_State, &state, state + 1,
true, __ATOMIC_SEQ_CST,
24 Snapshot state = __atomic_load_n(&m_State, __ATOMIC_RELAXED);
27 const Snapshot depth = state & DepthMask;
29 panic(
"RCU reader nesting underflow.");
32 next = depth == 1 ? state + Generation - 1 : state - 1;
33 }
while (!__atomic_compare_exchange_n(&m_State, &state, next,
true, __ATOMIC_RELEASE,
37 Snapshot snapshot()
const {
38 return __atomic_load_n(&m_State, __ATOMIC_SEQ_CST);
41 bool passed(Snapshot before)
const {
42 if (!(before & DepthMask)) {
45 const Snapshot now = __atomic_load_n(&m_State, __ATOMIC_ACQUIRE);
46 return !(now & DepthMask) || (now & ~DepthMask) != (before & ~DepthMask);
50 return (__atomic_load_n(&m_State, __ATOMIC_RELAXED) & DepthMask) != 0;
54 static constexpr Snapshot Generation = Snapshot{1} << 32;
55 static constexpr Snapshot DepthMask = Generation - 1;
56 static_assert(__atomic_always_lock_free(
sizeof(Snapshot),
nullptr));
57 alignas(
sizeof(Snapshot)) Snapshot m_State = 0;