GCC Code Coverage Report


Directory: Os/
File: ConditionVariableInterface.hpp
Date: 2026-10-14 21:16:29
Exec Total Coverage
Lines: 0 6 0.0%
Functions: 0 3 0.0%
Branches: 0 0 -%

Line Branch Exec Source
1 // ======================================================================
2 // \title Os/ConditionVariableInterface.hpp
3 // \brief Os::ConditionVariableHandle and Os::ConditionVariableInterface definitions
4 // ======================================================================
5 #ifndef OS_CONDITIONVARIABLEINTERFACE_HPP_
6 #define OS_CONDITIONVARIABLEINTERFACE_HPP_
7
8 #include <type_traits>
9
10 #include "Fw/Types/Assert.hpp"
11 #include "Os/Mutex.hpp"
12 #include "Os/Os.hpp"
13 #include "config/OsSelection.hpp" // defines Os::ConditionVariable alias and OS_CONDITION_VARIABLE_HEADER consumed by Os/Condition.hpp; do not remove
14
15 namespace Os {
16
17 class DelegateMutex;
18 class DelegateConditionVariable;
19
20 // A condition variable implementation operates on the handle of the configured Os::Mutex. Selecting a
21 // compile-time Mutex while leaving Os::ConditionVariable on the link-time delegate (or vice versa) hands the
22 // CMake-chosen implementation a handle of the wrong type, so both must be delegates or neither may be.
23 static_assert(std::is_same<Os::Mutex, Os::DelegateMutex>::value ==
24 std::is_same<Os::ConditionVariable, Os::DelegateConditionVariable>::value,
25 "Os::Mutex and Os::ConditionVariable must be overridden together in config/OsSelection.hpp");
26
27 //! \brief Condition variable handle parent
28 class ConditionVariableHandle {};
29
30 //! \brief interface for condition variables
31 //!
32 //! Condition variables allow a program to block on a condition while atomically releasing an Os::Mutex and atomically
33 //! reacquiring the mutex once the condition has been notified.
34 class ConditionVariableInterface {
35 public:
36 enum Status {
37 OP_OK, //!< Operation was successful
38 ERROR_MUTEX_NOT_HELD, //!< When trying to wait but we don't hold the mutex
39 ERROR_DIFFERENT_MUTEX, //!< When trying to use a different mutex than expected mutex
40 ERROR_NOT_IMPLEMENTED, //!< When trying to use a feature that isn't implemented
41 NOT_SUPPORTED, //!< ConditionVariable does not support operation
42 ERROR_OTHER //!< All other errors
43 };
44
45 //! Default constructor
46 ✗ ConditionVariableInterface() = default;
47 //! Default destructor
48 ✗ virtual ~ConditionVariableInterface() = default;
49
50 //! \brief copy constructor is forbidden
51 ConditionVariableInterface(const ConditionVariableInterface& other) = delete;
52
53 //! \brief assignment operator is forbidden
54 virtual ConditionVariableInterface& operator=(const ConditionVariableInterface& other) = delete;
55
56 //! \brief wait on a condition variable
57 //!
58 //! Wait on a condition variable. This function will atomically unlock the provided mutex and block on the condition
59 //! in one step. Blocking will occur until a future `notify` or `notifyAll` call is made to this variable on another
60 //! thread of execution.
61 //!
62 //! \param mutex: mutex to unlock as part of this operation
63 //! \return status of the conditional wait
64 virtual Status pend(Os::Mutex& mutex) = 0;
65
66 //! \brief notify a single waiter on this condition variable
67 //!
68 //! Notify a single waiter on this condition variable. It is not necessary to hold the mutex supplied by the waiters
69 //! and it is advantageous not to hold the lock to prevent immediate re-blocking.
70 virtual void notify() = 0;
71
72 //! \brief notify all waiters on this condition variable
73 //!
74 //! Notify all waiters on this condition variable. It is not necessary to hold the mutex supplied by the waiters
75 //! and it is advantageous not to hold the lock to prevent immediate re-blocking.
76 virtual void notifyAll() = 0;
77
78 //! \brief return the underlying condition variable handle (implementation specific).
79 //! \return internal task handle representation
80 virtual ConditionVariableHandle* getHandle() = 0;
81
82 //! \brief provide a pointer to a ConditionVariable delegate object
83 //!
84 //! \note ERROR_DIFFERENT_MUTEX is reported by the link-time Os::DelegateConditionVariable, which records the mutex
85 //! first supplied to pend(); an implementation selected directly as Os::ConditionVariable does not perform that
86 //! check.
87 static ConditionVariableInterface* getDelegate(ConditionVariableHandleStorage& aligned_new_memory);
88
89 // ------------------------------------------------------------------
90 // Common (non-virtual) functions built on top of pend(). Defined inline
91 // on the interface so they are available regardless of which
92 // implementation Os::ConditionVariable is configured to be.
93 // ------------------------------------------------------------------
94
95 //! \brief wait on a condition variable and assert success
96 //!
97 //! Wait on a condition variable. This function will atomically unlock the provided mutex and block on the condition
98 //! in one step. Blocking will occur until a future `notify` or `notifyAll` call is made to this variable on another
99 //! thread of execution.
100 //!
101 //! \warning it is invalid to supply a mutex different from those supplied by others
102 //! \warning conditions *must* be rechecked after the condition variable unlocks
103 //! \warning the mutex must be locked by the calling task
104 //!
105 //! \param mutex: mutex to unlock as part of this operation
106 ✗ void wait(Os::Mutex& mutex) {
107 ✗ const Status status = this->pend(mutex);
108 ✗ FW_ASSERT(status == Status::OP_OK,
109 static_cast<FwAssertArgType>(reinterpret_cast<PlatformPointerCastType>(this)), status);
110 ✗ }
111 };
112
113 } // namespace Os
114
115 #endif // OS_CONDITIONVARIABLEINTERFACE_HPP_
116