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