From 79792b5fda9d0accf9dfdf4f7217fe441e810e57 Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Thu, 20 Feb 2020 13:52:26 -0300 Subject: [PATCH 1/4] Improve rcl clock API documentation. Signed-off-by: Michel Hidalgo --- rcl/include/rcl/time.h | 178 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/rcl/include/rcl/time.h b/rcl/include/rcl/time.h index c5dea13d1..10d530c4b 100644 --- a/rcl/include/rcl/time.h +++ b/rcl/include/rcl/time.h @@ -149,6 +149,14 @@ typedef struct rcl_time_point_t * are not invalid. * Note that if data is uninitialized it may give a false positive. * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock the handle to the clock which is being queried * \return true if the source is believed to be valid, otherwise return false. */ @@ -161,6 +169,15 @@ rcl_clock_valid(rcl_clock_t * clock); /** * This will allocate all necessary internal structures, and initialize variables. * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes [1] + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * [1] if `clock_type` is `RCL_ROS_TIME` + * * \param[in] clock_type the type identifying the time source to provide * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations @@ -183,6 +200,17 @@ rcl_clock_init( * Passing a clock with type RCL_CLOCK_UNINITIALIZED will result in * RCL_RET_INVALID_ARGUMENT being returned. * + * This function is not thread-safe with any other function operating on the same + * clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock the handle to the clock which is being finalized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -199,6 +227,14 @@ rcl_clock_fini( * This will allocate all necessary internal structures, and initialize variables. * It is specifically setting up a RCL_ROS_TIME time source. * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations * \return `RCL_RET_OK` if the time source was successfully initialized, or @@ -218,6 +254,17 @@ rcl_ros_clock_init( * It is specifically setting up a `RCL_ROS_TIME` time source. It is expected * to be paired with the init fuction. * + * This function is not thread-safe with any other function operating on the same + * clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock the handle to the clock which is being initialized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -234,6 +281,14 @@ rcl_ros_clock_fini( * This will allocate all necessary internal structures, and initialize variables. * It is specifically setting up a `RCL_STEADY_TIME` time source. * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations * \return `RCL_RET_OK` if the time source was successfully initialized, or @@ -255,6 +310,18 @@ rcl_steady_clock_init( * It is specifically setting up a steady time source. It is expected to be * paired with the init fuction. * + * This function is not thread-safe with any other function operating on the same + * clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * + * [1] if jump callbacks were added * \param[in] clock the handle to the clock which is being initialized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -273,6 +340,14 @@ rcl_steady_clock_fini( * This will allocate all necessary internal structures, and initialize variables. * It is specifically setting up a system time source. * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations * \return `RCL_RET_OK` if the time source was successfully initialized, or @@ -294,6 +369,17 @@ rcl_system_clock_init( * It is specifically setting up a system time source. It is expected to be paired with * the init fuction. * + * This function is not thread-safe with any function operating on the same clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes [1] + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * [1] if jump callbacks were added + * * \param[in] clock the handle to the clock which is being initialized. * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -314,6 +400,14 @@ rcl_system_clock_fini( * The value will be computed as duration = finish - start. If start is after * finish the duration will be negative. * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] start The time point for the start of the duration. * \param[in] finish The time point for the end of the duration. * \param[out] delta The duration between the start and finish. @@ -331,6 +425,17 @@ rcl_difference_times( /** * This function will populate the data of the time_point_value object with the * current value from it's associated time abstraction. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | Yes [1] + * Lock-Free | Yes + * + * [1] if `clock` is of `RCL_ROS_TIME` type + * * \param[in] clock The time source from which to set the value. * \param[out] time_point_value The time_point value to populate. * \return `RCL_RET_OK` if the last call time was retrieved successfully, or @@ -349,6 +454,18 @@ rcl_clock_get_now(rcl_clock_t * clock, rcl_time_point_value_t * time_point_value * such that the time source will report the set value instead of falling * back to system time. * + * This function is not thread-safe with `rcl_clock_add_jump_callback`, + * nor `rcl_clock_remove_jump_callback` functions when used on the same + * clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock The clock to enable. * \return `RCL_RET_OK` if the time source was enabled successfully, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -365,6 +482,18 @@ rcl_enable_ros_time_override(rcl_clock_t * clock); * such that the time source will report the system time even if a custom * value has been set. * + * This function is not thread-safe with `rcl_clock_add_jump_callback`, + * nor `rcl_clock_remove_jump_callback` functions when used on the same + * clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock The clock to disable. * \return `RCL_RET_OK` if the time source was disabled successfully, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -382,6 +511,17 @@ rcl_disable_ros_time_override(rcl_clock_t * clock); * time overide is enabled. If it is enabled, the set value will be returned. * Otherwise this time source will return the equivalent to system time abstraction. * + * This function is not thread-safe with `rcl_enable_ros_time_override` nor + * `rcl_disable_ros_time_override` functions when used on the same clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock The clock to query. * \param[out] is_enabled Whether the override is enabled.. * \return `RCL_RET_OK` if the time source was queried successfully, or @@ -401,6 +541,18 @@ rcl_is_enabled_ros_time_override( * If queried and override enabled the time source will return this value, * otherwise it will return the system time. * + * This function is not thread-safe with `rcl_clock_add_jump_callback`, + * nor `rcl_clock_remove_jump_callback` functions when used on the same + * clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | No + * Uses Atomics | Yes + * Lock-Free | Yes + * * \param[in] clock The clock to update. * \param[in] time_value The new current time. * \return `RCL_RET_OK` if the time source was set successfully, or @@ -420,11 +572,24 @@ rcl_set_ros_time_override( * The user_data pointer is passed to the callback as the last argument. * A callback and user_data pair must be unique among the callbacks added to a clock. * + * This function is not thread-safe with `rcl_clock_remove_jump_callback`, + * `rcl_enable_ros_time_override`, `rcl_disable_ros_time_override` nor + * `rcl_set_ros_time_override` functions when used on the same clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock A clock to add a jump callback to. * \param[in] threshold Criteria indicating when to call the callback. * \param[in] callback A callback to call. * \param[in] user_data A pointer to be passed to the callback. * \return `RCL_RET_OK` if the callback was added successfully, or + * \return `RCL_RET_BAD_ALLOC` if a memory allocation failed, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or * \return `RCL_RET_ERROR` an unspecified error occurs. */ @@ -437,11 +602,24 @@ rcl_clock_add_jump_callback( /// Remove a previously added time jump callback. /** + * This function is not thread-safe with `rcl_clock_add_jump_callback` + * `rcl_enable_ros_time_override`, `rcl_disable_ros_time_override` nor + * `rcl_set_ros_time_override` functions when used on the same clock object. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * * \param[in] clock The clock to remove a jump callback from. * \param[in] threshold Criteria indicating when to call callback. * \param[in] callback The callback to call. * \param[in] user_data A pointer to be passed to the callback. * \return `RCL_RET_OK` if the callback was added successfully, or + * \return `RCL_RET_BAD_ALLOC` if a memory allocation failed, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or * \return `RCL_RET_ERROR` the callback was not found or an unspecified error occurs. */ From a018f15003072bf1a10cdf01aa1c49c63ed3fae8 Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Thu, 20 Feb 2020 13:52:38 -0300 Subject: [PATCH 2/4] Improve rcl clock API error checking. Signed-off-by: Michel Hidalgo --- rcl/src/rcl/time.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rcl/src/rcl/time.c b/rcl/src/rcl/time.c index 4772e757b..81784a8a0 100644 --- a/rcl/src/rcl/time.c +++ b/rcl/src/rcl/time.c @@ -232,6 +232,9 @@ rcl_ret_t rcl_difference_times( rcl_time_point_t * start, rcl_time_point_t * finish, rcl_duration_t * delta) { + RCL_CHECK_ARGUMENT_FOR_NULL(start, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(finish, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(delta, RCL_RET_INVALID_ARGUMENT); if (start->clock_type != finish->clock_type) { RCL_SET_ERROR_MSG("Cannot difference between time points with clocks types."); return RCL_RET_ERROR; From 03d4a769cf9515c6101a32b27c381af9322d6706 Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Fri, 21 Feb 2020 10:45:09 -0300 Subject: [PATCH 3/4] Address peer review comments. Signed-off-by: Michel Hidalgo --- rcl/include/rcl/time.h | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/rcl/include/rcl/time.h b/rcl/include/rcl/time.h index 10d530c4b..fb18b9ea3 100644 --- a/rcl/include/rcl/time.h +++ b/rcl/include/rcl/time.h @@ -176,7 +176,8 @@ rcl_clock_valid(rcl_clock_t * clock); * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes - * [1] if `clock_type` is `RCL_ROS_TIME` + * + * [1] If `clock_type` is `RCL_ROS_TIME` * * \param[in] clock_type the type identifying the time source to provide * \param[in] clock the handle to the clock which is being initialized @@ -206,7 +207,7 @@ rcl_clock_init( *
* Attribute | Adherence * ------------------ | ------------- - * Allocates Memory | Yes + * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes @@ -230,7 +231,7 @@ rcl_clock_fini( *
* Attribute | Adherence * ------------------ | ------------- - * Allocates Memory | No + * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes @@ -260,7 +261,7 @@ rcl_ros_clock_init( *
* Attribute | Adherence * ------------------ | ------------- - * Allocates Memory | Yes + * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes @@ -316,12 +317,11 @@ rcl_steady_clock_init( *
* Attribute | Adherence * ------------------ | ------------- - * Allocates Memory | Yes + * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * - * [1] if jump callbacks were added * \param[in] clock the handle to the clock which is being initialized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -374,11 +374,10 @@ rcl_system_clock_init( *
* Attribute | Adherence * ------------------ | ------------- - * Allocates Memory | Yes [1] + * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes - * [1] if jump callbacks were added * * \param[in] clock the handle to the clock which is being initialized. * \return `RCL_RET_OK` if the time source was successfully finalized, or @@ -434,7 +433,7 @@ rcl_difference_times( * Uses Atomics | Yes [1] * Lock-Free | Yes * - * [1] if `clock` is of `RCL_ROS_TIME` type + * [1] If `clock` is of `RCL_ROS_TIME` type * * \param[in] clock The time source from which to set the value. * \param[out] time_point_value The time_point value to populate. @@ -459,13 +458,15 @@ rcl_clock_get_now(rcl_clock_t * clock, rcl_time_point_value_t * time_point_value * clock object. * *
- * Attribute | Adherence + * Attribute | Adherence [1] * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * + * [1] Only applies to the function itself, as jump callbacks may not abide to it + * * \param[in] clock The clock to enable. * \return `RCL_RET_OK` if the time source was enabled successfully, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -487,13 +488,15 @@ rcl_enable_ros_time_override(rcl_clock_t * clock); * clock object. * *
- * Attribute | Adherence + * Attribute | Adherence [1] * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * + * [1] Only applies to the function itself, as jump callbacks may not abide to it + * * \param[in] clock The clock to disable. * \return `RCL_RET_OK` if the time source was disabled successfully, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -546,13 +549,15 @@ rcl_is_enabled_ros_time_override( * clock object. * *
- * Attribute | Adherence + * Attribute | Adherence [1] * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | Yes * Lock-Free | Yes * + * [1] Only applies to the function itself, as jump callbacks may not abide to it + * * \param[in] clock The clock to update. * \param[in] time_value The new current time. * \return `RCL_RET_OK` if the time source was set successfully, or From ca78af86b84e3f7ab84ac08300aa341dc2a3e36a Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Thu, 12 Mar 2020 15:47:12 -0300 Subject: [PATCH 4/4] Refine rcl_clock_t API thread-safety documentation. Signed-off-by: Michel Hidalgo --- rcl/include/rcl/time.h | 77 ++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/rcl/include/rcl/time.h b/rcl/include/rcl/time.h index fb18b9ea3..ed5c88b4c 100644 --- a/rcl/include/rcl/time.h +++ b/rcl/include/rcl/time.h @@ -173,11 +173,13 @@ rcl_clock_valid(rcl_clock_t * clock); * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes [1] - * Thread-Safe | No + * Thread-Safe | No [2] * Uses Atomics | No * Lock-Free | Yes * * [1] If `clock_type` is `RCL_ROS_TIME` + * [2] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object. * * \param[in] clock_type the type identifying the time source to provide * \param[in] clock the handle to the clock which is being initialized @@ -208,10 +210,14 @@ rcl_clock_init( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock the handle to the clock which is being finalized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -232,10 +238,13 @@ rcl_clock_fini( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [2] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object. + * * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations * \return `RCL_RET_OK` if the time source was successfully initialized, or @@ -262,10 +271,14 @@ rcl_ros_clock_init( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock the handle to the clock which is being initialized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -286,10 +299,13 @@ rcl_ros_clock_fini( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object. + * * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations * \return `RCL_RET_OK` if the time source was successfully initialized, or @@ -318,10 +334,14 @@ rcl_steady_clock_init( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock the handle to the clock which is being initialized * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -344,10 +364,14 @@ rcl_steady_clock_fini( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock the handle to the clock which is being initialized * \param[in] allocator The allocator to use for allocations * \return `RCL_RET_OK` if the time source was successfully initialized, or @@ -375,10 +399,14 @@ rcl_system_clock_init( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock the handle to the clock which is being initialized. * \return `RCL_RET_OK` if the time source was successfully finalized, or * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or @@ -433,7 +461,7 @@ rcl_difference_times( * Uses Atomics | Yes [1] * Lock-Free | Yes * - * [1] If `clock` is of `RCL_ROS_TIME` type + * [1] If `clock` is of `RCL_ROS_TIME` type. * * \param[in] clock The time source from which to set the value. * \param[out] time_point_value The time_point value to populate. @@ -461,11 +489,12 @@ rcl_clock_get_now(rcl_clock_t * clock, rcl_time_point_value_t * time_point_value * Attribute | Adherence [1] * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [2] * Uses Atomics | No * Lock-Free | Yes * - * [1] Only applies to the function itself, as jump callbacks may not abide to it + * [1] Only applies to the function itself, as jump callbacks may not abide to it. + * [2] Function is reentrant, but concurrent calls on the same `clock` object are not safe. * * \param[in] clock The clock to enable. * \return `RCL_RET_OK` if the time source was enabled successfully, or @@ -491,11 +520,12 @@ rcl_enable_ros_time_override(rcl_clock_t * clock); * Attribute | Adherence [1] * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [2] * Uses Atomics | No * Lock-Free | Yes * - * [1] Only applies to the function itself, as jump callbacks may not abide to it + * [1] Only applies to the function itself, as jump callbacks may not abide to it. + * [2] Function is reentrant, but concurrent calls on the same `clock` object are not safe. * * \param[in] clock The clock to disable. * \return `RCL_RET_OK` if the time source was disabled successfully, or @@ -521,10 +551,12 @@ rcl_disable_ros_time_override(rcl_clock_t * clock); * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * * \param[in] clock The clock to query. * \param[out] is_enabled Whether the override is enabled.. * \return `RCL_RET_OK` if the time source was queried successfully, or @@ -552,11 +584,12 @@ rcl_is_enabled_ros_time_override( * Attribute | Adherence [1] * ------------------ | ------------- * Allocates Memory | No - * Thread-Safe | No + * Thread-Safe | No [2] * Uses Atomics | Yes * Lock-Free | Yes * - * [1] Only applies to the function itself, as jump callbacks may not abide to it + * [1] Only applies to the function itself, as jump callbacks may not abide to it. + * [2] Function is reentrant, but concurrent calls on the same `clock` object are not safe. * * \param[in] clock The clock to update. * \param[in] time_value The new current time. @@ -585,10 +618,14 @@ rcl_set_ros_time_override( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock A clock to add a jump callback to. * \param[in] threshold Criteria indicating when to call the callback. * \param[in] callback A callback to call. @@ -615,10 +652,14 @@ rcl_clock_add_jump_callback( * Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes - * Thread-Safe | No + * Thread-Safe | No [1] * Uses Atomics | No * Lock-Free | Yes * + * [1] Function is reentrant, but concurrent calls on the same `clock` object are not safe. + * Thread-safety is also affected by that of the `allocator` object associated with the + * `clock` object. + * * \param[in] clock The clock to remove a jump callback from. * \param[in] threshold Criteria indicating when to call callback. * \param[in] callback The callback to call.