Telamon
OperationHelping.hh
1 #ifndef TELAMON_OPERATION_HELPING_HH
2 #define TELAMON_OPERATION_HELPING_HH
3 
4 #include <thread>
5 #include <variant>
6 #include <utility>
7 
9 
10 namespace telamon_simulator {
11 
13 template<NormalizedRepresentation LockFree>
15  using Output = typename LockFree::Output;
16  using Input = typename LockFree::Input;
17  using Commit = typename LockFree::Commit;
18  public:
20  struct PreCas {
21  PreCas () = default;
22  PreCas (const PreCas &) = default;
23  };
25  struct ExecutingCas {
26  Commit cas_list;
27  explicit ExecutingCas (Commit t_cas_list) : cas_list{std::move(t_cas_list)} {}
28  ExecutingCas (const ExecutingCas &) = default;
29  };
31  struct PostCas {
32  Commit cas_list;
33  nonstd::expected<std::monostate, std::optional<int>> executed;
34  PostCas (Commit t_cas_list, nonstd::expected<std::monostate, std::optional<int>> t_executed) : cas_list{t_cas_list},
35  executed{std::move(t_executed)} {}
36  PostCas (const PostCas &) = default;
37  };
39  struct Completed {
40  Output output;
41  explicit Completed (Output t_output) : output{std::move(t_output)} {}
42  Completed (const Completed &) = default;
43  };
44 
45  using OperationState = std::variant<PreCas, ExecutingCas, PostCas, Completed>;
46 
47  public:
48  OperationRecord (int t_owner, OperationState t_state, const typename LockFree::Input &t_input)
49  : m_owner{t_owner},
50  m_input{t_input},
51  m_state{std::move(t_state)} {}
52 
53  OperationRecord (const OperationRecord &copy, OperationState t_state)
54  : m_owner{copy.m_owner},
55  m_input{copy.m_input},
56  m_state{std::move(t_state)} {}
57 
58  OperationRecord (OperationRecord &&) noexcept = default;
59  OperationRecord (const OperationRecord &) = default;
60 
61  bool operator== (const OperationRecord &rhs) const {
62  return std::tie(m_owner, m_input) == std::tie(rhs.m_owner, rhs.m_input);
63  }
64  bool operator!= (const OperationRecord &rhs) const {
65  return !(rhs == *this);
66  }
67 
68  public:
69  [[nodiscard]] auto owner () const noexcept -> int { return m_owner; }
70  [[nodiscard]] auto state () const noexcept -> OperationState { return m_state; }
71  [[nodiscard]] auto input () const noexcept -> const typename LockFree::Input & { return m_input; }
72 
73  [[maybe_unused]] void set_state (const OperationState &t_state) noexcept { m_state = t_state; }
74 
75  private:
76  int m_owner;
77  OperationState m_state;
78  const typename LockFree::Input &m_input;
79 
80  static_assert(std::is_copy_constructible_v<OperationState>);
81 };
82 
84 template<typename LockFree> requires NormalizedRepresentation<LockFree>
86  public:
87  OperationRecordBox (int t_owner, typename OperationRecord<LockFree>::OperationState t_state, const typename LockFree::Input &t_input)
88  : m_ptr{new OperationRecord<LockFree>{t_owner, t_state, t_input}} {}
89 
90  OperationRecordBox (OperationRecordBox &&rhs) noexcept: m_ptr{std::move(rhs.m_ptr.load())} {}
91  OperationRecordBox (const OperationRecordBox &rhs) noexcept: m_ptr{rhs.m_ptr.load()} {}
92 
93  bool operator== (const OperationRecordBox &rhs) const {
94  return *m_ptr.load() == *rhs.m_ptr.load();
95  }
96 
97  bool operator!= (const OperationRecordBox &rhs) const {
98  return !(rhs == *this);
99  }
100 
101  [[nodiscard]] auto state() const noexcept -> typename OperationRecord<LockFree>::OperationState { return m_ptr.load()->state(); }
102 
103  [[nodiscard]] auto ptr () const noexcept -> OperationRecord<LockFree> * { return m_ptr.load(); }
104 
105  [[maybe_unused]] auto atomic_ptr () noexcept -> std::atomic<OperationRecord<LockFree> *> & { return m_ptr; }
106 
107  [[maybe_unused]] auto nonatomic_ptr () const noexcept -> OperationRecord<LockFree> * { return m_ptr; }
108 
110  auto swap (OperationRecordBox desired, OperationRecordBox *expected_ptr) -> bool {
111  auto desired_ptr = new OperationRecord{std::move(desired)}; //< TODO: Use folly/Hazptr
112  return m_ptr.compare_exchange_strong(expected_ptr, desired_ptr);
113  }
114 
115  private:
116  // TODO: Use folly/Hazptr
117  std::atomic<OperationRecord<LockFree> *> m_ptr;
118 };
119 
120 }
121 
122 #endif // TELAMON_OPERATION_HELPING_HH
Provides the foundational structure of a normalized structure which the simulated algorithm is requir...
A class which represents a single operation stored in the help queue.
Definition: OperationHelping.hh:85
auto swap(OperationRecordBox desired, OperationRecordBox *expected_ptr) -> bool
Atomically swaps the pointer m_ptr with pointer the given box record.
Definition: OperationHelping.hh:110
A class which represents a single operation contained in a OperationRecordBox.
Definition: OperationHelping.hh:14
This module encapsulates the implementation of the simulator.
Definition: NormalizedRepresentation.hh:25
Meta data related to CAS which is complete.
Definition: OperationHelping.hh:39
Meta data related to CAS which is going to be executed.
Definition: OperationHelping.hh:25
Meta data related to CAS which has already been executed.
Definition: OperationHelping.hh:31
Meta data related to CAS which is still pending.
Definition: OperationHelping.hh:20