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 } |