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#include OS_CPU_HEADER(os)
34
35template <typename TimeSource, const int unit>
36inline double conversion(typename TimeSource::Type& value) {
37 return (double)value * ((double)unit / (double)TimeSource::frequency());
38}
39
40uint64_t ElapsedCounterSource::frequency() {
41 static const uint64_t freq = (uint64_t)os::elapsed_frequency();
42 return freq;
43}
44
45ElapsedCounterSource::Type ElapsedCounterSource::now() {
46 return os::elapsed_counter();
47}
48
49double ElapsedCounterSource::seconds(Type value) {
50 return conversion<ElapsedCounterSource, 1>(value);
51}
52
53uint64_t ElapsedCounterSource::milliseconds(Type value) {
54 return (uint64_t)conversion<ElapsedCounterSource, MILLIUNITS>(value);
55}
56
57uint64_t ElapsedCounterSource::microseconds(Type value) {
58 return (uint64_t)conversion<ElapsedCounterSource, MICROUNITS>(value);
59}
60
61uint64_t ElapsedCounterSource::nanoseconds(Type value) {
62 return (uint64_t)conversion<ElapsedCounterSource, NANOUNITS>(value);
63}
64
65uint64_t FastUnorderedElapsedCounterSource::frequency() {
66#if defined(X86) && !defined(ZERO)
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
77FastUnorderedElapsedCounterSource::Type FastUnorderedElapsedCounterSource::now() {
78#if defined(X86) && !defined(ZERO)
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
87double FastUnorderedElapsedCounterSource::seconds(Type value) {
88 return conversion<FastUnorderedElapsedCounterSource, 1>(value);
89}
90
91uint64_t FastUnorderedElapsedCounterSource::milliseconds(Type value) {
92 return (uint64_t)conversion<FastUnorderedElapsedCounterSource, MILLIUNITS>(value);
93}
94
95uint64_t FastUnorderedElapsedCounterSource::microseconds(Type value) {
96 return (uint64_t)conversion<FastUnorderedElapsedCounterSource, MICROUNITS>(value);
97}
98
99uint64_t FastUnorderedElapsedCounterSource::nanoseconds(Type value) {
100 return (uint64_t)conversion<FastUnorderedElapsedCounterSource, NANOUNITS>(value);
101}
102
103uint64_t CompositeElapsedCounterSource::frequency() {
104 return ElapsedCounterSource::frequency();
105}
106
107CompositeElapsedCounterSource::Type CompositeElapsedCounterSource::now() {
108 CompositeTime ct;
109 ct.val1 = ElapsedCounterSource::now();
110#if defined(X86) && !defined(ZERO)
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
124double CompositeElapsedCounterSource::seconds(Type value) {
125 return conversion<ElapsedCounterSource, 1>(value.val1);
126}
127
128uint64_t CompositeElapsedCounterSource::milliseconds(Type value) {
129 return (uint64_t)conversion<ElapsedCounterSource, MILLIUNITS>(value.val1);
130}
131
132uint64_t CompositeElapsedCounterSource::microseconds(Type value) {
133 return (uint64_t)conversion<ElapsedCounterSource, MICROUNITS>(value.val1);
134}
135
136uint64_t CompositeElapsedCounterSource::nanoseconds(Type value) {
137 return (uint64_t)conversion<ElapsedCounterSource, NANOUNITS>(value.val1);
138}
139