src/hotspot/share/utilities/ticks.hpp
changeset 50113 caf115bb98ad
parent 49911 358be4680d12
child 52321 52d3bb5ba2f7
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
     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