1 /* 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 */ 24 25 #ifndef SHARE_VM_UTILITIES_TICKS_HPP 26 #define SHARE_VM_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 VM 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_VM_UTILITIES_TICKS_HPP