50#ifdef CONFIG_OVE_ZERO_HEAP
51 int err = ove_mutex_init(&handle_, &storage_);
53 int err = ove_mutex_create(&handle_);
55 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
67#ifdef CONFIG_OVE_ZERO_HEAP
68 ove_mutex_deinit(handle_);
70 ove_mutex_destroy(handle_);
77#ifdef CONFIG_OVE_ZERO_HEAP
87 other.handle_ =
nullptr;
99 ove_mutex_destroy(handle_);
100 handle_ = other.handle_;
101 other.handle_ =
nullptr;
126 const int err = ove_mutex_lock(handle_, OVE_WAIT_FOREVER);
127 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
137 return ove_mutex_lock(handle_, 0) == OVE_OK;
157 template <
class Rep,
class Period>
176 template <
class Clock,
class Duration>
178 try_lock_until(
const std::chrono::time_point<Clock, Duration> &deadline)
noexcept
180 const auto rel = deadline - Clock::now();
191 ove_mutex_unlock(handle_);
200 return handle_ !=
nullptr;
213 ove_mutex_t handle_ =
nullptr;
214#ifdef CONFIG_OVE_ZERO_HEAP
215 ove_mutex_storage_t storage_ = {};
236 { m.try_lock() } -> std::convertible_to<bool>;
242 "ove::Mutex must satisfy the BasicLockable named requirement");
266#ifdef CONFIG_OVE_ZERO_HEAP
267 int err = ove_recursive_mutex_init(&handle_, &storage_);
269 int err = ove_recursive_mutex_create(&handle_);
271 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
281#ifdef CONFIG_OVE_ZERO_HEAP
282 ove_mutex_deinit(handle_);
284 ove_recursive_mutex_destroy(handle_);
291#ifdef CONFIG_OVE_ZERO_HEAP
301 other.handle_ =
nullptr;
311 if (
this != &other) {
313 ove_recursive_mutex_destroy(handle_);
314 handle_ = other.handle_;
315 other.handle_ =
nullptr;
328 const int err = ove_recursive_mutex_lock(handle_, OVE_WAIT_FOREVER);
329 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
340 return ove_recursive_mutex_lock(handle_, 0) == OVE_OK;
354 template <
class Rep,
class Period>
370 template <
class Clock,
class Duration>
372 try_lock_until(
const std::chrono::time_point<Clock, Duration> &deadline)
noexcept
374 const auto rel = deadline - Clock::now();
383 ove_recursive_mutex_unlock(handle_);
392 return handle_ !=
nullptr;
405 ove_mutex_t handle_ =
nullptr;
406#ifdef CONFIG_OVE_ZERO_HEAP
407 ove_mutex_storage_t storage_ = {};
411static_assert(detail::basic_lockable<RecursiveMutex>,
412 "ove::RecursiveMutex must satisfy the BasicLockable named requirement");
413static_assert(detail::lockable<RecursiveMutex>,
414 "ove::RecursiveMutex must satisfy the Lockable named requirement");
505 template <
typename... Args> T &
init(Args &&...args)
507 bool expected =
false;
508 if (!initialized_.compare_exchange_strong(expected,
true))
509 OVE_STATIC_INIT_ASSERT(
false &&
"StaticCell already initialized");
510 return *
new (storage_) T(std::forward<Args>(args)...);
526 OVE_STATIC_INIT_ASSERT(initialized_.load());
527 return *
reinterpret_cast<T *
>(storage_);
545 OVE_STATIC_INIT_ASSERT(initialized_.load());
546 return *
reinterpret_cast<const T *
>(storage_);
555 return initialized_.load();
566 alignas(T) uint8_t storage_[
sizeof(T)]{};
567 std::atomic<bool> initialized_{
false};
595 explicit Semaphore(
unsigned int initial = 0,
unsigned int max = 1)
597#ifdef CONFIG_OVE_ZERO_HEAP
598 int err = ove_sem_init(&handle_, &storage_, initial, max);
600 int err = ove_sem_create(&handle_, initial, max);
602 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
612#ifdef CONFIG_OVE_ZERO_HEAP
613 ove_sem_deinit(handle_);
615 ove_sem_destroy(handle_);
622#ifdef CONFIG_OVE_ZERO_HEAP
632 other.handle_ =
nullptr;
642 if (
this != &other) {
644 ove_sem_destroy(handle_);
645 handle_ = other.handle_;
646 other.handle_ =
nullptr;
662 const int err = ove_sem_take(handle_, OVE_WAIT_FOREVER);
663 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
672 return ove_sem_take(handle_, 0) == OVE_OK;
692 template <
class Rep,
class Period>
709 template <
class Clock,
class Duration>
713 const auto rel = deadline - Clock::now();
727 ove_sem_give(handle_);
736 return handle_ !=
nullptr;
749 ove_sem_t handle_ =
nullptr;
750#ifdef CONFIG_OVE_ZERO_HEAP
751 ove_sem_storage_t storage_ = {};
776#ifdef CONFIG_OVE_ZERO_HEAP
777 int err = ove_event_init(&handle_, &storage_);
779 int err = ove_event_create(&handle_);
781 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
791#ifdef CONFIG_OVE_ZERO_HEAP
792 ove_event_deinit(handle_);
794 ove_event_destroy(handle_);
801#ifdef CONFIG_OVE_ZERO_HEAP
811 other.handle_ =
nullptr;
821 if (
this != &other) {
823 ove_event_destroy(handle_);
824 handle_ = other.handle_;
825 other.handle_ =
nullptr;
840 const int err = ove_event_wait(handle_, OVE_WAIT_FOREVER);
841 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
851 return ove_event_wait(handle_, 0) == OVE_OK;
863 template <
class Rep,
class Period>
878 template <
class Clock,
class Duration>
880 try_wait_until(
const std::chrono::time_point<Clock, Duration> &deadline)
noexcept
882 const auto rel = deadline - Clock::now();
891 ove_event_signal(handle_);
901 ove_event_signal_from_isr(handle_);
910 return handle_ !=
nullptr;
923 ove_event_t handle_ =
nullptr;
924#ifdef CONFIG_OVE_ZERO_HEAP
925 ove_event_storage_t storage_ = {};
952#ifdef CONFIG_OVE_ZERO_HEAP
953 int err = ove_condvar_init(&handle_, &storage_);
955 int err = ove_condvar_create(&handle_);
957 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
967#ifdef CONFIG_OVE_ZERO_HEAP
968 ove_condvar_deinit(handle_);
970 ove_condvar_destroy(handle_);
977#ifdef CONFIG_OVE_ZERO_HEAP
987 other.handle_ =
nullptr;
997 if (
this != &other) {
999 ove_condvar_destroy(handle_);
1000 handle_ = other.handle_;
1001 other.handle_ =
nullptr;
1025 const int err = ove_condvar_wait(handle_, mtx.
handle(), OVE_WAIT_FOREVER);
1026 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
1059 template <
class Rep,
class Period>
1074 template <
class Clock,
class Duration>
1077 const std::chrono::time_point<Clock, Duration> &deadline)
noexcept
1079 const auto rel = deadline - Clock::now();
1098 template <
typename Predicate>
void wait(
Mutex &mtx, Predicate pred)
1115 template <
typename Rep,
typename Period,
typename Predicate>
1119 const auto deadline = steady_clock::now() + rel;
1134 template <
typename Clock,
typename Duration,
typename Predicate>
1136 const std::chrono::time_point<Clock, Duration> &deadline,
1140 const auto now = Clock::now();
1141 if (now >= deadline)
1143 const int rc = ove_condvar_wait(handle_, mtx.
handle(),
1156 ove_condvar_signal(handle_);
1165 ove_condvar_broadcast(handle_);
1174 return handle_ !=
nullptr;
1187 ove_condvar_t handle_ =
nullptr;
1188#ifdef CONFIG_OVE_ZERO_HEAP
1189 ove_condvar_storage_t storage_ = {};
RAII wrapper around an oveRTOS condition variable.
Definition sync.hpp:943
Result< void > try_wait_until(Mutex &mtx, const std::chrono::time_point< Clock, Duration > &deadline) noexcept
Deadline-based wait templated over the clock.
Definition sync.hpp:1076
CondVar & operator=(CondVar &&other) noexcept
Move-assignment operator — transfers ownership of the kernel handle.
Definition sync.hpp:995
void wait(Mutex &mtx)
Atomically releases the mutex and waits for a notification.
Definition sync.hpp:1023
bool try_wait_until(Mutex &mtx, const std::chrono::time_point< Clock, Duration > &deadline, Predicate pred)
Deadline-based wait with predicate. std::condition_variable::wait_until predicate-overload analog.
Definition sync.hpp:1135
void wait(Mutex &mtx, Predicate pred)
Predicate-loop wait. std::condition_variable::wait predicate-overload analog.
Definition sync.hpp:1098
Result< void > try_wait_for(Mutex &mtx, const std::chrono::duration< Rep, Period > &rel) noexcept
Bounded-wait.
Definition sync.hpp:1061
CondVar()
Constructs and initialises the condition variable.
Definition sync.hpp:950
void notify_all()
Wakes all tasks waiting on this condition variable. std::condition_variable::notify_all analog.
Definition sync.hpp:1163
bool try_wait_for(Mutex &mtx, std::chrono::duration< Rep, Period > rel, Predicate pred)
Bounded-wait with predicate. std::condition_variable::wait_for predicate-overload analog.
Definition sync.hpp:1116
bool valid() const
Returns true if the underlying kernel handle is non-null.
Definition sync.hpp:1172
~CondVar() noexcept
Destroys the condition variable, releasing the underlying kernel resource.
Definition sync.hpp:963
CondVar(CondVar &&other) noexcept
Move constructor — transfers ownership of the kernel handle.
Definition sync.hpp:985
void notify_one()
Wakes one task waiting on this condition variable. std::condition_variable::notify_one analog.
Definition sync.hpp:1154
ove_condvar_t handle() const
Returns the raw oveRTOS condition variable handle.
Definition sync.hpp:1181
RAII wrapper around an oveRTOS binary event flag.
Definition sync.hpp:767
ove_event_t handle() const
Returns the raw oveRTOS event handle.
Definition sync.hpp:917
void signal_from_isr()
Signals the event from an ISR context, waking any blocked waiter.
Definition sync.hpp:899
Event(Event &&other) noexcept
Move constructor — transfers ownership of the kernel handle.
Definition sync.hpp:809
bool valid() const
Returns true if the underlying kernel handle is non-null.
Definition sync.hpp:908
~Event() noexcept
Destroys the event, releasing the underlying kernel resource.
Definition sync.hpp:787
Event()
Constructs and initialises the event in the unsignalled state.
Definition sync.hpp:774
void wait()
Blocks the calling task until the event is signalled.
Definition sync.hpp:838
Event & operator=(Event &&other) noexcept
Move-assignment operator — transfers ownership of the kernel handle.
Definition sync.hpp:819
Result< void > try_wait_until(const std::chrono::time_point< Clock, Duration > &deadline) noexcept
Deadline-based wait templated over the clock.
Definition sync.hpp:880
Result< void > try_wait_for(const std::chrono::duration< Rep, Period > &rel) noexcept
Bounded-wait.
Definition sync.hpp:865
bool try_wait()
Non-blocking check.
Definition sync.hpp:849
void signal()
Signals the event from task context, waking any blocked waiter.
Definition sync.hpp:889
Scoped RAII guard that locks a Mutex on construction and unlocks it on destruction.
Definition sync.hpp:427
LockGuard(Mutex &mtx)
Constructs the guard, immediately locking the given mutex.
Definition sync.hpp:444
~LockGuard() noexcept
Destroys the guard, unlocking the associated mutex.
Definition sync.hpp:452
RAII wrapper around an oveRTOS non-recursive mutex.
Definition sync.hpp:40
Mutex(Mutex &&other) noexcept
Move constructor — transfers ownership of the kernel handle.
Definition sync.hpp:85
bool try_lock()
Attempts to acquire the mutex without blocking. Satisfies the Lockable named requirement (alongside l...
Definition sync.hpp:135
ove_mutex_t handle() const
Returns the raw oveRTOS mutex handle.
Definition sync.hpp:207
~Mutex() noexcept
Destroys the mutex, releasing the underlying kernel resource.
Definition sync.hpp:63
Mutex()
Constructs and initialises the mutex.
Definition sync.hpp:48
bool valid() const
Returns true if the underlying kernel handle is non-null.
Definition sync.hpp:198
void unlock()
Releases the mutex.
Definition sync.hpp:189
Mutex & operator=(Mutex &&other) noexcept
Move-assignment operator — transfers ownership of the kernel handle.
Definition sync.hpp:95
Result< void > try_lock_until(const std::chrono::time_point< Clock, Duration > &deadline) noexcept
Attempts to acquire the mutex by deadline.
Definition sync.hpp:178
Result< void > try_lock_for(const std::chrono::duration< Rep, Period > &rel) noexcept
Attempts to acquire the mutex within rel.
Definition sync.hpp:159
void lock()
Acquires the mutex, blocking indefinitely. std::mutex::lock analog.
Definition sync.hpp:124
RAII wrapper around an oveRTOS recursive mutex.
Definition sync.hpp:256
RecursiveMutex(RecursiveMutex &&other) noexcept
Move constructor — transfers ownership of the kernel handle.
Definition sync.hpp:299
Result< void > try_lock_until(const std::chrono::time_point< Clock, Duration > &deadline) noexcept
Deadline-based acquisition templated over the clock.
Definition sync.hpp:372
RecursiveMutex()
Constructs and initialises the recursive mutex.
Definition sync.hpp:264
void unlock()
Releases one level of the recursive lock.
Definition sync.hpp:381
~RecursiveMutex() noexcept
Destroys the recursive mutex, releasing the underlying kernel resource.
Definition sync.hpp:277
bool try_lock()
Non-blocking acquisition attempt. Part of the Lockable named requirement satisfied by this class.
Definition sync.hpp:338
Result< void > try_lock_for(const std::chrono::duration< Rep, Period > &rel) noexcept
Bounded-wait acquisition. Same shape as Mutex::try_lock_for — see that method for the TimedLockable n...
Definition sync.hpp:356
RecursiveMutex & operator=(RecursiveMutex &&other) noexcept
Move-assignment operator — transfers ownership of the kernel handle.
Definition sync.hpp:309
void lock()
Acquires the recursive mutex, blocking indefinitely.
Definition sync.hpp:326
bool valid() const
Returns true if the underlying kernel handle is non-null.
Definition sync.hpp:390
ove_mutex_t handle() const
Returns the raw oveRTOS mutex handle.
Definition sync.hpp:399
RAII wrapper around an oveRTOS counting semaphore.
Definition sync.hpp:586
ove_sem_t handle() const
Returns the raw oveRTOS semaphore handle.
Definition sync.hpp:743
bool valid() const
Returns true if the underlying kernel handle is non-null.
Definition sync.hpp:734
Result< void > try_acquire_for(const std::chrono::duration< Rep, Period > &rel) noexcept
Bounded-wait acquisition.
Definition sync.hpp:694
void release()
Increments the semaphore count, unblocking a waiting task if any.
Definition sync.hpp:725
bool try_acquire()
Non-blocking acquisition attempt. std::counting_semaphore::try_acquire analog.
Definition sync.hpp:670
void acquire()
Decrements the semaphore count, blocking indefinitely.
Definition sync.hpp:660
Result< void > try_acquire_until(const std::chrono::time_point< Clock, Duration > &deadline) noexcept
Deadline-based acquisition templated over the clock.
Definition sync.hpp:711
Semaphore & operator=(Semaphore &&other) noexcept
Move-assignment operator — transfers ownership of the kernel handle.
Definition sync.hpp:640
Semaphore(Semaphore &&other) noexcept
Move constructor — transfers ownership of the kernel handle.
Definition sync.hpp:630
~Semaphore() noexcept
Destroys the semaphore, releasing the underlying kernel resource.
Definition sync.hpp:608
Semaphore(unsigned int initial=0, unsigned int max=1)
Constructs and initialises the semaphore.
Definition sync.hpp:595
Thread-safe, lazily initialised storage cell for a single object of type T.
Definition sync.hpp:493
bool is_initialized() const
Returns true if init() has been called successfully.
Definition sync.hpp:553
T & init(Args &&...args)
Constructs the contained object in-place.
Definition sync.hpp:505
const T & get() const
Returns a const reference to the contained object.
Definition sync.hpp:543
T & get()
Returns a reference to the contained object.
Definition sync.hpp:524
Strong ove::Error type, Result<T> alias, and std::error_code interop for the oveRTOS C++ binding.
Top-level namespace for all oveRTOS C++ abstractions.
Definition app.hpp:20
constexpr uint64_t to_timeout_ns(std::chrono::duration< Rep, Period > d) noexcept
Convert a chrono duration to uint64_t nanoseconds for the C API.
Definition types.hpp:129
Result< void > from_rc(int rc) noexcept
Lifts a substrate rc-code into a Result<void>.
Definition error.hpp:254
std::expected< T, Error > Result
std::expected-based result alias.
Definition error.hpp:139
Common type definitions and concepts for the C++ wrapper layer.