src/hotspot/share/utilities/ticks.cpp
changeset 50113 caf115bb98ad
parent 47216 71c04702a3d5
child 50174 78d9ffb8146f
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
     1 /*
     1 /*
     2  * Copyright (c) 2013, 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.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "runtime/os.hpp"
    26 #include "runtime/os.hpp"
    27 #include "utilities/ticks.inline.hpp"
    27 #include "utilities/ticks.hpp"
    28 
    28 
    29 #ifdef ASSERT
    29 #ifdef X86
    30  const jlong Ticks::invalid_time_stamp = -2; // 0xFFFF FFFF`FFFF FFFE
    30 #include "rdtsc_x86.hpp"
    31 #endif
    31 #endif
    32 
    32 
    33 void Ticks::stamp() {
    33 #include OS_CPU_HEADER(os)
    34   _stamp_ticks = os::elapsed_counter();
    34 
       
    35 template <typename TimeSource, const int unit>
       
    36 inline double conversion(typename TimeSource::Type& value) {
       
    37   return (double)value * ((double)unit / (double)TimeSource::frequency());
    35 }
    38 }
    36 
    39 
    37 const Ticks Ticks::now() {
    40 uint64_t ElapsedCounterSource::frequency() {
    38   Ticks t;
    41   static const uint64_t freq = (uint64_t)os::elapsed_frequency();
    39   t.stamp();
    42   return freq;
    40   return t;
       
    41 }
    43 }
    42 
    44 
    43 Tickspan::Tickspan(const Ticks& end, const Ticks& start) {
    45 ElapsedCounterSource::Type ElapsedCounterSource::now() {
    44   assert(end.value() != Ticks::invalid_time_stamp, "end is unstamped!");
    46   return os::elapsed_counter();
    45   assert(start.value() != Ticks::invalid_time_stamp, "start is unstamped!");
       
    46 
       
    47   assert(end >= start, "negative time!");
       
    48 
       
    49   _span_ticks = end.value() - start.value();
       
    50 }
    47 }
    51 
    48 
    52 template <typename ReturnType>
    49 double ElapsedCounterSource::seconds(Type value) {
    53 static ReturnType time_conversion(const Tickspan& span, TicksToTimeHelper::Unit unit) {
    50   return conversion<ElapsedCounterSource, 1>(value);
    54   assert(TicksToTimeHelper::SECONDS == unit ||
       
    55          TicksToTimeHelper::MILLISECONDS == unit, "invalid unit!");
       
    56 
       
    57   ReturnType frequency_per_unit = (ReturnType)os::elapsed_frequency() / (ReturnType)unit;
       
    58 
       
    59   return (ReturnType) ((ReturnType)span.value() / frequency_per_unit);
       
    60 }
    51 }
    61 
    52 
    62 double TicksToTimeHelper::seconds(const Tickspan& span) {
    53 uint64_t ElapsedCounterSource::milliseconds(Type value) {
    63   return time_conversion<double>(span, SECONDS);
    54   return (uint64_t)conversion<ElapsedCounterSource, MILLIUNITS>(value);
    64 }
    55 }
    65 
    56 
    66 jlong TicksToTimeHelper::milliseconds(const Tickspan& span) {
    57 uint64_t ElapsedCounterSource::microseconds(Type value) {
    67   return time_conversion<jlong>(span, MILLISECONDS);
    58   return (uint64_t)conversion<ElapsedCounterSource, MICROUNITS>(value);
    68 }
    59 }
       
    60 
       
    61 uint64_t ElapsedCounterSource::nanoseconds(Type value) {
       
    62   return (uint64_t)conversion<ElapsedCounterSource, NANOUNITS>(value);
       
    63 }
       
    64 
       
    65 uint64_t FastUnorderedElapsedCounterSource::frequency() {
       
    66 #ifdef X86
       
    67   static bool valid_rdtsc = Rdtsc::initialize();
       
    68   if (valid_rdtsc) {
       
    69     static const uint64_t freq = (uint64_t)Rdtsc::frequency();
       
    70     return freq;
       
    71   }
       
    72 #endif
       
    73   static const uint64_t freq = (uint64_t)os::elapsed_frequency();
       
    74   return freq;
       
    75 }
       
    76 
       
    77 FastUnorderedElapsedCounterSource::Type FastUnorderedElapsedCounterSource::now() {
       
    78 #ifdef X86
       
    79   static bool valid_rdtsc = Rdtsc::initialize();
       
    80   if (valid_rdtsc) {
       
    81     return Rdtsc::elapsed_counter();
       
    82   }
       
    83 #endif
       
    84   return os::elapsed_counter();
       
    85 }
       
    86 
       
    87 double FastUnorderedElapsedCounterSource::seconds(Type value) {
       
    88   return conversion<FastUnorderedElapsedCounterSource, 1>(value);
       
    89 }
       
    90 
       
    91 uint64_t FastUnorderedElapsedCounterSource::milliseconds(Type value) {
       
    92   return (uint64_t)conversion<FastUnorderedElapsedCounterSource, MILLIUNITS>(value);
       
    93 }
       
    94 
       
    95 uint64_t FastUnorderedElapsedCounterSource::microseconds(Type value) {
       
    96   return (uint64_t)conversion<FastUnorderedElapsedCounterSource, MICROUNITS>(value);
       
    97 }
       
    98 
       
    99 uint64_t FastUnorderedElapsedCounterSource::nanoseconds(Type value) {
       
   100   return (uint64_t)conversion<FastUnorderedElapsedCounterSource, NANOUNITS>(value);
       
   101 }
       
   102 
       
   103 uint64_t CompositeElapsedCounterSource::frequency() {
       
   104   return ElapsedCounterSource::frequency();
       
   105 }
       
   106 
       
   107 CompositeElapsedCounterSource::Type CompositeElapsedCounterSource::now() {
       
   108   CompositeTime ct;
       
   109   ct.val1 = ElapsedCounterSource::now();
       
   110 #ifdef X86
       
   111   static bool initialized = false;
       
   112   static bool valid_rdtsc = false;
       
   113   if (!initialized) {
       
   114     valid_rdtsc = Rdtsc::initialize();
       
   115     initialized = true;
       
   116   }
       
   117   if (valid_rdtsc) {
       
   118     ct.val2 = Rdtsc::elapsed_counter();
       
   119   }
       
   120 #endif
       
   121   return ct;
       
   122 }
       
   123 
       
   124 double CompositeElapsedCounterSource::seconds(Type value) {
       
   125   return conversion<ElapsedCounterSource, 1>(value.val1);
       
   126 }
       
   127 
       
   128 uint64_t CompositeElapsedCounterSource::milliseconds(Type value) {
       
   129   return (uint64_t)conversion<ElapsedCounterSource, MILLIUNITS>(value.val1);
       
   130 }
       
   131 
       
   132 uint64_t CompositeElapsedCounterSource::microseconds(Type value) {
       
   133   return (uint64_t)conversion<ElapsedCounterSource, MICROUNITS>(value.val1);
       
   134 }
       
   135 
       
   136 uint64_t CompositeElapsedCounterSource::nanoseconds(Type value) {
       
   137   return (uint64_t)conversion<ElapsedCounterSource, NANOUNITS>(value.val1);
       
   138 }