zpp
Zephyr C++20 Framework
futex.hpp
Go to the documentation of this file.
1 
7 #ifndef ZPP_INCLUDE_ZPP_FUTEX_HPP
8 #define ZPP_INCLUDE_ZPP_FUTEX_HPP
9 
10 #ifdef CONFIG_USERSPACE
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/sys/__assert.h>
14 
15 #include <chrono>
16 
17 namespace zpp {
18 
22 template<typename T_Futex>
24 {
25 public:
26  using native_type = struct k_futex;
29 protected:
33  constexpr futex_base() noexcept
34  {
35  }
36 
37 public:
45  [[nodiscard]] bool wait(int expected) noexcept
46  {
47  if (futex_wait(native_handle(), expected, K_FOREVER) == 0) {
48  return true;
49  } else {
50  return false;
51  }
52  }
53 
61  [[nodiscard]] bool try_wait(int expected) noexcept
62  {
63  if (futex_wait(native_handle(), expected, K_NO_WAIT) == 0) {
64  return true;
65  } else {
66  return false;
67  }
68  }
69 
78  template<class T_Rep, class T_Period>
79  [[nodiscard]] bool
80  try_wait_for(int expected, const std::chrono::duration<T_Rep, T_Period>& timeout) noexcept
81  {
82  using namespace std::chrono;
83 
84  if (futex_wait(native_handle(), expected, to_timeout(timeout)) == 0)
85  {
86  return true;
87  } else {
88  return false;
89  }
90  }
91 
95  void wake_one() noexcept
96  {
97  futex_wake(native_handle(), false);
98  }
99 
103  void wake_all() noexcept
104  {
105  futex_wake(native_handle(), true);
106  }
107 
113  auto native_handle() noexcept -> native_pointer
114  {
115  return static_cast<T_Futex*>(this)->native_handle();
116  }
117 
123  auto native_handle() const noexcept -> native_const_pointer
124  {
125  return static_cast<const T_Futex*>(this)->native_handle();
126  }
127 public:
128  futex_base(const futex_base&) = delete;
129  futex_base(futex_base&&) = delete;
130  futex_base& operator=(const futex_base&) = delete;
132 };
133 
137 class futex : public futex_base<futex> {
138 public:
144  constexpr auto native_handle() noexcept -> native_pointer
145  {
146  return &m_futex;
147  }
148 
154  constexpr auto native_handle() const noexcept -> native_const_pointer
155  {
156  return &m_futex;
157  }
158 private:
159  native_type m_futex{};
160 public:
161  futex(const futex&) = delete;
162  futex(futex&&) = delete;
163  futex& operator=(const futex&) = delete;
164  futex& operator=(futex&&) = delete;
165 };
166 
170 class futex_ref : public futex_base<futex_ref> {
171 public:
178  explicit constexpr futex_ref(native_pointer f) noexcept
179  : m_futex_ptr(f)
180  {
181  __ASSERT_NO_MSG(m_futex_ptr != nullptr);
182  }
183 
190  template<typename T_Futex>
191  explicit constexpr futex_ref(T_Futex& f) noexcept
192  : m_futex_ptr(f.native_handle())
193  {
194  __ASSERT_NO_MSG(m_futex_ptr != nullptr);
195  }
196 
205  constexpr futex_ref& operator=(native_pointer f) noexcept
206  {
207  m_futex_ptr = f;
208  __ASSERT_NO_MSG(m_futex_ptr != nullptr);
209  return *this;
210  }
211 
220  template<typename T_Futex>
221  constexpr futex_ref& operator=(T_Futex& f) noexcept
222  {
223  m_futex_ptr = f.native_handle();
224  __ASSERT_NO_MSG(m_futex_ptr != nullptr);
225  return *this;
226  }
227 
233  constexpr auto native_handle() noexcept -> native_pointer
234  {
235  return m_futex_ptr;
236  }
237 
243  constexpr auto native_handle() const noexcept -> native_const_pointer
244  {
245  return m_futex_ptr;
246  }
247 private:
248  native_pointer m_futex_ptr{ nullptr };
249 public:
250  futex_ref() = delete;
251 };
252 
253 } // namespace zpp
254 
255 #endif // CONFIG_USERSPACE
256 
257 #endif // ZPP_INCLUDE_ZPP_FUTEX_HPP
A CRTP futex base class.
Definition: futex.hpp:24
bool try_wait(int expected) noexcept
Try wait for the futex.
Definition: futex.hpp:61
bool wait(int expected) noexcept
Wait for the futex.
Definition: futex.hpp:45
void wake_all() noexcept
Wakeup all waiting threads.
Definition: futex.hpp:103
bool try_wait_for(int expected, const std::chrono::duration< T_Rep, T_Period > &timeout) noexcept
Wait for the futex.
Definition: futex.hpp:80
futex_base & operator=(futex_base &&)=delete
auto native_handle() const noexcept -> native_const_pointer
get the native zephyr futex handle.
Definition: futex.hpp:123
struct k_futex native_type
Definition: futex.hpp:26
auto native_handle() noexcept -> native_pointer
get the native zephyr futex handle.
Definition: futex.hpp:113
futex_base(futex_base &&)=delete
constexpr futex_base() noexcept
Default constructor.
Definition: futex.hpp:33
futex_base(const futex_base &)=delete
native_type * native_pointer
Definition: futex.hpp:27
native_type const * native_const_pointer
Definition: futex.hpp:28
void wake_one() noexcept
Wakeup one waiting thread.
Definition: futex.hpp:95
futex_base & operator=(const futex_base &)=delete
A futex class referencing another futex object.
Definition: futex.hpp:170
constexpr auto native_handle() noexcept -> native_pointer
get the native zephyr futex handle.
Definition: futex.hpp:233
constexpr futex_ref & operator=(T_Futex &f) noexcept
copy operator
Definition: futex.hpp:221
constexpr auto native_handle() const noexcept -> native_const_pointer
get the native zephyr futex handle.
Definition: futex.hpp:243
constexpr futex_ref(native_pointer f) noexcept
Construct a futex using a native k_futex*.
Definition: futex.hpp:178
constexpr futex_ref & operator=(native_pointer f) noexcept
copy operator
Definition: futex.hpp:205
constexpr futex_ref(T_Futex &f) noexcept
Construct a futex using another futex object.
Definition: futex.hpp:191
futex_ref()=delete
A futex class.
Definition: futex.hpp:137
constexpr auto native_handle() const noexcept -> native_const_pointer
get the native zephyr futex handle.
Definition: futex.hpp:154
futex(futex &&)=delete
futex & operator=(futex &&)=delete
futex & operator=(const futex &)=delete
futex(const futex &)=delete
constexpr auto native_handle() noexcept -> native_pointer
get the native zephyr futex handle.
Definition: futex.hpp:144
constexpr k_timeout_t to_timeout(const std::chrono::duration< T_Rep, T_Period > &d) noexcept
convert a duration to tick
Definition: clock.hpp:88