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 #include "precompiled.hpp" 26 #include "runtime/os.hpp" 27 #include "utilities/ticks.hpp" 28 29 #if defined(X86) && !defined(ZERO) 30 #include "rdtsc_x86.hpp" 31 #endif 32 33 template <typename TimeSource, const int unit> 34 inline double conversion(typename TimeSource::Type& value) { 35 return (double)value * ((double)unit / (double)TimeSource::frequency()); 36 } 37 38 uint64_t ElapsedCounterSource::frequency() { 39 static const uint64_t freq = (uint64_t)os::elapsed_frequency(); 40 return freq; 41 } 42 43 ElapsedCounterSource::Type ElapsedCounterSource::now() { 44 return os::elapsed_counter(); 45 } 46 47 double ElapsedCounterSource::seconds(Type value) { 48 return conversion<ElapsedCounterSource, 1>(value); 49 } 50 51 uint64_t ElapsedCounterSource::milliseconds(Type value) { 52 return (uint64_t)conversion<ElapsedCounterSource, MILLIUNITS>(value); 53 } 54 55 uint64_t ElapsedCounterSource::microseconds(Type value) { 56 return (uint64_t)conversion<ElapsedCounterSource, MICROUNITS>(value); 57 } 58 59 uint64_t ElapsedCounterSource::nanoseconds(Type value) { 60 return (uint64_t)conversion<ElapsedCounterSource, NANOUNITS>(value); 61 } 62 63 uint64_t FastUnorderedElapsedCounterSource::frequency() { 64 #if defined(X86) && !defined(ZERO) 65 static bool valid_rdtsc = Rdtsc::initialize(); 66 if (valid_rdtsc) { 67 static const uint64_t freq = (uint64_t)Rdtsc::frequency(); 68 return freq; 69 } 70 #endif 71 static const uint64_t freq = (uint64_t)os::elapsed_frequency(); 72 return freq; 73 } 74 75 FastUnorderedElapsedCounterSource::Type FastUnorderedElapsedCounterSource::now() { 76 #if defined(X86) && !defined(ZERO) 77 static bool valid_rdtsc = Rdtsc::initialize(); 78 if (valid_rdtsc) { 79 return Rdtsc::elapsed_counter(); 80 } 81 #endif 82 return os::elapsed_counter(); 83 } 84 85 double FastUnorderedElapsedCounterSource::seconds(Type value) { 86 return conversion<FastUnorderedElapsedCounterSource, 1>(value); 87 } 88 89 uint64_t FastUnorderedElapsedCounterSource::milliseconds(Type value) { 90 return (uint64_t)conversion<FastUnorderedElapsedCounterSource, MILLIUNITS>(value); 91 } 92 93 uint64_t FastUnorderedElapsedCounterSource::microseconds(Type value) { 94 return (uint64_t)conversion<FastUnorderedElapsedCounterSource, MICROUNITS>(value); 95 } 96 97 uint64_t FastUnorderedElapsedCounterSource::nanoseconds(Type value) { 98 return (uint64_t)conversion<FastUnorderedElapsedCounterSource, NANOUNITS>(value); 99 } 100 101 uint64_t CompositeElapsedCounterSource::frequency() { 102 return ElapsedCounterSource::frequency(); 103 } 104 105 CompositeElapsedCounterSource::Type CompositeElapsedCounterSource::now() { 106 CompositeTime ct; 107 ct.val1 = ElapsedCounterSource::now(); 108 #if defined(X86) && !defined(ZERO) 109 static bool initialized = false; 110 static bool valid_rdtsc = false; 111 if (!initialized) { 112 valid_rdtsc = Rdtsc::initialize(); 113 initialized = true; 114 } 115 if (valid_rdtsc) { 116 ct.val2 = Rdtsc::elapsed_counter(); 117 } 118 #endif 119 return ct; 120 } 121 122 double CompositeElapsedCounterSource::seconds(Type value) { 123 return conversion<ElapsedCounterSource, 1>(value.val1); 124 } 125 126 uint64_t CompositeElapsedCounterSource::milliseconds(Type value) { 127 return (uint64_t)conversion<ElapsedCounterSource, MILLIUNITS>(value.val1); 128 } 129 130 uint64_t CompositeElapsedCounterSource::microseconds(Type value) { 131 return (uint64_t)conversion<ElapsedCounterSource, MICROUNITS>(value.val1); 132 } 133 134 uint64_t CompositeElapsedCounterSource::nanoseconds(Type value) { 135 return (uint64_t)conversion<ElapsedCounterSource, NANOUNITS>(value.val1); 136 }