1 /* 2 * Copyright (c) 2019, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for time instance. 32 */ 33 34 #ifndef TIME_HPP_ 35 #define TIME_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <stddef.h> 40 #include <stdint.h> 41 42 #include "common/equatable.hpp" 43 #include "common/serial_number.hpp" 44 45 namespace ot { 46 47 /** 48 * @addtogroup core-timer 49 * 50 * @brief 51 * This module includes definitions for the time instance. 52 * 53 * @{ 54 */ 55 56 /** 57 * Represents a time instance. 58 */ 59 class Time : public Unequatable<Time> 60 { 61 public: 62 static constexpr uint32_t kOneMinuteInSec = 60; ///< One minute interval in sec. 63 static constexpr uint32_t kOneHourInSec = 60 * kOneMinuteInSec; ///< One hour interval in sec. 64 static constexpr uint32_t kOneDayInSec = 24 * kOneHourInSec; ///< One day interval in sec. 65 66 static constexpr uint32_t kOneSecondInMsec = 1000u; ///< One second interval in msec. 67 static constexpr uint32_t kOneMinuteInMsec = kOneMinuteInSec * kOneSecondInMsec; ///< One minute interval in msec. 68 static constexpr uint32_t kOneHourInMsec = kOneHourInSec * kOneSecondInMsec; ///< One hour interval in msec. 69 static constexpr uint32_t kOneDayInMsec = kOneDayInSec * kOneSecondInMsec; ///< One day interval in msec. 70 71 static constexpr uint32_t kOneMsecInUsec = 1000u; ///< One millisecond in microseconds. 72 static constexpr uint32_t kOneSecondInUsec = 1000000u; ///< One second interval in microseconds. 73 74 /** 75 * This constant defines a maximum time duration ensured to be longer than any other duration. 76 */ 77 static const uint32_t kMaxDuration = ~static_cast<uint32_t>(0UL); 78 79 /** 80 * This is the default constructor for a `Time` object. 81 */ 82 Time(void) = default; 83 84 /** 85 * Initializes a `Time` object with a given value. 86 * 87 * @param[in] aValue The numeric time value to initialize the `Time` object. 88 */ Time(uint32_t aValue)89 explicit Time(uint32_t aValue) { SetValue(aValue); } 90 91 /** 92 * Gets the numeric time value associated with the `Time` object. 93 * 94 * @returns The numeric `Time` value. 95 */ GetValue(void) const96 uint32_t GetValue(void) const { return mValue; } 97 98 /** 99 * Sets the numeric time value. 100 * 101 * @param[in] aValue The numeric time value. 102 */ SetValue(uint32_t aValue)103 void SetValue(uint32_t aValue) { mValue = aValue; } 104 105 /** 106 * Calculates the time duration between two `Time` instances. 107 * 108 * @note Expression `(t1 - t2)` returns the duration of the interval starting from `t2` and ending at `t1`. When 109 * calculating the duration, `t2 is assumed to be in the past relative to `t1`. The duration calculation correctly 110 * takes into account the wrapping of numeric value of `Time` instances. The returned value can span the entire 111 * range of the `uint32_t` type. 112 * 113 * @param[in] aOther A `Time` instance to subtract from. 114 * 115 * @returns The duration of interval from @p aOther to this `Time` object. 116 */ operator -(const Time & aOther) const117 uint32_t operator-(const Time &aOther) const { return mValue - aOther.mValue; } 118 119 /** 120 * Returns a new `Time` which is ahead of this `Time` object by a given duration. 121 * 122 * @param[in] aDuration A duration. 123 * 124 * @returns A new `Time` which is ahead of this object by @aDuration. 125 */ operator +(uint32_t aDuration) const126 Time operator+(uint32_t aDuration) const { return Time(mValue + aDuration); } 127 128 /** 129 * Returns a new `Time` which is behind this `Time` object by a given duration. 130 * 131 * @param[in] aDuration A duration. 132 * 133 * @returns A new `Time` which is behind this object by @aDuration. 134 */ operator -(uint32_t aDuration) const135 Time operator-(uint32_t aDuration) const { return Time(mValue - aDuration); } 136 137 /** 138 * Moves this `Time` object forward by a given duration. 139 * 140 * @param[in] aDuration A duration. 141 */ operator +=(uint32_t aDuration)142 void operator+=(uint32_t aDuration) { mValue += aDuration; } 143 144 /** 145 * Moves this `Time` object backward by a given duration. 146 * 147 * @param[in] aDuration A duration. 148 */ operator -=(uint32_t aDuration)149 void operator-=(uint32_t aDuration) { mValue -= aDuration; } 150 151 /** 152 * Indicates whether two `Time` instances are equal. 153 * 154 * @param[in] aOther A `Time` instance to compare with. 155 * 156 * @retval TRUE The two `Time` instances are equal. 157 * @retval FALSE The two `Time` instances are not equal. 158 */ operator ==(const Time & aOther) const159 bool operator==(const Time &aOther) const { return mValue == aOther.mValue; } 160 161 /** 162 * Indicates whether this `Time` instance is strictly before another one. 163 * 164 * @note The comparison operators correctly take into account the wrapping of `Time` numeric value. For a given 165 * `Time` instance `t0`, any `Time` instance `t` where `(t - t0)` is less than half the range of `uint32_t` type 166 * is considered to be after `t0`, otherwise it is considered to be before 't0' (or equal to it). As an example 167 * to illustrate this model we can use clock hours: If we are at hour 12, hours 1 to 5 are considered to be 168 * after 12, and hours 6 to 11 are considered to be before 12. 169 * 170 * @param[in] aOther A `Time` instance to compare with. 171 * 172 * @retval TRUE This `Time` instance is strictly before @p aOther. 173 * @retval FALSE This `Time` instance is not strictly before @p aOther. 174 */ operator <(const Time & aOther) const175 bool operator<(const Time &aOther) const { return SerialNumber::IsLess(mValue, aOther.mValue); } 176 177 /** 178 * Indicates whether this `Time` instance is after or equal to another one. 179 * 180 * @param[in] aOther A `Time` instance to compare with. 181 * 182 * @retval TRUE This `Time` instance is after or equal to @p aOther. 183 * @retval FALSE This `Time` instance is not after or equal to @p aOther. 184 */ operator >=(const Time & aOther) const185 bool operator>=(const Time &aOther) const { return !(*this < aOther); } 186 187 /** 188 * Indicates whether this `Time` instance is before or equal to another one. 189 * 190 * @param[in] aOther A `Time` instance to compare with. 191 * 192 * @retval TRUE This `Time` instance is before or equal to @p aOther. 193 * @retval FALSE This `Time` instance is not before or equal to @p aOther. 194 */ operator <=(const Time & aOther) const195 bool operator<=(const Time &aOther) const { return (aOther >= *this); } 196 197 /** 198 * Indicates whether this `Time` instance is strictly after another one. 199 * 200 * @param[in] aOther A `Time` instance to compare with. 201 * 202 * @retval TRUE This `Time` instance is strictly after @p aOther. 203 * @retval FALSE This `Time` instance is not strictly after @p aOther. 204 */ operator >(const Time & aOther) const205 bool operator>(const Time &aOther) const { return (aOther < *this); } 206 207 /** 208 * Returns a new `Time` instance which is in distant future relative to current `Time` object. 209 * 210 * The distant future is the largest time that is ahead of `Time`. For any time `t`, if `(*this <= t)`, then 211 * `t <= this->GetGetDistantFuture()`, except for the ambiguous `t` value which is half range `(1 << 31)` apart. 212 * 213 * When comparing `GetDistantFuture()` with a time `t` the caller must ensure that `t` is already ahead of `*this`. 214 * 215 * @returns A new `Time` in distance future relative to current `Time` object. 216 */ GetDistantFuture(void) const217 Time GetDistantFuture(void) const { return Time(mValue + kDistantInterval); } 218 219 /** 220 * Returns a new `Time` instance which is in distant past relative to current `Time` object. 221 * 222 * The distant past is the smallest time that is before `Time`. For any time `t`, if `(t <= *this )`, then 223 * `this->GetGetDistantPast() <= t`, except for the ambiguous `t` value which is half range `(1 << 31)` apart. 224 * 225 * When comparing `GetDistantPast()` with a time `t` the caller must ensure that the `t` is already before `*this`. 226 * 227 * @returns A new `Time` in distance past relative to current `Time` object. 228 */ GetDistantPast(void) const229 Time GetDistantPast(void) const { return Time(mValue - kDistantInterval); } 230 231 /** 232 * Converts a given number of seconds to milliseconds. 233 * 234 * @param[in] aSeconds The seconds value to convert to milliseconds. 235 * 236 * @returns The number of milliseconds. 237 */ SecToMsec(uint32_t aSeconds)238 static uint32_t constexpr SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; } 239 240 /** 241 * Converts a given number of milliseconds to seconds. 242 * 243 * @param[in] aMilliseconds The milliseconds value to convert to seconds. 244 * 245 * @returns The number of seconds. 246 */ MsecToSec(uint32_t aMilliseconds)247 static uint32_t constexpr MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; } 248 249 private: 250 static constexpr uint32_t kDistantInterval = (1UL << 31) - 1; 251 252 uint32_t mValue; 253 }; 254 255 /** 256 * Represents a time instance (millisecond time). 257 */ 258 typedef Time TimeMilli; 259 260 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 261 262 /** 263 * Represents a time instance (microsecond time). 264 */ 265 typedef Time TimeMicro; 266 267 #endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 268 269 /** 270 * @} 271 */ 272 273 } // namespace ot 274 275 #endif // TIME_HPP_ 276