oveRTOS C API
Embedded RTOS framework — build system, configuration, and portable C API
Loading...
Searching...
No Matches
sync.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 *
6 * This file is part of oveRTOS.
7 */
8
28#ifndef OVE_SYNC_H
29#define OVE_SYNC_H
30
31#include "ove/types.h"
32#include "ove_config.h"
33#include "ove/storage.h"
34#include "ove/time.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40#ifdef CONFIG_OVE_SYNC
41
42/* =========================================================================
43 * Mutex — _init / _deinit (static storage)
44 * ========================================================================= */
45
58OVE_NODISCARD int ove_mutex_init(ove_mutex_t *mtx, ove_mutex_storage_t *storage) OVE_NONNULL(1, 2);
59
76
77/* =========================================================================
78 * Semaphore — _init / _deinit (static storage)
79 * ========================================================================= */
80
95OVE_NODISCARD int ove_sem_init(ove_sem_t *sem, ove_sem_storage_t *storage, unsigned int initial,
96 unsigned int max) OVE_NONNULL(1, 2);
97
108
109/* =========================================================================
110 * Binary event — _init / _deinit (static storage)
111 * ========================================================================= */
112
130OVE_NODISCARD int ove_event_init(ove_event_t *evt, ove_event_storage_t *storage) OVE_NONNULL(1, 2);
131
142
143/* =========================================================================
144 * Recursive mutex — _init (static storage)
145 * ========================================================================= */
146
163OVE_NODISCARD int ove_recursive_mutex_init(ove_mutex_t *mtx, ove_mutex_storage_t *storage)
164 OVE_NONNULL(1, 2);
165
166/* =========================================================================
167 * Condition variable — _init / _deinit (static storage)
168 * ========================================================================= */
169
183OVE_NODISCARD int ove_condvar_init(ove_condvar_t *cv, ove_condvar_storage_t *storage)
184 OVE_NONNULL(1, 2);
185
197
198/* =========================================================================
199 * Heap-gated _create / _destroy variants
200 * ========================================================================= */
201
202#ifdef OVE_HEAP_SYNC
203
215OVE_NODISCARD int ove_mutex_create(ove_mutex_t *mtx) OVE_NONNULL(1);
216
227
240OVE_NODISCARD int ove_sem_create(ove_sem_t *sem, unsigned int initial, unsigned int max)
241 OVE_NONNULL(1);
242
253
264OVE_NODISCARD int ove_event_create(ove_event_t *evt) OVE_NONNULL(1);
265
276
287OVE_NODISCARD int ove_recursive_mutex_create(ove_mutex_t *mtx) OVE_NONNULL(1);
288
300
311OVE_NODISCARD int ove_condvar_create(ove_condvar_t *cv) OVE_NONNULL(1);
312
324
325#endif /* OVE_HEAP_SYNC */
326
327/* =========================================================================
328 * Operations — always available (when CONFIG_OVE_SYNC is set)
329 * ========================================================================= */
330
346OVE_NODISCARD int ove_mutex_lock(ove_mutex_t mtx, uint64_t timeout_ns) OVE_NONNULL(1);
347
362OVE_NODISCARD static inline int ove_mutex_lock_until(ove_mutex_t mtx, uint64_t deadline_ns)
363{
364 return ove_mutex_lock(mtx, ove_time_deadline_to_timeout_ns(deadline_ns));
365}
366
377
393OVE_NODISCARD int ove_sem_take(ove_sem_t sem, uint64_t timeout_ns) OVE_NONNULL(1);
394
409OVE_NODISCARD static inline int ove_sem_take_until(ove_sem_t sem, uint64_t deadline_ns)
410{
411 return ove_sem_take(sem, ove_time_deadline_to_timeout_ns(deadline_ns));
412}
413
424
441int ove_sem_set_notify(ove_sem_t sem, ove_notify_cb cb, void *user_data) OVE_NONNULL(1);
442
462OVE_NODISCARD int ove_event_wait(ove_event_t evt, uint64_t timeout_ns) OVE_NONNULL(1);
463
478OVE_NODISCARD static inline int ove_event_wait_until(ove_event_t evt, uint64_t deadline_ns)
479{
480 return ove_event_wait(evt, ove_time_deadline_to_timeout_ns(deadline_ns));
481}
482
496
510
531OVE_NODISCARD int ove_recursive_mutex_lock(ove_mutex_t mtx, uint64_t timeout_ns) OVE_NONNULL(1);
532
548OVE_NODISCARD static inline int ove_recursive_mutex_lock_until(ove_mutex_t mtx,
549 uint64_t deadline_ns)
550{
552}
553
567
589OVE_NODISCARD int ove_condvar_wait(ove_condvar_t cv, ove_mutex_t mtx, uint64_t timeout_ns)
590 OVE_NONNULL(1, 2);
591
609OVE_NODISCARD static inline int ove_condvar_wait_until(ove_condvar_t cv, ove_mutex_t mtx,
610 uint64_t deadline_ns)
611{
612 return ove_condvar_wait(cv, mtx, ove_time_deadline_to_timeout_ns(deadline_ns));
613}
614
627
638
639#else /* !CONFIG_OVE_SYNC */
640
641/* P0-3: _init/_deinit stubs so OVE_*_DEFINE_STATIC links cleanly when
642 * CONFIG_OVE_SYNC=n. The macros expand to a constructor that calls the
643 * _init function unconditionally; without these stubs, the link fails. */
644static inline int ove_mutex_init(ove_mutex_t *m, ove_mutex_storage_t *s)
645{
646 (void)m;
647 (void)s;
649}
650static inline void ove_mutex_deinit(ove_mutex_t m)
651{
652 (void)m;
653}
654static inline int ove_sem_init(ove_sem_t *s, ove_sem_storage_t *st, unsigned int i, unsigned int x)
655{
656 (void)s;
657 (void)st;
658 (void)i;
659 (void)x;
661}
662static inline void ove_sem_deinit(ove_sem_t s)
663{
664 (void)s;
665}
666static inline int ove_event_init(ove_event_t *e, ove_event_storage_t *s)
667{
668 (void)e;
669 (void)s;
671}
672static inline void ove_event_deinit(ove_event_t e)
673{
674 (void)e;
675}
676static inline int ove_recursive_mutex_init(ove_mutex_t *m, ove_mutex_storage_t *s)
677{
678 (void)m;
679 (void)s;
681}
682static inline int ove_condvar_init(ove_condvar_t *c, ove_condvar_storage_t *s)
683{
684 (void)c;
685 (void)s;
687}
688static inline void ove_condvar_deinit(ove_condvar_t c)
689{
690 (void)c;
691}
692
693static inline int ove_mutex_create(ove_mutex_t *m)
694{
695 (void)m;
697}
698static inline void ove_mutex_destroy(ove_mutex_t m)
699{
700 (void)m;
701}
702static inline int ove_mutex_lock(ove_mutex_t m, uint64_t t)
703{
704 (void)m;
705 (void)t;
707}
708static inline void ove_mutex_unlock(ove_mutex_t m)
709{
710 (void)m;
711}
712static inline int ove_sem_create(ove_sem_t *s, unsigned int i, unsigned int x)
713{
714 (void)s;
715 (void)i;
716 (void)x;
718}
719static inline void ove_sem_destroy(ove_sem_t s)
720{
721 (void)s;
722}
723static inline int ove_sem_take(ove_sem_t s, uint64_t t)
724{
725 (void)s;
726 (void)t;
728}
729static inline int ove_sem_set_notify(ove_sem_t s, ove_notify_cb cb, void *ud)
730{
731 (void)s;
732 (void)cb;
733 (void)ud;
735}
736static inline void ove_sem_give(ove_sem_t s)
737{
738 (void)s;
739}
740static inline int ove_event_create(ove_event_t *e)
741{
742 (void)e;
744}
745static inline void ove_event_destroy(ove_event_t e)
746{
747 (void)e;
748}
749static inline int ove_event_wait(ove_event_t e, uint64_t t)
750{
751 (void)e;
752 (void)t;
754}
755static inline void ove_event_signal(ove_event_t e)
756{
757 (void)e;
758}
759static inline void ove_event_signal_from_isr(ove_event_t e)
760{
761 (void)e;
762}
763static inline int ove_recursive_mutex_create(ove_mutex_t *m)
764{
765 (void)m;
767}
768static inline int ove_recursive_mutex_lock(ove_mutex_t m, uint64_t t)
769{
770 (void)m;
771 (void)t;
773}
774static inline void ove_recursive_mutex_unlock(ove_mutex_t m)
775{
776 (void)m;
777}
778static inline void ove_recursive_mutex_destroy(ove_mutex_t m)
779{
780 (void)m;
781}
782static inline int ove_condvar_create(ove_condvar_t *c)
783{
784 (void)c;
786}
787static inline void ove_condvar_destroy(ove_condvar_t c)
788{
789 (void)c;
790}
791static inline int ove_condvar_wait(ove_condvar_t c, ove_mutex_t m, uint64_t t)
792{
793 (void)c;
794 (void)m;
795 (void)t;
797}
798static inline void ove_condvar_signal(ove_condvar_t c)
799{
800 (void)c;
801}
802static inline void ove_condvar_broadcast(ove_condvar_t c)
803{
804 (void)c;
805}
806
807#endif /* CONFIG_OVE_SYNC */
808
809#ifdef __cplusplus
810}
811#endif
812
813#endif /* OVE_SYNC_H */
814
void ove_sem_destroy(ove_sem_t sem)
Destroy and free a semaphore allocated with ove_sem_create().
OVE_NODISCARD int ove_event_init(ove_event_t *evt, ove_event_storage_t *storage) OVE_NONNULL(1
Initialise a binary event object using caller-supplied static storage.
OVE_NODISCARD int ove_condvar_create(ove_condvar_t *cv) OVE_NONNULL(1)
Allocate and initialise a condition variable from the heap.
void ove_condvar_signal(ove_condvar_t cv)
Wake one thread waiting on a condition variable.
OVE_NODISCARD int OVE_NODISCARD int void ove_condvar_deinit(ove_condvar_t cv)
Release resources held by a condition variable initialised with ove_condvar_init().
int ove_sem_set_notify(ove_sem_t sem, ove_notify_cb cb, void *user_data) OVE_NONNULL(1)
Register a notify callback fired after every successful give.
OVE_NODISCARD int void ove_sem_deinit(ove_sem_t sem)
Release resources held by a semaphore initialised with ove_sem_init().
OVE_NODISCARD int ove_mutex_create(ove_mutex_t *mtx) OVE_NONNULL(1)
Allocate and initialise a non-recursive mutex from the heap.
OVE_NODISCARD int ove_recursive_mutex_init(ove_mutex_t *mtx, ove_mutex_storage_t *storage) OVE_NONNULL(1
Initialise a recursive mutex using caller-supplied static storage.
OVE_NODISCARD int ove_event_wait(ove_event_t evt, uint64_t timeout_ns) OVE_NONNULL(1)
Wait for a binary event to be signalled.
OVE_NODISCARD int ove_event_create(ove_event_t *evt) OVE_NONNULL(1)
Allocate and initialise a binary event from the heap.
OVE_NODISCARD int static OVE_NODISCARD int ove_condvar_wait_until(ove_condvar_t cv, ove_mutex_t mtx, uint64_t deadline_ns)
Deadline-based variant of ove_condvar_wait.
Definition sync.h:609
OVE_NODISCARD int ove_sem_init(ove_sem_t *sem, ove_sem_storage_t *storage, unsigned int initial, unsigned int max) OVE_NONNULL(1
Initialise a counting semaphore using caller-supplied static storage.
void ove_mutex_destroy(ove_mutex_t mtx)
Destroy and free a mutex allocated with ove_mutex_create().
void ove_recursive_mutex_destroy(ove_mutex_t mtx)
Destroy and free a recursive mutex allocated with ove_recursive_mutex_create().
OVE_NODISCARD int ove_sem_create(ove_sem_t *sem, unsigned int initial, unsigned int max) OVE_NONNULL(1)
Allocate and initialise a counting semaphore from the heap.
void ove_condvar_destroy(ove_condvar_t cv)
Destroy and free a condition variable allocated with ove_condvar_create().
static OVE_NODISCARD int ove_recursive_mutex_lock_until(ove_mutex_t mtx, uint64_t deadline_ns)
Deadline-based variant of ove_recursive_mutex_lock.
Definition sync.h:548
void ove_recursive_mutex_unlock(ove_mutex_t mtx)
Release one level of a recursive mutex lock.
static OVE_NODISCARD int ove_sem_take_until(ove_sem_t sem, uint64_t deadline_ns)
Deadline-based variant of ove_sem_take.
Definition sync.h:409
void ove_event_destroy(ove_event_t evt)
Destroy and free an event allocated with ove_event_create().
static OVE_NODISCARD int ove_event_wait_until(ove_event_t evt, uint64_t deadline_ns)
Deadline-based variant of ove_event_wait.
Definition sync.h:478
OVE_NODISCARD int ove_mutex_init(ove_mutex_t *mtx, ove_mutex_storage_t *storage) OVE_NONNULL(1
Initialise a non-recursive mutex using caller-supplied static storage.
OVE_NODISCARD int void ove_mutex_deinit(ove_mutex_t mtx)
Release resources held by a mutex initialised with ove_mutex_init().
void ove_condvar_broadcast(ove_condvar_t cv)
Wake all threads waiting on a condition variable.
static OVE_NODISCARD int ove_mutex_lock_until(ove_mutex_t mtx, uint64_t deadline_ns)
Deadline-based variant of ove_mutex_lock.
Definition sync.h:362
OVE_NODISCARD int ove_recursive_mutex_lock(ove_mutex_t mtx, uint64_t timeout_ns) OVE_NONNULL(1)
Acquire a recursive mutex, blocking until it is available or the timeout expires.
void ove_mutex_unlock(ove_mutex_t mtx)
Release a non-recursive mutex previously acquired by ove_mutex_lock().
OVE_NODISCARD int ove_recursive_mutex_create(ove_mutex_t *mtx) OVE_NONNULL(1)
Allocate and initialise a recursive mutex from the heap.
OVE_NODISCARD int OVE_NODISCARD int ove_condvar_init(ove_condvar_t *cv, ove_condvar_storage_t *storage) OVE_NONNULL(1
Initialise a condition variable using caller-supplied static storage.
void ove_event_signal_from_isr(ove_event_t evt)
Signal a binary event from an interrupt service routine.
OVE_NODISCARD int ove_condvar_wait(ove_condvar_t cv, ove_mutex_t mtx, uint64_t timeout_ns) OVE_NONNULL(1
Atomically release a mutex and wait on a condition variable.
OVE_NODISCARD int ove_sem_take(ove_sem_t sem, uint64_t timeout_ns) OVE_NONNULL(1)
Decrement (take) a semaphore, blocking until a count is available or the timeout expires.
void ove_sem_give(ove_sem_t sem)
Increment (give) a semaphore, potentially unblocking a waiting thread.
void ove_event_signal(ove_event_t evt)
Signal a binary event, unblocking one waiting thread.
OVE_NODISCARD int void ove_event_deinit(ove_event_t evt)
Release resources held by an event initialised with ove_event_init().
OVE_NODISCARD int ove_mutex_lock(ove_mutex_t mtx, uint64_t timeout_ns) OVE_NONNULL(1)
Acquire a non-recursive mutex, blocking until it is available or the timeout expires.
static uint64_t ove_time_deadline_to_timeout_ns(uint64_t deadline_ns)
Convert a steady-clock deadline to a duration suitable for the existing timeout_ns-taking APIs.
Definition time.h:162
struct ove_event * ove_event_t
Opaque handle for a binary event (signal/wait) object.
Definition types.h:217
struct ove_sem * ove_sem_t
Opaque handle for a counting semaphore object.
Definition types.h:214
struct ove_condvar * ove_condvar_t
Opaque handle for a condition variable object.
Definition types.h:220
struct ove_mutex * ove_mutex_t
Opaque handle for a mutex object.
Definition types.h:211
void(* ove_notify_cb)(void *user_data)
Notify-callback signature used by the _set_notify variants of the comm primitives (stream / queue / e...
Definition types.h:298
@ OVE_ERR_NOT_SUPPORTED
Definition types.h:98