1 /* |
1 /* |
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
8 * |
8 * |
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
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 |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
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 |
12 * version 2 for more details (a copy is included in the LICENSE file that |
13 * accompanied this code). |
13 * accompanied this code). |
14 * |
14 * |
15 * You should have received a copy of the GNU General Public License version |
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, |
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. |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 * |
18 * |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
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 |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #ifndef SHARE_VM_UTILITIES_TICKS_HPP |
25 #ifndef SHARE_VM_UTILITIES_TICKS_HPP |
26 #define SHARE_VM_UTILITIES_TICKS_HPP |
26 #define SHARE_VM_UTILITIES_TICKS_HPP |
27 |
27 |
|
28 #include "jni.h" |
28 #include "memory/allocation.hpp" |
29 #include "memory/allocation.hpp" |
29 #include "utilities/globalDefinitions.hpp" |
30 #include "utilities/macros.hpp" |
30 |
31 |
31 class Ticks; |
32 // Time sources |
32 |
33 class ElapsedCounterSource { |
33 class Tickspan { |
34 public: |
34 friend class Ticks; |
35 typedef jlong Type; |
35 friend Tickspan operator-(const Ticks& end, const Ticks& start); |
36 static uint64_t frequency(); |
36 |
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 } |
37 private: |
232 private: |
38 jlong _span_ticks; |
233 TimeInstant(jlong ticks) : Rep<TimeSource>(ticks) {} |
39 |
234 friend class GranularTimer; |
40 Tickspan(const Ticks& end, const Ticks& start); |
235 friend class ObjectSample; |
41 |
236 // GC VM tests |
42 public: |
|
43 Tickspan() : _span_ticks(0) {} |
|
44 |
|
45 Tickspan& operator+=(const Tickspan& rhs) { |
|
46 _span_ticks += rhs._span_ticks; |
|
47 return *this; |
|
48 } |
|
49 |
|
50 Tickspan& operator-=(const Tickspan& rhs) { |
|
51 _span_ticks -= rhs._span_ticks; |
|
52 return *this; |
|
53 } |
|
54 |
|
55 jlong value() const { |
|
56 return _span_ticks; |
|
57 } |
|
58 |
|
59 }; |
|
60 |
|
61 class Ticks { |
|
62 private: |
|
63 jlong _stamp_ticks; |
|
64 |
|
65 public: |
|
66 Ticks() : _stamp_ticks(0) { |
|
67 assert((_stamp_ticks = invalid_time_stamp) == invalid_time_stamp, |
|
68 "initial unstamped time value assignment"); |
|
69 } |
|
70 |
|
71 Ticks& operator+=(const Tickspan& span) { |
|
72 _stamp_ticks += span.value(); |
|
73 return *this; |
|
74 } |
|
75 |
|
76 Ticks& operator-=(const Tickspan& span) { |
|
77 _stamp_ticks -= span.value(); |
|
78 return *this; |
|
79 } |
|
80 |
|
81 void stamp(); |
|
82 |
|
83 jlong value() const { |
|
84 return _stamp_ticks; |
|
85 } |
|
86 |
|
87 static const Ticks now(); |
|
88 |
|
89 #ifdef ASSERT |
|
90 static const jlong invalid_time_stamp; |
|
91 #endif |
|
92 |
|
93 #ifndef PRODUCT |
|
94 // only for internal use by GC VM tests |
|
95 friend class TimePartitionPhasesIteratorTest; |
237 friend class TimePartitionPhasesIteratorTest; |
96 friend class GCTimerTest; |
238 friend class GCTimerTest; |
97 |
239 }; |
98 private: |
240 |
99 // implicit type conversion |
241 #if INCLUDE_JFR |
100 Ticks(int ticks) : _stamp_ticks(ticks) {} |
242 typedef TimeInstant<CompositeCounterRepresentation, CompositeElapsedCounterSource> Ticks; |
101 |
243 typedef TimeInterval<CompositeCounterRepresentation, CompositeElapsedCounterSource> Tickspan; |
102 #endif // !PRODUCT |
244 #else |
103 |
245 typedef TimeInstant<CounterRepresentation, ElapsedCounterSource> Ticks; |
104 }; |
246 typedef TimeInterval<CounterRepresentation, ElapsedCounterSource> Tickspan; |
105 |
247 #endif |
106 class TicksToTimeHelper : public AllStatic { |
|
107 public: |
|
108 enum Unit { |
|
109 SECONDS = 1, |
|
110 MILLISECONDS = 1000 |
|
111 }; |
|
112 static double seconds(const Tickspan& span); |
|
113 static jlong milliseconds(const Tickspan& span); |
|
114 }; |
|
115 |
248 |
116 #endif // SHARE_VM_UTILITIES_TICKS_HPP |
249 #endif // SHARE_VM_UTILITIES_TICKS_HPP |