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 44 namespace ot { 45 46 /** 47 * @addtogroup core-timer 48 * 49 * @brief 50 * This module includes definitions for the time instance. 51 * 52 * @{ 53 * 54 */ 55 56 /** 57 * This class represents a time instance. 58 * 59 */ 60 class Time : public Unequatable<Time> 61 { 62 public: 63 /** 64 * This constant defines a maximum time duration ensured to be longer than any other duration. 65 * 66 */ 67 static const uint32_t kMaxDuration = ~static_cast<uint32_t>(0UL); 68 69 /** 70 * This is the default constructor for a `Time` object. 71 * 72 */ 73 Time(void) = default; 74 75 /** 76 * This constructor initializes a `Time` object with a given value. 77 * 78 * @param[in] aValue The numeric time value to initialize the `Time` object. 79 * 80 */ Time(uint32_t aValue)81 explicit Time(uint32_t aValue) { SetValue(aValue); } 82 83 /** 84 * This method gets the numeric time value associated with the `Time` object. 85 * 86 * @returns The numeric `Time` value. 87 * 88 */ GetValue(void) const89 uint32_t GetValue(void) const { return mValue; } 90 91 /** 92 * This method sets the numeric time value. 93 * 94 * @param[in] aValue The numeric time value. 95 * 96 */ SetValue(uint32_t aValue)97 void SetValue(uint32_t aValue) { mValue = aValue; } 98 99 /** 100 * This method calculates the time duration between two `Time` instances. 101 * 102 * @note Expression `(t1 - t2)` returns the duration of the interval starting from `t2` and ending at `t1`. When 103 * calculating the duration, `t2 is assumed to be in the past relative to `t1`. The duration calculation correctly 104 * takes into account the wrapping of numeric value of `Time` instances. The returned value can span the entire 105 * range of the `uint32_t` type. 106 * 107 * @param[in] aOther A `Time` instance to subtract from. 108 * 109 * @returns The duration of interval from @p aOther to this `Time` object. 110 * 111 */ operator -(const Time & aOther) const112 uint32_t operator-(const Time &aOther) const { return mValue - aOther.mValue; } 113 114 /** 115 * This method returns a new `Time` which is ahead of this `Time` object by a given duration. 116 * 117 * @param[in] aDuration A duration. 118 * 119 * @returns A new `Time` which is ahead of this object by @aDuration. 120 * 121 */ operator +(uint32_t aDuration) const122 Time operator+(uint32_t aDuration) const { return Time(mValue + aDuration); } 123 124 /** 125 * This method returns a new `Time` which is behind this `Time` object by a given duration. 126 * 127 * @param[in] aDuration A duration. 128 * 129 * @returns A new `Time` which is behind this object by @aDuration. 130 * 131 */ operator -(uint32_t aDuration) const132 Time operator-(uint32_t aDuration) const { return Time(mValue - aDuration); } 133 134 /** 135 * This method moves this `Time` object forward by a given duration. 136 * 137 * @param[in] aDuration A duration. 138 * 139 */ operator +=(uint32_t aDuration)140 void operator+=(uint32_t aDuration) { mValue += aDuration; } 141 142 /** 143 * This method moves this `Time` object backward by a given duration. 144 * 145 * @param[in] aDuration A duration. 146 * 147 */ operator -=(uint32_t aDuration)148 void operator-=(uint32_t aDuration) { mValue -= aDuration; } 149 150 /** 151 * This method indicates whether two `Time` instances are equal. 152 * 153 * @param[in] aOther A `Time` instance to compare with. 154 * 155 * @retval TRUE The two `Time` instances are equal. 156 * @retval FALSE The two `Time` instances are not equal. 157 * 158 */ operator ==(const Time & aOther) const159 bool operator==(const Time &aOther) const { return mValue == aOther.mValue; } 160 161 /** 162 * This method 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 * 175 */ operator <(const Time & aOther) const176 bool operator<(const Time &aOther) const { return ((mValue - aOther.mValue) & (1UL << 31)) != 0; } 177 178 /** 179 * This method indicates whether this `Time` instance is after or equal to another one. 180 * 181 * @param[in] aOther A `Time` instance to compare with. 182 * 183 * @retval TRUE This `Time` instance is after or equal to @p aOther. 184 * @retval FALSE This `Time` instance is not after or equal to @p aOther. 185 * 186 */ operator >=(const Time & aOther) const187 bool operator>=(const Time &aOther) const { return !(*this < aOther); } 188 189 /** 190 * This method indicates whether this `Time` instance is before or equal to another one. 191 * 192 * @param[in] aOther A `Time` instance to compare with. 193 * 194 * @retval TRUE This `Time` instance is before or equal to @p aOther. 195 * @retval FALSE This `Time` instance is not before or equal to @p aOther. 196 * 197 */ operator <=(const Time & aOther) const198 bool operator<=(const Time &aOther) const { return (aOther >= *this); } 199 200 /** 201 * This method indicates whether this `Time` instance is strictly after another one. 202 * 203 * @param[in] aOther A `Time` instance to compare with. 204 * 205 * @retval TRUE This `Time` instance is strictly after @p aOther. 206 * @retval FALSE This `Time` instance is not strictly after @p aOther. 207 * 208 */ operator >(const Time & aOther) const209 bool operator>(const Time &aOther) const { return (aOther < *this); } 210 211 /** 212 * This method returns a new `Time` instance which is in distant future relative to current `Time` object. 213 * 214 * The returned distance future `Time` is guaranteed to be equal or after (as defined by comparison operator `<=`) 215 * any other `Time` which is after this `Time` object, i.e., for any `t` for which we have `*this <= t`, it is 216 * ensured that `t <= this->GetGetDistantFuture()`. 217 * 218 * @returns A new `Time` in distance future relative to current `Time` object. 219 * 220 */ GetDistantFuture(void) const221 Time GetDistantFuture(void) const { return Time(mValue + kDistantFuture); } 222 223 /** 224 * This method returns a new `Time` instance which is in distant past relative to current `Time` object. 225 * 226 * The returned distance past `Time` is guaranteed to be equal or before (as defined by comparison operator `>=`) 227 * any other `Time` which is before this `Time` object, i.e., for any `t` for which we have `*this >= t`, it is 228 * ensured that `t >= this->GetDistantPast()`. 229 * 230 * @returns A new `Time` in distance past relative to current `Time` object. 231 * 232 */ GetDistantPast(void) const233 Time GetDistantPast(void) const { return Time(mValue - kDistantFuture); } 234 235 /** 236 * This static method converts a given number of seconds to milliseconds. 237 * 238 * @returns The number of milliseconds. 239 * 240 */ SecToMsec(uint32_t aSeconds)241 static uint32_t SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; } 242 243 /** 244 * This static method converts a given number of milliseconds to seconds. 245 * 246 * @returns The number of seconds. 247 * 248 */ MsecToSec(uint32_t aMilliseconds)249 static uint32_t MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; } 250 251 private: 252 static constexpr uint32_t kDistantFuture = (1UL << 31); 253 254 uint32_t mValue; 255 }; 256 257 /** 258 * This type represents a time instance (millisecond time). 259 * 260 */ 261 typedef Time TimeMilli; 262 263 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 264 265 /** 266 * This type represents a time instance (microsecond time). 267 * 268 */ 269 typedef Time TimeMicro; 270 271 #endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 272 273 /** 274 * @} 275 * 276 */ 277 278 } // namespace ot 279 280 #endif // TIME_HPP_ 281