author | egahlin |
Tue, 15 May 2018 20:24:34 +0200 | |
changeset 50113 | caf115bb98ad |
parent 49911 | 358be4680d12 |
child 52321 | 52d3bb5ba2f7 |
permissions | -rw-r--r-- |
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
1 |
/* |
50113 | 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. |
|
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 |
*/ |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
24 |
|
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
25 |
#ifndef SHARE_VM_UTILITIES_TICKS_HPP |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
26 |
#define SHARE_VM_UTILITIES_TICKS_HPP |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
27 |
|
50113 | 28 |
#include "jni.h" |
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
29 |
#include "memory/allocation.hpp" |
50113 | 30 |
#include "utilities/macros.hpp" |
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
31 |
|
50113 | 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 |
}; |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
43 |
|
50113 | 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 |
}; |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
59 |
|
50113 | 60 |
template <typename T1, typename T2> |
61 |
class PairRep { |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
62 |
public: |
50113 | 63 |
T1 val1; |
64 |
T2 val2; |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
65 |
|
50113 | 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; |
|
49911
358be4680d12
6672778: G1 should trim task queues more aggressively during evacuation pauses
tschatzl
parents:
49364
diff
changeset
|
74 |
} |
50113 | 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 |
}; |
|
49911
358be4680d12
6672778: G1 should trim task queues more aggressively during evacuation pauses
tschatzl
parents:
49364
diff
changeset
|
88 |
|
50113 | 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; |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
97 |
|
50113 | 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); |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
107 |
}; |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
108 |
|
50113 | 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() {} |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
117 |
public: |
50113 | 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); |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
153 |
} |
50113 | 154 |
}; |
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
155 |
|
50113 | 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; |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
177 |
} |
50113 | 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 |
}; |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
183 |
|
50113 | 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); |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
212 |
return *this; |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
213 |
} |
50113 | 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); |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
223 |
} |
50113 | 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 VM tests |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
237 |
friend class TimePartitionPhasesIteratorTest; |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
238 |
friend class GCTimerTest; |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
239 |
}; |
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
240 |
|
50113 | 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 |
|
21767
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
248 |
|
41eaa9a17059
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
diff
changeset
|
249 |
#endif // SHARE_VM_UTILITIES_TICKS_HPP |