Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #pragma once
18 : :
19 : : #include <atomic>
20 : :
21 : : #include "wirestead/base/common.hpp"
22 : :
23 : : namespace wirestead {
24 : : namespace concurrency {
25 : :
26 : : /**
27 : : * @brief Thread-safe atomic state wrapper
28 : : *
29 : : * Lightweight wrapper for atomic state management.
30 : : */
31 : : template <typename StateType>
32 : : class AtomicState {
33 : : public:
34 : : using State = StateType;
35 : :
36 : : explicit AtomicState(const State& initial_state = State{});
37 : :
38 : : State get() const noexcept;
39 : : void set(const State& new_state) noexcept;
40 : : void set(State&& new_state) noexcept;
41 : :
42 : : bool compare_and_set(const State& expected, const State& desired) noexcept;
43 : : State exchange(const State& new_state) noexcept;
44 : :
45 : : bool is_state(const State& expected_state) const noexcept;
46 : :
47 : : private:
48 : : std::atomic<State> state_;
49 : : };
50 : :
51 : : // Specialization for LinkState
52 : : using AtomicLinkState = AtomicState<base::LinkState>;
53 : :
54 : : // AtomicState template implementations
55 : : template <typename StateType>
56 : 2108 : AtomicState<StateType>::AtomicState(const State& initial_state) : state_(initial_state) {}
57 : :
58 : : template <typename StateType>
59 : 9132 : StateType AtomicState<StateType>::get() const noexcept {
60 : 9132 : return state_.load();
61 : : }
62 : :
63 : : template <typename StateType>
64 : 4515 : void AtomicState<StateType>::set(const State& new_state) noexcept {
65 : 4515 : state_.store(new_state);
66 : 4515 : }
67 : :
68 : : template <typename StateType>
69 : 4891 : void AtomicState<StateType>::set(State&& new_state) noexcept {
70 : 4891 : state_.store(new_state);
71 : 4891 : }
72 : :
73 : : template <typename StateType>
74 : : bool AtomicState<StateType>::compare_and_set(const State& expected, const State& desired) noexcept {
75 : : State expected_copy = expected;
76 : : return state_.compare_exchange_strong(expected_copy, desired);
77 : : }
78 : :
79 : : template <typename StateType>
80 : : StateType AtomicState<StateType>::exchange(const State& new_state) noexcept {
81 : : return state_.exchange(new_state);
82 : : }
83 : :
84 : : template <typename StateType>
85 : 1143022 : bool AtomicState<StateType>::is_state(const State& expected_state) const noexcept {
86 : 1143022 : return state_.load() == expected_state;
87 : : }
88 : :
89 : : } // namespace concurrency
90 : : } // namespace wirestead
|