zpp
Zephyr C++20 Framework
mutex.hpp
Go to the documentation of this file.
1 
7 #ifndef ZPP_INCLUDE_ZPP_MUTEX_HPP
8 #define ZPP_INCLUDE_ZPP_MUTEX_HPP
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/__assert.h>
12 
13 #include <chrono>
14 
15 #include <zpp/result.hpp>
16 #include <zpp/error_code.hpp>
17 
18 namespace zpp {
19 
23 template<typename T_Mutex>
25 {
26 public:
27  using native_type = struct k_mutex;
30 protected:
34  constexpr mutex_base() noexcept
35  {
36  }
37 
38 public:
44  [[nodiscard]] auto lock() noexcept
45  {
47 
48  auto rc = k_mutex_lock(native_handle(), K_FOREVER);
49  if (rc == 0) {
50  res.assign_value();
51  } else {
52  res.assign_error(to_error_code(-rc));
53  }
54 
55  return res;
56  }
57 
63  [[nodiscard]] auto try_lock() noexcept
64  {
66 
67  auto rc = k_mutex_lock(native_handle(), K_NO_WAIT);
68  if (rc == 0) {
69  res.assign_value();
70  } else {
71  res.assign_error(to_error_code(-rc));
72  }
73 
74  return res;
75  }
76 
84  template<class T_Rep, class T_Period>
85  [[nodiscard]] auto
86  try_lock_for(const std::chrono::duration<T_Rep, T_Period>& timeout) noexcept
87  {
88  using namespace std::chrono;
89 
91 
92  auto rc = k_mutex_lock(native_handle(), to_timeout(timeout));
93  if (rc == 0) {
94  res.assign_value();
95  } else {
96  res.assign_error(to_error_code(-rc));
97  }
98 
99  return res;
100  }
101 
107  [[nodiscard]] auto unlock() noexcept
108  {
110 
111  auto rc = k_mutex_unlock(native_handle());
112  if (rc == 0) {
113  res.assign_value();
114  } else {
115  res.assign_error(to_error_code(-rc));
116  }
117 
118  return res;
119  }
120 
126  auto native_handle() noexcept -> native_pointer
127  {
128  return static_cast<T_Mutex*>(this)->native_handle();
129  }
130 
136  auto native_handle() const noexcept -> native_const_pointer
137  {
138  return static_cast<const T_Mutex*>(this)->native_handle();
139  }
140 public:
141  mutex_base(const mutex_base&) = delete;
142  mutex_base(mutex_base&&) = delete;
143  mutex_base& operator=(const mutex_base&) = delete;
145 };
146 
150 class mutex : public mutex_base<mutex> {
151 public:
155  mutex() noexcept
156  {
157  k_mutex_init(&m_mutex);
158  }
159 
165  constexpr auto native_handle() noexcept -> native_pointer
166  {
167  return &m_mutex;
168  }
169 
175  constexpr auto native_handle() const noexcept -> native_const_pointer
176  {
177  return &m_mutex;
178  }
179 private:
180  native_type m_mutex{};
181 public:
182  mutex(const mutex&) = delete;
183  mutex(mutex&&) = delete;
184  mutex& operator=(const mutex&) = delete;
185  mutex& operator=(mutex&&) = delete;
186 };
187 
191 class mutex_ref : public mutex_base<mutex_ref> {
192 public:
199  explicit constexpr mutex_ref(native_pointer m) noexcept
200  : m_mutex_ptr(m)
201  {
202  __ASSERT_NO_MSG(m_mutex_ptr != nullptr);
203  }
204 
211  template<class T_Mutex>
212  explicit constexpr mutex_ref(T_Mutex& m) noexcept
213  : m_mutex_ptr(m.native_handle())
214  {
215  __ASSERT_NO_MSG(m_mutex_ptr != nullptr);
216  }
217 
226  constexpr mutex_ref& operator=(native_pointer m) noexcept
227  {
228  m_mutex_ptr = m;
229  __ASSERT_NO_MSG(m_mutex_ptr != nullptr);
230  return *this;
231  }
232 
241  template<class T_Mutex>
242  constexpr mutex_ref& operator=(T_Mutex& m) noexcept
243  {
244  m_mutex_ptr = m.native_handle();
245  __ASSERT_NO_MSG(m_mutex_ptr != nullptr);
246  return *this;
247  }
248 
254  constexpr auto native_handle() noexcept -> native_pointer
255  {
256  return m_mutex_ptr;
257  }
258 
264  constexpr auto native_handle() const noexcept -> native_const_pointer
265  {
266  return m_mutex_ptr;
267  }
268 private:
269  native_pointer m_mutex_ptr{ nullptr };
270 public:
271  mutex_ref() = delete;
272 };
273 
274 } // namespace zpp
275 
276 #endif // ZPP_INCLUDE_ZPP_MUTEX_HPP
A recursive mutex CRTP base class.
Definition: mutex.hpp:25
constexpr mutex_base() noexcept
Protected default constructor so only derived objects can be created.
Definition: mutex.hpp:34
mutex_base & operator=(const mutex_base &)=delete
native_type const * native_const_pointer
Definition: mutex.hpp:29
auto try_lock_for(const std::chrono::duration< T_Rep, T_Period > &timeout) noexcept
Try locking the mutex with a timeout.
Definition: mutex.hpp:86
auto lock() noexcept
Lock the mutex. Wait forever until it is locked.
Definition: mutex.hpp:44
auto native_handle() noexcept -> native_pointer
get the native zephyr mutex handle.
Definition: mutex.hpp:126
mutex_base(mutex_base &&)=delete
auto unlock() noexcept
Unlock the mutex.
Definition: mutex.hpp:107
native_type * native_pointer
Definition: mutex.hpp:28
auto try_lock() noexcept
Try locking the mutex without waiting.
Definition: mutex.hpp:63
mutex_base & operator=(mutex_base &&)=delete
auto native_handle() const noexcept -> native_const_pointer
get the native zephyr mutex handle.
Definition: mutex.hpp:136
mutex_base(const mutex_base &)=delete
struct k_mutex native_type
Definition: mutex.hpp:27
A recursive mutex class borrowing the native mutex.
Definition: mutex.hpp:191
mutex_ref()=delete
constexpr mutex_ref & operator=(T_Mutex &m) noexcept
Assing another mutex object.
Definition: mutex.hpp:242
constexpr auto native_handle() const noexcept -> native_const_pointer
get the native zephyr mutex handle.
Definition: mutex.hpp:264
constexpr mutex_ref & operator=(native_pointer m) noexcept
Assing another mutex object.
Definition: mutex.hpp:226
constexpr mutex_ref(T_Mutex &m) noexcept
Construct a mutex using another mutex object.
Definition: mutex.hpp:212
constexpr mutex_ref(native_pointer m) noexcept
Construct a mutex using a native k_mutex*.
Definition: mutex.hpp:199
constexpr auto native_handle() noexcept -> native_pointer
get the native zephyr mutex handle.
Definition: mutex.hpp:254
A recursive mutex class.
Definition: mutex.hpp:150
mutex(const mutex &)=delete
mutex(mutex &&)=delete
mutex & operator=(mutex &&)=delete
constexpr auto native_handle() const noexcept -> native_const_pointer
get the native zephyr mutex handle.
Definition: mutex.hpp:175
mutex() noexcept
Default contructor.
Definition: mutex.hpp:155
constexpr auto native_handle() noexcept -> native_pointer
get the native zephyr mutex handle.
Definition: mutex.hpp:165
mutex & operator=(const mutex &)=delete
result class
Definition: result.hpp:89
void assign_value(const T_Ok &v) noexcept
Definition: result.hpp:197
void assign_error(const T_Error &e) noexcept
Definition: result.hpp:219
constexpr error_code to_error_code(int v) noexcept
Definition: error_code.hpp:102
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