-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add new time.h/c * Update documentation to distinguish between unspecified/infinite * Add overflow/bounds checking for time utils Signed-off-by: Emerson Knapp <[email protected]>
- Loading branch information
Emerson Knapp
committed
Mar 1, 2021
1 parent
94f4f33
commit d71e386
Showing
8 changed files
with
310 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef RMW__TIME_H_ | ||
#define RMW__TIME_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif // __cplusplus | ||
|
||
#include <stdint.h> | ||
|
||
#include "rcutils/time.h" | ||
|
||
#include "rmw/macros.h" | ||
#include "rmw/visibility_control.h" | ||
|
||
/// A struct representing a duration or relative time in RMW - does not encode an origin. | ||
typedef struct RMW_PUBLIC_TYPE rmw_time_t | ||
{ | ||
/// Seconds component | ||
uint64_t sec; | ||
|
||
/// Nanoseconds component | ||
uint64_t nsec; | ||
} rmw_time_t; | ||
|
||
typedef rcutils_time_point_value_t rmw_time_point_value_t; | ||
typedef rcutils_duration_value_t rmw_duration_t; | ||
|
||
/// Constant representing an infinite duration. Use rmw_time_equal for comparisons. | ||
/** | ||
* Different RMW implementations have different representations for infinite durations. | ||
* This value is reported for QoS policy durations that are left unspecified. | ||
* Do not directly compare `sec == sec && nsec == nsec`, because we don't want to be sensitive | ||
* to non-normalized values (nsec > 1 second) - use rmw_time_equal instead. | ||
* This value is INT64_MAX nanoseconds = 0x7FFF FFFF FFFF FFFF = d 9 223 372 036 854 775 807 | ||
*/ | ||
static const struct rmw_time_t RMW_DURATION_INFINITE = {9223372036LL, 854775807LL}; | ||
static const struct rmw_time_t RMW_DURATION_UNSPECIFIED = {0LL, 0LL}; | ||
|
||
/// Check whether two rmw_time_t represent the same time. | ||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
bool | ||
rmw_time_equal(const rmw_time_t left, const rmw_time_t right); | ||
|
||
/// Return the total nanosecond representation of a time. | ||
/** | ||
* \return INT64_MAX if input is too large to store in 64 bits | ||
*/ | ||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
rmw_duration_t | ||
rmw_time_total_nsec(const rmw_time_t time); | ||
|
||
/// Construct rmw_time_t from a total nanoseconds representation. | ||
/** | ||
* rmw_time_t only specifies relative time, so the origin is not relevant for this calculation. | ||
* \return RMW_DURATION_INFINITE if input is negative, which is not representable in rmw_time_t | ||
*/ | ||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
rmw_time_t | ||
rmw_time_from_nsec(const rmw_duration_t nanoseconds); | ||
|
||
/// Ensure that an rmw_time_t does not have nanoseconds > 1 second. | ||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
rmw_time_t | ||
rmw_time_normalize(const rmw_time_t time); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif // __cplusplus | ||
|
||
#endif // RMW__TIME_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "rmw/time.h" | ||
|
||
#include "rcutils/time.h" | ||
|
||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
bool | ||
rmw_time_equal(const rmw_time_t left, const rmw_time_t right) | ||
{ | ||
return rmw_time_total_nsec(left) == rmw_time_total_nsec(right); | ||
} | ||
|
||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
rmw_duration_t | ||
rmw_time_total_nsec(const rmw_time_t time) | ||
{ | ||
static const int64_t max_sec = INT64_MAX / RCUTILS_S_TO_NS(1); | ||
if ((int64_t)time.sec > max_sec) { | ||
// Seconds not representable in nanoseconds | ||
return INT64_MAX; | ||
} | ||
|
||
const int64_t sec_as_nsec = RCUTILS_S_TO_NS(time.sec); | ||
if ((int64_t)time.nsec > (INT64_MAX - sec_as_nsec)) { | ||
// overflow | ||
return INT64_MAX; | ||
} | ||
return sec_as_nsec + time.nsec; | ||
} | ||
|
||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
rmw_time_t | ||
rmw_time_from_nsec(const rmw_duration_t nanoseconds) | ||
{ | ||
if (nanoseconds < 0) { | ||
return RMW_DURATION_INFINITE; | ||
} | ||
|
||
// Avoid typing the 1 billion constant | ||
rmw_time_t time; | ||
time.sec = RCUTILS_NS_TO_S(nanoseconds); | ||
time.nsec = nanoseconds % RCUTILS_S_TO_NS(1); | ||
return time; | ||
} | ||
|
||
RMW_PUBLIC | ||
RMW_WARN_UNUSED | ||
rmw_time_t | ||
rmw_time_normalize(const rmw_time_t time) | ||
{ | ||
return rmw_time_from_nsec(rmw_time_total_nsec(time)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.