17#ifndef IOX_HOOFS_POSIX_WRAPPER_TIMER_HPP
18#define IOX_HOOFS_POSIX_WRAPPER_TIMER_HPP
20#include "iceoryx_hoofs/cxx/optional.hpp"
21#include "iceoryx_hoofs/cxx/vector.hpp"
22#include "iceoryx_hoofs/design_pattern/creation.hpp"
23#include "iceoryx_hoofs/internal/units/duration.hpp"
24#include "iceoryx_hoofs/platform/signal.hpp"
25#include "iceoryx_hoofs/platform/time.hpp"
28#include <condition_variable>
42 TIMER_NOT_INITIALIZED,
54using namespace iox::units::duration_literals;
105 static constexpr size_t SIZE_OF_COMBINDED_INDEX_AND_DESCRIPTOR =
sizeof(uint32_t);
106 static constexpr size_t SIZE_OF_SIGVAL_INT =
sizeof(int);
107 static_assert(SIZE_OF_SIGVAL_INT >= SIZE_OF_COMBINDED_INDEX_AND_DESCRIPTOR,
"size of sigval_int is to low");
109 static constexpr uint32_t MAX_NUMBER_OF_CALLBACK_HANDLES = 100u;
110 static_assert(MAX_NUMBER_OF_CALLBACK_HANDLES <= std::numeric_limits<uint8_t>::max(),
111 "number of callback handles exceeds max index value");
113 struct OsTimerCallbackHandle
115 static constexpr uint32_t MAX_DESCRIPTOR_VALUE{(1u << 24u) - 1u};
116 static sigval indexAndDescriptorToSigval(uint8_t index, uint32_t descriptor)
noexcept;
117 static uint8_t sigvalToIndex(sigval intVal)
noexcept;
118 static uint32_t sigvalToDescriptor(sigval intVal)
noexcept;
120 void incrementDescriptor() noexcept;
122 std::mutex m_accessMutex;
126 std::atomic<uint32_t> m_descriptor{0u};
128 std::atomic_flag m_callbackIsAboutToBeExecuted = ATOMIC_FLAG_INIT;
130 std::atomic<bool> m_inUse{
false};
131 std::atomic<bool> m_isTimerActive{
false};
132 std::atomic<uint64_t> m_timerInvocationCounter{0u};
134 OsTimer* m_timer{
nullptr};
141 static constexpr timer_t INVALID_TIMER_ID = 0;
143 static constexpr timer_t INVALID_TIMER_ID =
nullptr;
147 static void callbackHelper(sigval data)
noexcept;
149 OsTimer(
const units::Duration timeToWait,
const std::function<
void()>& callback)
noexcept;
151 OsTimer(
const OsTimer&) =
delete;
152 OsTimer(OsTimer&&) =
delete;
153 OsTimer&
operator=(
const OsTimer&) =
delete;
157 virtual ~OsTimer() noexcept;
167 cxx::expected<TimerError>
start(const RunMode runMode, const
CatchUpPolicy catchUpPolicy) noexcept;
172 cxx::expected<TimerError>
stop() noexcept;
179 cxx::expected<TimerError>
180 restart(const units::Duration timeToWait, const RunMode runMode, const
CatchUpPolicy catchUpPolicy) noexcept;
189 cxx::expected<uint64_t, TimerError>
getOverruns() noexcept;
195 TimerError
getError() const noexcept;
200 void executeCallback() noexcept;
204 units::Duration m_timeToWait;
207 std::function<
void()> m_callback;
210 timer_t m_timerId{INVALID_TIMER_ID};
212 uint8_t m_callbackHandleIndex{0u};
216 bool m_isInitialized{
false};
220 TimerError m_errorValue{TimerError::NO_ERROR};
222 static OsTimerCallbackHandle s_callbackHandlePool[MAX_NUMBER_OF_CALLBACK_HANDLES];
235 Timer(
const units::Duration timeToWait)
noexcept;
245 Timer(
const units::Duration timeToWait,
const std::function<
void()>& callback)
noexcept;
250 static cxx::expected<units::Duration, TimerError>
now() noexcept;
265 virtual ~
Timer() noexcept = default;
279 cxx::expected<TimerError>
stop() noexcept;
286 cxx::expected<TimerError>
305 cxx::optional<OsTimer> m_osTimer;
308 static cxx::error<TimerError> createErrorFromErrno(const int32_t errnum) noexcept;
311 units::Duration m_timeToWait;
314 units::Duration m_creationTime;
317 TimerError m_errorValue{TimerError::NO_ERROR};
Interface for timers on POSIX operating systems.
Definition: timer.hpp:82
bool hasError() const noexcept
Returns true if the construction of the object was successful.
Timer(const units::Duration timeToWait, const std::function< void()> &callback) noexcept
Creates a timer with an operating system callback.
cxx::expected< TimerError > start(const RunMode runMode, const CatchUpPolicy catchUpPolicy) noexcept
Starts the timer.
CatchUpPolicy
defines the behavior of the timer when the callback runtime is greater than the periodic trigger time...
Definition: timer.hpp:98
Timer & operator=(const Timer &other)=delete
Move or semantics are forbidden as address of object is not allowed to change.
static cxx::expected< units::Duration, TimerError > now() noexcept
creates Duration from the result of clock_gettime(CLOCK_REALTIME, ...)
cxx::expected< TimerError > stop() noexcept
Disarms the timer.
cxx::expected< units::Duration, TimerError > timeUntilExpiration() noexcept
cxx::expected< uint64_t, TimerError > getOverruns() noexcept
In case the callback is not immediately called by the operating system, getOverruns() returns the add...
TimerError getError() const noexcept
Returns the error that occured on constructing the object.
Timer(const units::Duration timeToWait) noexcept
Creates a timer without an operating system callback.
cxx::expected< TimerError > restart(const units::Duration timeToWait, const RunMode runMode, const CatchUpPolicy catchUpPolicy) noexcept
Disarms the timer, assigns a new timeToWait value and arms the timer.
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:29