aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/time_provider/monotonic.h
blob: 9b5e5df149b44bb2a7c4dd470b9c786b6e73a329 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#pragma once

#include <util/datetime/base.h>

namespace NMonotonic {

    template <class TDerived>
    class TMonotonicBase: public TTimeBase<TDerived> {
        using TBase = TTimeBase<TDerived>;

    public:
        using TBase::TBase;

        using TBase::Days;
        using TBase::Hours;
        using TBase::MicroSeconds;
        using TBase::MilliSeconds;
        using TBase::Minutes;
        using TBase::Seconds;

        static constexpr TDerived Max() noexcept {
            return TDerived::FromValue(::Max<ui64>());
        }

        static constexpr TDerived Zero() noexcept {
            return TDerived::FromValue(0);
        }

        static constexpr TDerived MicroSeconds(ui64 us) noexcept {
            return TDerived::FromValue(TInstant::MicroSeconds(us).GetValue());
        }

        static constexpr TDerived MilliSeconds(ui64 ms) noexcept {
            return TDerived::FromValue(TInstant::MilliSeconds(ms).GetValue());
        }

        static constexpr TDerived Seconds(ui64 s) noexcept {
            return TDerived::FromValue(TInstant::Seconds(s).GetValue());
        }

        static constexpr TDerived Minutes(ui64 m) noexcept {
            return TDerived::FromValue(TInstant::Minutes(m).GetValue());
        }

        static constexpr TDerived Hours(ui64 h) noexcept {
            return TDerived::FromValue(TInstant::Hours(h).GetValue());
        }

        static constexpr TDerived Days(ui64 d) noexcept {
            return TDerived::FromValue(TInstant::Days(d).GetValue());
        }
    };

    /**
     * Returns current monotonic time in microseconds
     */
    ui64 GetMonotonicMicroSeconds();

    /**
     * Similar to TInstant, but measuring monotonic time
     */
    class TMonotonic: public TMonotonicBase<TMonotonic> {
        using TBase = TMonotonicBase<TMonotonic>;

    protected:
        constexpr explicit TMonotonic(TValue value) noexcept
            : TBase(value)
        {
        }

    public:
        constexpr TMonotonic() noexcept {
        }

        static constexpr TMonotonic FromValue(TValue value) noexcept {
            return TMonotonic(value);
        }

        static inline TMonotonic Now() {
            return TMonotonic::MicroSeconds(GetMonotonicMicroSeconds());
        }

        using TBase::Days;
        using TBase::Hours;
        using TBase::MicroSeconds;
        using TBase::MilliSeconds;
        using TBase::Minutes;
        using TBase::Seconds;

        template <class T>
        inline TMonotonic& operator+=(const T& t) noexcept {
            return (*this = (*this + t));
        }

        template <class T>
        inline TMonotonic& operator-=(const T& t) noexcept {
            return (*this = (*this - t));
        }
    };

    /**
     * Returns current CLOCK_BOOTTIME time in microseconds
     */
    ui64 GetBootTimeMicroSeconds();

    /**
     * Similar to TInstant, but measuring CLOCK_BOOTTIME time
     */
    class TBootTime: public TMonotonicBase<TBootTime> {
        using TBase = TMonotonicBase<TBootTime>;

    protected:
        constexpr explicit TBootTime(TValue value) noexcept
            : TBase(value)
        {
        }

    public:
        constexpr TBootTime() noexcept {
        }

        static constexpr TBootTime FromValue(TValue value) noexcept {
            return TBootTime(value);
        }

        static inline TBootTime Now() {
            return TBootTime::MicroSeconds(GetBootTimeMicroSeconds());
        }

        using TBase::Days;
        using TBase::Hours;
        using TBase::MicroSeconds;
        using TBase::MilliSeconds;
        using TBase::Minutes;
        using TBase::Seconds;

        template <class T>
        inline TBootTime& operator+=(const T& t) noexcept {
            return (*this = (*this + t));
        }

        template <class T>
        inline TBootTime& operator-=(const T& t) noexcept {
            return (*this = (*this - t));
        }
    };

} // namespace NMonotonic

Y_DECLARE_PODTYPE(NMonotonic::TMonotonic);
Y_DECLARE_PODTYPE(NMonotonic::TBootTime);

namespace std {
    template <>
    struct hash<NMonotonic::TMonotonic> {
        size_t operator()(const NMonotonic::TMonotonic& key) const noexcept {
            return hash<NMonotonic::TMonotonic::TValue>()(key.GetValue());
        }
    };

    template <>
    struct hash<NMonotonic::TBootTime> {
        size_t operator()(const NMonotonic::TBootTime& key) const noexcept {
            return hash<NMonotonic::TBootTime::TValue>()(key.GetValue());
        }
    };
}

namespace NMonotonic {

    constexpr TDuration operator-(const TMonotonic& l, const TMonotonic& r) {
        return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue());
    }

    constexpr TMonotonic operator+(const TMonotonic& l, const TDuration& r) {
        TInstant result = TInstant::FromValue(l.GetValue()) + r;
        return TMonotonic::FromValue(result.GetValue());
    }

    constexpr TMonotonic operator-(const TMonotonic& l, const TDuration& r) {
        TInstant result = TInstant::FromValue(l.GetValue()) - r;
        return TMonotonic::FromValue(result.GetValue());
    }

    constexpr TDuration operator-(const TBootTime& l, const TBootTime& r) {
        return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue());
    }

    constexpr TBootTime operator+(const TBootTime& l, const TDuration& r) {
        TInstant result = TInstant::FromValue(l.GetValue()) + r;
        return TBootTime::FromValue(result.GetValue());
    }

    constexpr TBootTime operator-(const TBootTime& l, const TDuration& r) {
        TInstant result = TInstant::FromValue(l.GetValue()) - r;
        return TBootTime::FromValue(result.GetValue());
    }

} // namespace NMonotonic

// TODO: remove, alias for compatibility
using TMonotonic = NMonotonic::TMonotonic;