• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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