comparison graal/com.oracle.max.base/src/com/sun/max/profile/Metrics.java @ 3733:e233f5660da4

Added Java files from Maxine project.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 19:59:18 +0100
parents
children bc8527f3071c
comparison
equal deleted inserted replaced
3732:3e2e8b8abdaf 3733:e233f5660da4
1 /*
2 * Copyright (c) 2007, 2011, 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 package com.sun.max.profile;
24
25 import java.io.*;
26 import java.util.*;
27 import java.util.Arrays;
28
29 import com.sun.max.lang.*;
30 import com.sun.max.program.*;
31
32 /**
33 * The {@code Metrics} class implements metrics gathering for quick and dirty
34 * reporting of various events in a program.
35 */
36 public final class Metrics {
37
38 public static boolean DISABLED;
39
40 private Metrics() {
41 // do nothing.
42 }
43
44 private static boolean enabled;
45
46 public interface Metric {
47 void reset();
48 void report(String name, PrintStream stream);
49 }
50
51 /**
52 * This class implements a simple counter that can be both incremented and accumulated.
53 *
54 */
55 public static class Counter implements Metric {
56 protected int count;
57 protected long accumulation;
58
59 public synchronized void increment() {
60 count++;
61 }
62
63 public synchronized void accumulate(long value) {
64 count++;
65 accumulation += value;
66 }
67
68 public synchronized int getCount() {
69 return count;
70 }
71
72 public synchronized long getAccumulation() {
73 return accumulation;
74 }
75
76 public synchronized void reset() {
77 count = 0;
78 accumulation = 0;
79 }
80
81 public synchronized void report(String name, PrintStream stream) {
82 if (accumulation > 0) {
83 final double average = accumulation / (double) count;
84 Metrics.report(stream, name, "total", "--", String.valueOf(accumulation), "accumulated");
85 Metrics.report(stream, name, "average", "--", String.valueOf(average), "accumulated (" + count + " counted)");
86 } else {
87 Metrics.report(stream, name, "total", "--", String.valueOf(count), "counted");
88 }
89 }
90 }
91
92 public static class Rate implements Metric {
93
94 protected final Counter counter;
95 protected final Clock clock;
96 protected long firstTicks;
97 protected long lastAccumulation;
98 protected long lastTicks;
99
100 public Rate(Counter counter, Clock clock) {
101 this.counter = counter;
102 this.clock = clock;
103 firstTicks = clock.getTicks();
104 lastTicks = firstTicks;
105 }
106
107 public double getRate() {
108 return (counter.accumulation - lastAccumulation) / (double) (clock.getTicks() - lastTicks);
109 }
110
111 public double getAverageRate() {
112 return (counter.accumulation) / (double) (clock.getTicks() - firstTicks);
113 }
114
115 public void reset() {
116 firstTicks = clock.getTicks();
117 lastTicks = firstTicks;
118 lastAccumulation = 0;
119 }
120
121 public void resetRate() {
122 lastAccumulation = counter.accumulation;
123 lastTicks = clock.getTicks();
124 }
125
126 public void report(String name, PrintStream stream) {
127 double inst = getRate();
128 double avg = getAverageRate();
129 if (clock.getHZ() == 0) {
130 Metrics.report(stream, name, "inst.", "--", String.valueOf(inst), "/ tick");
131 Metrics.report(stream, name, "average", "--", String.valueOf(avg), "/ tick");
132 } else {
133 inst = inst / clock.getHZ();
134 avg = avg / clock.getHZ();
135 Metrics.report(stream, name, "inst.", "--", String.valueOf(inst), "/ second");
136 Metrics.report(stream, name, "average", "--", String.valueOf(avg), "/ second");
137 }
138 }
139 }
140
141 /**
142 * This class represents a distribution of values that have been recorded. Various
143 * implementations implement different approximations with different time and space
144 * tradeoffs.
145 *
146 */
147 public static class Distribution<T> implements Metric {
148
149 static class Counted implements Comparable<Counted> {
150 final int total;
151 final Object value;
152
153 public Counted(Object value, int total) {
154 this.total = total;
155 this.value = value;
156 }
157
158 public int compareTo(Counted o) {
159 if (o.total < total) {
160 return -1;
161 } else if (o.total > total) {
162 return 1;
163 }
164 return 0;
165 }
166
167 }
168
169 protected int total;
170
171 public int getTotal() {
172 return total;
173 }
174
175 public int getCount(T value) {
176 return -1;
177 }
178
179 public void reset() {
180 total = 0;
181 }
182
183 public Map<T, Integer> asMap() {
184 return Collections.emptyMap();
185 }
186
187 public void report(String name, PrintStream stream) {
188 stream.println(name + ": ");
189 final Map<T, Integer> asMap = asMap();
190 final Counted[] counts = new Counted[asMap.size()];
191 int i = 0;
192 for (Map.Entry<T, Integer> entry : asMap.entrySet()) {
193 counts[i++] = new Counted(entry.getKey(), entry.getValue());
194 }
195 Arrays.sort(counts);
196 for (Counted counted : counts) {
197 stream.printf(" %-10d : %s\n", counted.total, counted.value);
198 }
199 }
200 }
201
202 /**
203 * This method increments the count of a particular named metric, creating it if necessary.
204 * @param name the name of the metric to increment
205 */
206 public static void increment(String name) {
207 GlobalMetrics.getCounter(name).increment();
208 }
209
210 /**
211 * This method increases the accumulation of a particular named metric by the given value.
212 * Each {@code accumulate()} call counts as a single {@code increment()} call as well.
213 * @param name the name of the metric to accumulate
214 * @param value the value to add to the current accumulation
215 */
216 public static void accumulate(String name, int value) {
217 GlobalMetrics.getCounter(name).accumulate(value);
218 }
219
220 public static void trace(int level) {
221 if (Trace.hasLevel(level)) {
222 GlobalMetrics.report(Trace.stream());
223 }
224 }
225
226 public static boolean enabled() {
227 return enabled;
228 }
229
230 static int longestMetricName = 16;
231
232 public static void report(PrintStream out, String metricName, String runName, String benchName, String value, String units) {
233 out.print("@metric ");
234 out.print(Strings.padLengthWithSpaces(metricName, longestMetricName + 1));
235 out.print(" ");
236 out.print(Strings.padLengthWithSpaces(runName, 9));
237 out.print(" ");
238 out.print(Strings.padLengthWithSpaces(benchName, 18));
239 out.print(" ");
240 out.print(Strings.padLengthWithSpaces(20, value));
241 out.print(" ");
242 out.print(units);
243 out.println("");
244 }
245
246 public static void enable(boolean enable) {
247 enabled = enable;
248 }
249 }