From 336f11dc31e3b8f6f10d89a357ba726eafb783ec Mon Sep 17 00:00:00 2001 From: Nathan Hui Date: Wed, 2 Apr 2025 12:22:44 +1100 Subject: [PATCH] Added rcl_timer_get_next_call_time (#1146) (cherry-picked from commit 2e9549c0301a0d390eea7f3d2b9251626e03b376) Signed-off-by: Nathan Hui --- rcl/include/rcl/timer.h | 24 ++++++++++++++++++++++++ rcl/src/rcl/timer.c | 16 ++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/rcl/include/rcl/timer.h b/rcl/include/rcl/timer.h index ec08acf0b..f6fb4eabb 100644 --- a/rcl/include/rcl/timer.h +++ b/rcl/include/rcl/timer.h @@ -325,6 +325,30 @@ RCL_WARN_UNUSED rcl_ret_t rcl_timer_get_time_until_next_call(const rcl_timer_t * timer, int64_t * time_until_next_call); +/// Retrieve the time when the next call to rcl_timer_call() shall occur. +/** + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | Yes + * Lock-Free | Yes [1] + * [1] if `atomic_is_lock_free()` returns true for `atomic_int_least64_t` + * + * \param[in] timer the handle to the timer that is being queried + * \param[out] next_call_time the output variable for the result + * \return #RCL_RET_OK if the timer until next call was successfully calculated, or + * \return #RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or + * \return #RCL_RET_TIMER_INVALID if the timer->impl is invalid, or + * \return #RCL_RET_TIMER_CANCELED if the timer is canceled, or + * \return #RCL_RET_ERROR an unspecified error occur. + */ +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_timer_get_next_call_time(const rcl_timer_t * timer, int64_t * next_call_time); + /// Retrieve the time since the previous call to rcl_timer_call() occurred. /** * This function calculates the time since the last call and copies it into diff --git a/rcl/src/rcl/timer.c b/rcl/src/rcl/timer.c index 77239fb39..a3bbe7d43 100644 --- a/rcl/src/rcl/timer.c +++ b/rcl/src/rcl/timer.c @@ -309,6 +309,22 @@ rcl_timer_is_ready(const rcl_timer_t * timer, bool * is_ready) return RCL_RET_OK; } +rcl_ret_t +rcl_timer_get_next_call_time(const rcl_timer_t * timer, int64_t * next_call_time) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(timer->impl, RCL_RET_TIMER_INVALID); + RCL_CHECK_ARGUMENT_FOR_NULL(next_call_time, RCL_RET_INVALID_ARGUMENT); + + if (rcutils_atomic_load_bool(&timer->impl->canceled)) { + return RCL_RET_TIMER_CANCELED; + } + + *next_call_time = + rcutils_atomic_load_int64_t(&timer->impl->next_call_time); + return RCL_RET_OK; +} + rcl_ret_t rcl_timer_get_time_until_next_call(const rcl_timer_t * timer, int64_t * time_until_next_call) {