Since compare and swap can fail when there are concurrent modifications, this wraps some of the boilerplate compare and swap retry logic. This performs the provided lambda in a loop until the compare and swap succeeds. The lambda is required to mutate the AtomicState argument passed to it. This returns a structure containing the old atomic value and new atomic value.
| 239 | // The lambda is required to mutate the AtomicState argument passed to it. |
| 240 | // This returns a structure containing the old atomic value and new atomic value. |
| 241 | AtomicStateTransition modify_atomic_state(const std::function<void(AtomicState&)>& fn) { |
| 242 | AtomicState old_atomic_state = atomic_state_.load(); |
| 243 | AtomicState new_atomic_state = old_atomic_state; |
| 244 | while (true) { |
| 245 | new_atomic_state = old_atomic_state; |
| 246 | // fn mutates new_atomic_state and must change something |
| 247 | fn(new_atomic_state); |
| 248 | DCHECK(old_atomic_state.ref_count != new_atomic_state.ref_count || |
| 249 | old_atomic_state.state != new_atomic_state.state || |
| 250 | old_atomic_state.residency != new_atomic_state.residency); |
| 251 | if (atomic_state_.compare_exchange_weak(old_atomic_state, new_atomic_state)) { |
| 252 | break; |
| 253 | } |
| 254 | } |
| 255 | return AtomicStateTransition(old_atomic_state, new_atomic_state); |
| 256 | } |
| 257 | |
| 258 | LIRSState state() const { |
| 259 | return atomic_state_.load().state; |
no test coverage detected