/* * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_VM_UTILITIES_TICKS_HPP #define SHARE_VM_UTILITIES_TICKS_HPP #include "jni.h" #include "memory/allocation.hpp" #include "utilities/macros.hpp" // Time sources class ElapsedCounterSource { public: typedef jlong Type; static uint64_t frequency(); static Type now(); static double seconds(Type value); static uint64_t milliseconds(Type value); static uint64_t microseconds(Type value); static uint64_t nanoseconds(Type value); }; // Not guaranteed to be synchronized across hardware threads and // therefore software threads, and can be updated asynchronously // by software. now() can jump backwards as well as jump forward // when threads query different cores/sockets. // Very much not recommended for general use. Caveat emptor. class FastUnorderedElapsedCounterSource { public: typedef jlong Type; static uint64_t frequency(); static Type now(); static double seconds(Type value); static uint64_t milliseconds(Type value); static uint64_t microseconds(Type value); static uint64_t nanoseconds(Type value); }; template class PairRep { public: T1 val1; T2 val2; PairRep() : val1((T1)0), val2((T2)0) {} void operator+=(const PairRep& rhs) { val1 += rhs.val1; val2 += rhs.val2; } void operator-=(const PairRep& rhs) { val1 -= rhs.val1; val2 -= rhs.val2; } bool operator==(const PairRep& rhs) const { return val1 == rhs.val1; } bool operator!=(const PairRep& rhs) const { return !operator==(rhs); } bool operator<(const PairRep& rhs) const { return val1 < rhs.val1; } bool operator>(const PairRep& rhs) const { return val1 > rhs.val1; } }; template PairRep operator-(const PairRep& lhs, const PairRep& rhs) { PairRep temp(lhs); temp -= rhs; return temp; } typedef PairRep CompositeTime; class CompositeElapsedCounterSource { public: typedef CompositeTime Type; static uint64_t frequency(); static Type now(); static double seconds(Type value); static uint64_t milliseconds(Type value); static uint64_t microseconds(Type value); static uint64_t nanoseconds(Type value); }; template class Representation { public: typedef typename TimeSource::Type Type; protected: Type _rep; Representation(const Representation& end, const Representation& start) : _rep(end._rep - start._rep) {} Representation() : _rep() {} public: void operator+=(const Representation& rhs) { _rep += rhs._rep; } void operator-=(const Representation& rhs) { _rep -= rhs._rep; } bool operator==(const Representation& rhs) const { return _rep == rhs._rep; } bool operator!=(const Representation& rhs) const { return !operator==(rhs); } bool operator<(const Representation& rhs) const { return _rep < rhs._rep; } bool operator>(const Representation& rhs) const { return _rep > rhs._rep; } bool operator<=(const Representation& rhs) const { return !operator>(rhs); } bool operator>=(const Representation& rhs) const { return !operator<(rhs); } double seconds() const { return TimeSource::seconds(_rep); } uint64_t milliseconds() const { return TimeSource::milliseconds(_rep); } uint64_t microseconds() const { return TimeSource::microseconds(_rep); } uint64_t nanoseconds() const { return TimeSource::nanoseconds(_rep); } }; template class CounterRepresentation : public Representation { protected: CounterRepresentation(const CounterRepresentation& end, const CounterRepresentation& start) : Representation(end, start) {} explicit CounterRepresentation(jlong value) : Representation() { this->_rep = value; } public: CounterRepresentation() : Representation() {} typename TimeSource::Type value() const { return this->_rep; } operator typename TimeSource::Type() { return value(); } }; template class CompositeCounterRepresentation : public Representation { protected: CompositeCounterRepresentation(const CompositeCounterRepresentation& end, const CompositeCounterRepresentation& start) : Representation(end, start) {} explicit CompositeCounterRepresentation(jlong value) : Representation() { this->_rep.val1 = value; this->_rep.val2 = value; } public: CompositeCounterRepresentation() : Representation() {} ElapsedCounterSource::Type value() const { return this->_rep.val1; } FastUnorderedElapsedCounterSource::Type ft_value() const { return this->_rep.val2; } }; template