1 | /* |
2 | * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_UTILITIES_TICKS_HPP |
26 | #define SHARE_UTILITIES_TICKS_HPP |
27 | |
28 | #include "jni.h" |
29 | #include "memory/allocation.hpp" |
30 | #include "utilities/macros.hpp" |
31 | |
32 | // Time sources |
33 | class ElapsedCounterSource { |
34 | public: |
35 | typedef jlong Type; |
36 | static uint64_t frequency(); |
37 | static Type now(); |
38 | static double seconds(Type value); |
39 | static uint64_t milliseconds(Type value); |
40 | static uint64_t microseconds(Type value); |
41 | static uint64_t nanoseconds(Type value); |
42 | }; |
43 | |
44 | // Not guaranteed to be synchronized across hardware threads and |
45 | // therefore software threads, and can be updated asynchronously |
46 | // by software. now() can jump backwards as well as jump forward |
47 | // when threads query different cores/sockets. |
48 | // Very much not recommended for general use. Caveat emptor. |
49 | class FastUnorderedElapsedCounterSource { |
50 | public: |
51 | typedef jlong Type; |
52 | static uint64_t frequency(); |
53 | static Type now(); |
54 | static double seconds(Type value); |
55 | static uint64_t milliseconds(Type value); |
56 | static uint64_t microseconds(Type value); |
57 | static uint64_t nanoseconds(Type value); |
58 | }; |
59 | |
60 | template <typename T1, typename T2> |
61 | class PairRep { |
62 | public: |
63 | T1 val1; |
64 | T2 val2; |
65 | |
66 | PairRep() : val1((T1)0), val2((T2)0) {} |
67 | void operator+=(const PairRep& rhs) { |
68 | val1 += rhs.val1; |
69 | val2 += rhs.val2; |
70 | } |
71 | void operator-=(const PairRep& rhs) { |
72 | val1 -= rhs.val1; |
73 | val2 -= rhs.val2; |
74 | } |
75 | bool operator==(const PairRep& rhs) const { |
76 | return val1 == rhs.val1; |
77 | } |
78 | bool operator!=(const PairRep& rhs) const { |
79 | return !operator==(rhs); |
80 | } |
81 | bool operator<(const PairRep& rhs) const { |
82 | return val1 < rhs.val1; |
83 | } |
84 | bool operator>(const PairRep& rhs) const { |
85 | return val1 > rhs.val1; |
86 | } |
87 | }; |
88 | |
89 | template <typename T1, typename T2> |
90 | PairRep<T1, T2> operator-(const PairRep<T1, T2>& lhs, const PairRep<T1, T2>& rhs) { |
91 | PairRep<T1, T2> temp(lhs); |
92 | temp -= rhs; |
93 | return temp; |
94 | } |
95 | |
96 | typedef PairRep<ElapsedCounterSource::Type, FastUnorderedElapsedCounterSource::Type> CompositeTime; |
97 | |
98 | class CompositeElapsedCounterSource { |
99 | public: |
100 | typedef CompositeTime Type; |
101 | static uint64_t frequency(); |
102 | static Type now(); |
103 | static double seconds(Type value); |
104 | static uint64_t milliseconds(Type value); |
105 | static uint64_t microseconds(Type value); |
106 | static uint64_t nanoseconds(Type value); |
107 | }; |
108 | |
109 | template <typename TimeSource> |
110 | class Representation { |
111 | public: |
112 | typedef typename TimeSource::Type Type; |
113 | protected: |
114 | Type _rep; |
115 | Representation(const Representation<TimeSource>& end, const Representation<TimeSource>& start) : _rep(end._rep - start._rep) {} |
116 | Representation() : _rep() {} |
117 | public: |
118 | void operator+=(const Representation<TimeSource>& rhs) { |
119 | _rep += rhs._rep; |
120 | } |
121 | void operator-=(const Representation<TimeSource>& rhs) { |
122 | _rep -= rhs._rep; |
123 | } |
124 | bool operator==(const Representation<TimeSource>& rhs) const { |
125 | return _rep == rhs._rep; |
126 | } |
127 | bool operator!=(const Representation<TimeSource>& rhs) const { |
128 | return !operator==(rhs); |
129 | } |
130 | bool operator<(const Representation<TimeSource>& rhs) const { |
131 | return _rep < rhs._rep; |
132 | } |
133 | bool operator>(const Representation<TimeSource>& rhs) const { |
134 | return _rep > rhs._rep; |
135 | } |
136 | bool operator<=(const Representation<TimeSource>& rhs) const { |
137 | return !operator>(rhs); |
138 | } |
139 | bool operator>=(const Representation<TimeSource>& rhs) const { |
140 | return !operator<(rhs); |
141 | } |
142 | double seconds() const { |
143 | return TimeSource::seconds(_rep); |
144 | } |
145 | uint64_t milliseconds() const { |
146 | return TimeSource::milliseconds(_rep); |
147 | } |
148 | uint64_t microseconds() const { |
149 | return TimeSource::microseconds(_rep); |
150 | } |
151 | uint64_t nanoseconds() const { |
152 | return TimeSource::nanoseconds(_rep); |
153 | } |
154 | }; |
155 | |
156 | template <typename TimeSource> |
157 | class CounterRepresentation : public Representation<TimeSource> { |
158 | protected: |
159 | CounterRepresentation(const CounterRepresentation& end, const CounterRepresentation& start) : Representation<TimeSource>(end, start) {} |
160 | explicit CounterRepresentation(jlong value) : Representation<TimeSource>() { |
161 | this->_rep = value; |
162 | } |
163 | public: |
164 | CounterRepresentation() : Representation<TimeSource>() {} |
165 | typename TimeSource::Type value() const { return this->_rep; } |
166 | operator typename TimeSource::Type() { return value(); } |
167 | }; |
168 | |
169 | template <typename TimeSource> |
170 | class CompositeCounterRepresentation : public Representation<TimeSource> { |
171 | protected: |
172 | CompositeCounterRepresentation(const CompositeCounterRepresentation& end, const CompositeCounterRepresentation& start) : |
173 | Representation<TimeSource>(end, start) {} |
174 | explicit CompositeCounterRepresentation(jlong value) : Representation<TimeSource>() { |
175 | this->_rep.val1 = value; |
176 | this->_rep.val2 = value; |
177 | } |
178 | public: |
179 | CompositeCounterRepresentation() : Representation<TimeSource>() {} |
180 | ElapsedCounterSource::Type value() const { return this->_rep.val1; } |
181 | FastUnorderedElapsedCounterSource::Type ft_value() const { return this->_rep.val2; } |
182 | }; |
183 | |
184 | template <template <typename> class, typename> |
185 | class TimeInstant; |
186 | |
187 | template <template <typename> class Rep, typename TimeSource> |
188 | class TimeInterval : public Rep<TimeSource> { |
189 | template <template <typename> class, typename> |
190 | friend class TimeInstant; |
191 | TimeInterval(const TimeInstant<Rep, TimeSource>& end, const TimeInstant<Rep, TimeSource>& start) : Rep<TimeSource>(end, start) {} |
192 | public: |
193 | TimeInterval() : Rep<TimeSource>() {} |
194 | TimeInterval<Rep, TimeSource> operator+(const TimeInterval<Rep, TimeSource>& rhs) const { |
195 | TimeInterval<Rep, TimeSource> temp(*this); |
196 | temp += rhs; |
197 | return temp; |
198 | } |
199 | TimeInterval<Rep, TimeSource> operator-(const TimeInterval<Rep, TimeSource>& rhs) const { |
200 | TimeInterval<Rep, TimeSource> temp(*this); |
201 | temp -= rhs; |
202 | return temp; |
203 | } |
204 | }; |
205 | |
206 | template <template <typename> class Rep, typename TimeSource> |
207 | class TimeInstant : public Rep<TimeSource> { |
208 | public: |
209 | TimeInstant() : Rep<TimeSource>() {} |
210 | TimeInstant<Rep, TimeSource>& operator+=(const TimeInterval<Rep, TimeSource>& rhs) { |
211 | Rep<TimeSource>::operator+=(rhs); |
212 | return *this; |
213 | } |
214 | TimeInstant<Rep, TimeSource>& operator-=(const TimeInterval<Rep, TimeSource>& rhs) { |
215 | Rep<TimeSource>::operator-=(rhs); |
216 | return *this; |
217 | } |
218 | TimeInterval<Rep, TimeSource> operator+(const TimeInstant<Rep, TimeSource>& end) const { |
219 | return TimeInterval<Rep, TimeSource>(end, *this); |
220 | } |
221 | TimeInterval<Rep, TimeSource> operator-(const TimeInstant<Rep, TimeSource>& start) const { |
222 | return TimeInterval<Rep, TimeSource>(*this, start); |
223 | } |
224 | void stamp() { |
225 | this->_rep = TimeSource::now(); |
226 | } |
227 | static TimeInstant<Rep, TimeSource> now() { |
228 | TimeInstant<Rep, TimeSource> temp; |
229 | temp.stamp(); |
230 | return temp; |
231 | } |
232 | private: |
233 | TimeInstant(jlong ticks) : Rep<TimeSource>(ticks) {} |
234 | friend class GranularTimer; |
235 | friend class ObjectSample; |
236 | // GC unit tests |
237 | friend class TimePartitionPhasesIteratorTest; |
238 | friend class GCTimerTest; |
239 | }; |
240 | |
241 | #if INCLUDE_JFR |
242 | typedef TimeInstant<CompositeCounterRepresentation, CompositeElapsedCounterSource> Ticks; |
243 | typedef TimeInterval<CompositeCounterRepresentation, CompositeElapsedCounterSource> Tickspan; |
244 | #else |
245 | typedef TimeInstant<CounterRepresentation, ElapsedCounterSource> Ticks; |
246 | typedef TimeInterval<CounterRepresentation, ElapsedCounterSource> Tickspan; |
247 | #endif |
248 | |
249 | #endif // SHARE_UTILITIES_TICKS_HPP |
250 | |