Commit | Line | Data |
---|---|---|
9dbeec54 FC |
1 | /******************************************************************************* |
2 | * Copyright (c) 2010 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Francois Godin (copelnug@gmail.com) - Initial design and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.lttng.ui.views.statistics.model; | |
14 | ||
15 | import java.util.Collection; | |
b12f4544 | 16 | import java.util.HashMap; |
9dbeec54 FC |
17 | import java.util.HashSet; |
18 | import java.util.LinkedList; | |
19 | import java.util.Set; | |
20 | import java.util.Map; | |
21 | ||
b12f4544 | 22 | import org.eclipse.linuxtools.lttng.LttngConstants; |
9dbeec54 | 23 | import org.eclipse.linuxtools.lttng.event.LttngEvent; |
f970b04d | 24 | import org.eclipse.linuxtools.lttng.state.StateStrings.Events; |
9dbeec54 FC |
25 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; |
26 | import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; | |
27 | import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; | |
28 | import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; | |
29 | ||
30 | /** | |
31 | * <h4>Class that process the LTTng kernel events.</h4> | |
32 | */ | |
33 | public class KernelStatisticsData extends StatisticsData { | |
a2e53983 | 34 | /** |
b12f4544 | 35 | * <h4>Header for the CPU categories.</h4> |
a2e53983 | 36 | */ |
b12f4544 FC |
37 | public static final String HEADER_CPUS = Messages.KernelStatisticsData_CPUs; |
38 | public static final int HEADER_CPUS_INT = 256 | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
39 | /** |
40 | * <h4>Header for the event types categories.</h4> | |
41 | */ | |
b12f4544 FC |
42 | public static final String HEADER_EVENT_TYPES = Messages.KernelStatisticsData_EventTypes; |
43 | public static final int HEADER_EVENT_TYPES_INT = (HEADER_CPUS_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
44 | /** |
45 | * <h4>Header for the function categories.</h4> | |
46 | */ | |
b12f4544 FC |
47 | public static final String HEADER_FUNCTIONS = Messages.KernelStatisticsData_Functions; |
48 | public static final int HEADER_FUNCTIONS_INT = (HEADER_EVENT_TYPES_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
49 | /** |
50 | * <h4>Header for the mode categories.</h4> | |
51 | */ | |
b12f4544 FC |
52 | public static final String HEADER_MODES = Messages.KernelStatisticsData_Modes; |
53 | public static final int HEADER_MODES_INT = (HEADER_FUNCTIONS_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
54 | /** |
55 | * <h4>Header for the processes categories.</h4> | |
56 | */ | |
b12f4544 FC |
57 | public static final String HEADER_PROCESSES = Messages.KernelStatisticsData_Processes; |
58 | public static final int HEADER_PROCESSES_INT = (HEADER_MODES_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
59 | /** |
60 | * <h4>Header for the submode categories.</h4> | |
61 | */ | |
b12f4544 FC |
62 | public static final String HEADER_SUBMODES = Messages.KernelStatisticsData_SubModes; |
63 | public static final int HEADER_SUBMODES_INT = (HEADER_PROCESSES_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
64 | ||
65 | /** | |
66 | * <h4>Class to generate unique IDs for processes.</h4> | |
67 | */ | |
f970b04d | 68 | private ProcessKeyProvider fPidKeys = new ProcessKeyProvider(LttngConstants.STATS_PROCESS_ID); |
b12f4544 FC |
69 | |
70 | /** | |
71 | * <h4>Class to generate unique Ids for event types.</h4> | |
72 | */ | |
73 | private KeyProvider fTypeKeys = new KeyProvider(LttngConstants.STATS_TYPE_ID); | |
74 | /** | |
75 | * <h4>Class to generate unique Ids for subModes.</h4> | |
76 | */ | |
77 | private KeyProvider fSubModeKeys = new KeyProvider(); | |
78 | ||
79 | /** | |
80 | * <h4>Place Holder in path.</h4> | |
81 | */ | |
82 | private static final int PLACE_HOLDER = 0; | |
83 | ||
84 | /** | |
85 | * For performance reason the following algorithm is applied to the paths: | |
86 | * | |
87 | * Each array entry has to be unique to form a unique path. To generate | |
88 | * unique entries a bit mask is used, where the bit mask is applied to the | |
89 | * upper N bits of an integer value. It is assumed, that each value that | |
90 | * will be filled in the place holder below is smaller than 2 ^ (32 - N). | |
91 | */ | |
92 | ||
93 | /** | |
94 | * <h4>Pre-created paths for type statistics, which will be filled for each | |
95 | * relevant event.</h4> | |
96 | */ | |
97 | private final FixedArray[] fTypedPaths = { new FixedArray(PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
98 | new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
99 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
100 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
101 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
102 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
103 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
104 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
105 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
106 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
107 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
108 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
109 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), }; | |
110 | /** | |
111 | * <h4>Pre-created paths for other statistics, which will be filled for each | |
112 | * relevant event.</h4> | |
113 | */ | |
114 | final FixedArray[] fNormalPaths = { new FixedArray(PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
115 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER), | |
116 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER), | |
117 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), | |
118 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
119 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), | |
120 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
121 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
122 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), | |
123 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), }; | |
124 | ||
a2e53983 FC |
125 | /** |
126 | * <h4>Indicate that it's a value.</h4> | |
127 | * <p> | |
128 | * Used when checking the possible child node for a node. | |
129 | * </p> | |
130 | * <p> | |
131 | * It differentiate a category of a value by being appended to a value. | |
132 | * </p> | |
133 | */ | |
b12f4544 FC |
134 | private static final Integer NODE = -1; |
135 | private static final Integer ROOT_NODE_KEY = -2; | |
a2e53983 FC |
136 | |
137 | /** | |
138 | * <h4>Constructor.</h4> | |
139 | * | |
140 | * @param traceName | |
141 | */ | |
142 | public KernelStatisticsData(String traceName) { | |
b12f4544 FC |
143 | super(); |
144 | Map<Integer, Set<Integer>> keys = getKeys(); | |
145 | ||
146 | // //////////// Adding category sets | |
147 | keys.put(HEADER_PROCESSES_INT, new HashSet<Integer>()); | |
148 | keys.put(HEADER_MODES_INT, new HashSet<Integer>()); | |
149 | keys.put(HEADER_CPUS_INT, new HashSet<Integer>(4)); // Over 4 CPUs is | |
150 | // not common | |
151 | keys.put(HEADER_SUBMODES_INT, new HashSet<Integer>()); | |
152 | keys.put(HEADER_EVENT_TYPES_INT, new HashSet<Integer>()); | |
153 | keys.put(HEADER_FUNCTIONS_INT, new HashSet<Integer>(4)); // Seems to be | |
154 | // always one. | |
155 | ||
156 | // /////////// Adding value sets | |
157 | // Under a trace | |
158 | Set<Integer> temp = new HashSet<Integer>(8); | |
159 | temp.add(HEADER_PROCESSES_INT); | |
160 | temp.add(HEADER_MODES_INT); | |
161 | temp.add(HEADER_CPUS_INT); | |
162 | temp.add(HEADER_EVENT_TYPES_INT); | |
163 | keys.put(ROOT_NODE_KEY, temp); | |
164 | // Under a process | |
165 | temp = new HashSet<Integer>(4); | |
166 | temp.add(HEADER_MODES_INT); | |
167 | temp.add(HEADER_CPUS_INT); | |
168 | temp.add(HEADER_EVENT_TYPES_INT); | |
169 | keys.put(HEADER_PROCESSES_INT * NODE, temp); | |
170 | // Under a CPUs : Functions is a special case | |
171 | temp = new HashSet<Integer>(4); | |
172 | temp.add(HEADER_MODES_INT); | |
173 | temp.add(HEADER_EVENT_TYPES_INT); | |
174 | keys.put(HEADER_CPUS_INT * NODE, temp); | |
175 | // Under a functions | |
176 | temp = new HashSet<Integer>(4); | |
177 | temp.add(HEADER_MODES_INT); | |
178 | temp.add(HEADER_EVENT_TYPES_INT); | |
179 | keys.put(HEADER_FUNCTIONS_INT * NODE, temp); | |
180 | // Under a mode | |
181 | temp = new HashSet<Integer>(4); | |
182 | temp.add(HEADER_SUBMODES_INT); | |
183 | temp.add(HEADER_EVENT_TYPES_INT); | |
184 | keys.put(HEADER_MODES_INT * NODE, temp); | |
185 | // Under a submodes | |
186 | temp = new HashSet<Integer>(2); | |
187 | temp.add(HEADER_EVENT_TYPES_INT); | |
188 | keys.put(HEADER_SUBMODES_INT * NODE, temp); | |
189 | // Under an event type | |
190 | temp = new HashSet<Integer>(16); | |
191 | keys.put(HEADER_EVENT_TYPES_INT * NODE, temp); | |
192 | ||
193 | // //////////// CREATE root | |
194 | keys.put(ROOT.get(0), new HashSet<Integer>(2)); // 1 trace at the time | |
195 | StatisticsTreeNode node = getOrCreate(ROOT); | |
196 | node.setName("root"); //$NON-NLS-1$ | |
a2e53983 FC |
197 | } |
198 | ||
199 | /* | |
200 | * (non-Javadoc) | |
201 | * | |
202 | * @see | |
203 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
204 | * #endTraceset(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
205 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
206 | */ | |
207 | @Override | |
208 | public void endTraceset(LttngEvent event, LttngTraceState traceState) { | |
b12f4544 FC |
209 | // TODO Should we uncomment the rest? |
210 | // It include in the cpu time the time between the last event of each | |
211 | // cpu and the time of the last global event. | |
212 | // Because we know that there won't be a change of mode or process | |
213 | // between those time. | |
214 | /* | |
215 | * if(last_ == null) return; | |
216 | * | |
217 | * LttngProcessState process = traceState.getRunning_process().get(0L); | |
218 | * System.out.println(process.getState().getChange_LttTime()); for(long | |
219 | * cpu : traceState.getRunning_process().keySet()) { LttngEventType | |
220 | * newType = new LttngEventType(last_.getType().getTracefileName(), cpu, | |
221 | * last_.getType().getMarkerName(), last_.getType().getLabels()); | |
222 | * last_.setType(newType); increase(last_, traceState, Values.CPU_TIME | | |
223 | * Values.CUMULATIVE_CPU_TIME | Values.ELAPSED_TIME | | |
224 | * Values.STATE_CUMULATIVE_CPU_TIME); // TODO Are all those values | |
225 | * required? } | |
226 | */ | |
a2e53983 FC |
227 | } |
228 | ||
229 | /* | |
230 | * (non-Javadoc) | |
231 | * | |
232 | * @see | |
233 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
234 | * #getChildren | |
235 | * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray) | |
236 | */ | |
237 | @Override | |
b12f4544 FC |
238 | public Collection<StatisticsTreeNode> getChildren(final FixedArray path) { |
239 | LinkedList<StatisticsTreeNode> result = new LinkedList<StatisticsTreeNode>(); | |
240 | ||
241 | if (path.size() % 2 == 0) { // if we are at a Category | |
242 | StatisticsTreeNode current = null; | |
243 | for (int value : getKeys().get(path.get(path.size() - 1))) { | |
244 | current = get(path.append(value)); | |
245 | if (current != null && current.getValue().nbEvents != 0) | |
246 | result.add(current); | |
247 | } | |
248 | } else if (path.size() == 1) { // Special case. | |
249 | if (path.equals(ROOT)) // Asking for the root. | |
250 | for (int value : getKeys().get(ROOT.get(0))) | |
251 | result.add(getOrCreate(new FixedArray(value))); | |
252 | else | |
253 | // Get value under the root | |
254 | for (int value : getKeys().get(ROOT_NODE_KEY)) { | |
255 | StatisticsTreeNode node = getOrCreate(path.append(value)); | |
256 | node.setName(getCategoryFromId(value)); | |
257 | result.add(node); | |
258 | } | |
259 | } else {// If we are at a value | |
260 | for (int value : getKeys().get((path.get(path.size() - 2) * NODE))) { // Search | |
261 | // the | |
262 | // parent | |
263 | // name | |
264 | // + | |
265 | // NODE | |
266 | StatisticsTreeNode node = getOrCreate(path.append(value)); | |
267 | node.setName(getCategoryFromId(value)); | |
268 | result.add(node); | |
269 | } | |
270 | ||
271 | if (path.size() == 5 && path.get(3) == HEADER_CPUS_INT) { // Special | |
272 | // the | |
273 | // Functions | |
274 | // is just | |
275 | // there. | |
276 | // We want | |
277 | // the | |
278 | // fourth | |
279 | // element | |
280 | // but it | |
281 | // start | |
282 | // at 0. | |
283 | // So #3 | |
284 | StatisticsTreeNode node = getOrCreate(path.append(HEADER_FUNCTIONS_INT)); | |
285 | node.setName(getCategoryFromId(HEADER_FUNCTIONS_INT)); | |
286 | result.add(node); | |
287 | } | |
288 | } | |
289 | ||
290 | return result; | |
a2e53983 FC |
291 | } |
292 | ||
293 | /** | |
294 | * <h4>Get the standard paths for an event.</h4> | |
295 | * | |
296 | * @param event | |
297 | * Event to get the path for. | |
298 | * @param traceState | |
299 | * State of the trace for this event. | |
300 | * @return Array of FixedArray representing the paths. | |
301 | */ | |
b12f4544 FC |
302 | private FixedArray[] getNormalPaths(LttngEvent event, LttngTraceState traceState) { |
303 | int trace = (int) traceState.getContext().getIdentifier(); // No need | |
304 | // for the | |
305 | // identifier | |
306 | // (already | |
307 | // applied) | |
308 | Long cpu = event.getCpuId(); | |
309 | int cpus = cpu.intValue() | LttngConstants.STATS_CPU_ID; | |
310 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
f970b04d | 311 | int processName = fPidKeys.getUniqueId(process.getPid().intValue(), process.getCpu().intValue(), process.getCreation_time()); |
b12f4544 FC |
312 | int mode = process.getState().getExec_mode().ordinal() | LttngConstants.STATS_MODE_ID; |
313 | int submode = fSubModeKeys.getUniqueId(process.getState().getExec_submode_id(), process.getState().getExec_submode()); | |
314 | int function = process.getCurrent_function().intValue() | LttngConstants.STATS_FUNCTION_ID; | |
315 | ||
316 | /* | |
317 | * Note that it's faster to re-use the path object, set the relevant | |
318 | * fields and clone the path later when it's time to add to the map | |
319 | */ | |
320 | ||
321 | // FixedArray(trace) | |
322 | fNormalPaths[0].set(0, trace); | |
323 | ||
324 | // FixedArray(trace,HEADER_MODES_INT,mode) | |
325 | fNormalPaths[1].set(0, trace); | |
326 | fNormalPaths[1].set(2, mode); | |
327 | ||
328 | // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
329 | fNormalPaths[2].set(0, trace); | |
330 | fNormalPaths[2].set(2, mode); | |
331 | fNormalPaths[2].set(4, submode); | |
332 | ||
333 | // FixedArray(trace,HEADER_PROCESSES_INT,processName) | |
334 | fNormalPaths[3].set(0, trace); | |
335 | fNormalPaths[3].set(2, processName); | |
336 | ||
337 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus) | |
338 | fNormalPaths[4].set(0, trace); | |
339 | fNormalPaths[4].set(2, processName); | |
340 | fNormalPaths[4].set(4, cpus); | |
341 | ||
342 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function) | |
343 | fNormalPaths[5].set(0, trace); | |
344 | fNormalPaths[5].set(2, processName); | |
345 | fNormalPaths[5].set(4, cpus); | |
346 | fNormalPaths[5].set(6, function); | |
347 | ||
348 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function, | |
349 | // HEADER_MODES_INT, mode) | |
350 | fNormalPaths[6].set(0, trace); | |
351 | fNormalPaths[6].set(2, processName); | |
352 | fNormalPaths[6].set(4, cpus); | |
353 | fNormalPaths[6].set(6, function); | |
354 | fNormalPaths[6].set(8, mode); | |
355 | ||
356 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function, | |
357 | // HEADER_MODES_INT, mode, HEADER_SUBMODES_INT, submode) | |
358 | fNormalPaths[7].set(0, trace); | |
359 | fNormalPaths[7].set(2, processName); | |
360 | fNormalPaths[7].set(4, cpus); | |
361 | fNormalPaths[7].set(6, function); | |
362 | fNormalPaths[7].set(8, mode); | |
363 | fNormalPaths[7].set(10, submode); | |
364 | ||
365 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode) | |
366 | fNormalPaths[8].set(0, trace); | |
367 | fNormalPaths[8].set(2, processName); | |
368 | fNormalPaths[8].set(4, cpus); | |
369 | fNormalPaths[8].set(6, mode); | |
370 | ||
371 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
372 | fNormalPaths[9].set(0, trace); | |
373 | fNormalPaths[9].set(2, processName); | |
374 | fNormalPaths[9].set(4, cpus); | |
375 | fNormalPaths[9].set(6, mode); | |
376 | fNormalPaths[9].set(8, submode); | |
377 | ||
378 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode) | |
379 | fNormalPaths[10].set(0, trace); | |
380 | fNormalPaths[10].set(2, processName); | |
381 | fNormalPaths[10].set(4, mode); | |
382 | ||
383 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
384 | fNormalPaths[11].set(0, trace); | |
385 | fNormalPaths[11].set(2, processName); | |
386 | fNormalPaths[11].set(4, mode); | |
387 | fNormalPaths[11].set(6, submode); | |
388 | ||
389 | // FixedArray(trace,HEADER_CPUS_INT,cpus) | |
390 | fNormalPaths[12].set(0, trace); | |
391 | fNormalPaths[12].set(2, cpus); | |
392 | ||
393 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode) | |
394 | fNormalPaths[13].set(0, trace); | |
395 | fNormalPaths[13].set(2, cpus); | |
396 | fNormalPaths[13].set(4, mode); | |
397 | ||
398 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
399 | fNormalPaths[14].set(0, trace); | |
400 | fNormalPaths[14].set(2, cpus); | |
401 | fNormalPaths[14].set(4, mode); | |
402 | fNormalPaths[14].set(6, submode); | |
403 | ||
404 | return fNormalPaths; | |
405 | ||
a2e53983 FC |
406 | } |
407 | ||
408 | /** | |
409 | * <h4>Get the event types paths.</h4> | |
410 | * | |
411 | * @param event | |
412 | * Event to get the path for. | |
413 | * @param traceState | |
414 | * State of the trace for this event. | |
415 | * @return Array of FixedArray representing the paths. | |
416 | */ | |
b12f4544 FC |
417 | private FixedArray[] getTypePaths(LttngEvent event, LttngTraceState traceState) { |
418 | int trace = (int) traceState.getContext().getIdentifier(); // No need | |
419 | // for the | |
420 | // identifier | |
421 | // (already | |
422 | // applied) | |
423 | Long cpu = event.getCpuId(); | |
424 | int cpus = cpu.intValue() | LttngConstants.STATS_CPU_ID; | |
425 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
f970b04d | 426 | int processName = fPidKeys.getUniqueId(process.getPid().intValue(), process.getCpu().intValue(), process.getCreation_time()); |
b12f4544 FC |
427 | int mode = process.getState().getExec_mode().ordinal() | LttngConstants.STATS_MODE_ID; |
428 | int submode = fSubModeKeys.getUniqueId(process.getState().getExec_submode_id(), process.getState().getExec_submode()); | |
429 | int function = process.getCurrent_function().intValue() | LttngConstants.STATS_FUNCTION_ID; | |
430 | int type = fTypeKeys.getUniqueId(event.getMarkerId(), event.getMarkerName()); | |
431 | ||
432 | /* | |
433 | * Note that it's faster to re-use the path object, set the relevant | |
434 | * fields and clone the path later when it's time to add to the map | |
435 | */ | |
436 | ||
437 | // FixedArray(trace,HEADER_EVENT_TYPES_INT,type) | |
438 | fTypedPaths[0].set(0, trace); | |
439 | fTypedPaths[0].set(2, type); | |
440 | ||
441 | // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
442 | fTypedPaths[1].set(0, trace); | |
443 | fTypedPaths[1].set(2, mode); | |
444 | fTypedPaths[1].set(4, type); | |
445 | ||
446 | // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
447 | fTypedPaths[2].set(0, trace); | |
448 | fTypedPaths[2].set(2, mode); | |
449 | fTypedPaths[2].set(4, submode); | |
450 | fTypedPaths[2].set(6, type); | |
451 | ||
452 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_EVENT_TYPES_INT,type) | |
453 | fTypedPaths[3].set(0, trace); | |
454 | fTypedPaths[3].set(2, processName); | |
455 | fTypedPaths[3].set(4, type); | |
456 | ||
457 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_EVENT_TYPES_INT,type) | |
458 | fTypedPaths[4].set(0, trace); | |
459 | fTypedPaths[4].set(2, processName); | |
460 | fTypedPaths[4].set(4, cpus); | |
461 | fTypedPaths[4].set(6, type); | |
462 | ||
463 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,HEADER_EVENT_TYPES_INT,type) | |
464 | fTypedPaths[5].set(0, trace); | |
465 | fTypedPaths[5].set(2, processName); | |
466 | fTypedPaths[5].set(4, cpus); | |
467 | fTypedPaths[5].set(6, function); | |
468 | fTypedPaths[5].set(8, type); | |
469 | ||
470 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
471 | fTypedPaths[6].set(0, trace); | |
472 | fTypedPaths[6].set(2, processName); | |
473 | fTypedPaths[6].set(4, cpus); | |
474 | fTypedPaths[6].set(6, function); | |
475 | fTypedPaths[6].set(8, mode); | |
476 | fTypedPaths[6].set(10, type); | |
477 | ||
478 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function, | |
479 | // HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
480 | fTypedPaths[7].set(0, trace); | |
481 | fTypedPaths[7].set(2, processName); | |
482 | fTypedPaths[7].set(4, cpus); | |
483 | fTypedPaths[7].set(6, function); | |
484 | fTypedPaths[7].set(8, mode); | |
485 | fTypedPaths[7].set(10, submode); | |
486 | fTypedPaths[7].set(12, type); | |
487 | ||
488 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
489 | fTypedPaths[8].set(0, trace); | |
490 | fTypedPaths[8].set(2, processName); | |
491 | fTypedPaths[8].set(4, cpus); | |
492 | fTypedPaths[8].set(6, mode); | |
493 | fTypedPaths[8].set(8, type); | |
494 | ||
495 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
496 | fTypedPaths[9].set(0, trace); | |
497 | fTypedPaths[9].set(2, processName); | |
498 | fTypedPaths[9].set(4, cpus); | |
499 | fTypedPaths[9].set(6, mode); | |
500 | fTypedPaths[9].set(8, submode); | |
501 | fTypedPaths[9].set(10, type); | |
502 | ||
503 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
504 | fTypedPaths[10].set(0, trace); | |
505 | fTypedPaths[10].set(2, processName); | |
506 | fTypedPaths[10].set(4, mode); | |
507 | fTypedPaths[10].set(6, type); | |
508 | ||
509 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
510 | fTypedPaths[11].set(0, trace); | |
511 | fTypedPaths[11].set(2, processName); | |
512 | fTypedPaths[11].set(4, mode); | |
513 | fTypedPaths[11].set(6, submode); | |
514 | fTypedPaths[11].set(8, type); | |
515 | ||
516 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_EVENT_TYPES_INT,type) | |
517 | fTypedPaths[12].set(0, trace); | |
518 | fTypedPaths[12].set(2, cpus); | |
519 | fTypedPaths[12].set(4, type); | |
520 | ||
521 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
522 | fTypedPaths[13].set(0, trace); | |
523 | fTypedPaths[13].set(2, cpus); | |
524 | fTypedPaths[13].set(4, mode); | |
525 | fTypedPaths[13].set(6, type); | |
526 | ||
527 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
528 | fTypedPaths[14].set(0, trace); | |
529 | fTypedPaths[14].set(2, cpus); | |
530 | fTypedPaths[14].set(4, mode); | |
531 | fTypedPaths[14].set(6, submode); | |
532 | fTypedPaths[14].set(8, type); | |
533 | ||
534 | return fTypedPaths; | |
a2e53983 FC |
535 | } |
536 | ||
537 | /* | |
538 | * (non-Javadoc) | |
539 | * | |
540 | * @see | |
541 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
542 | * #process_exit(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
543 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
544 | */ | |
545 | @Override | |
546 | public void process_exit(LttngEvent event, LttngTraceState traceState) { | |
b12f4544 FC |
547 | FixedArray[] paths = getNormalPaths(event, traceState); |
548 | Long cpu = event.getCpuId(); | |
549 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
a2e53983 | 550 | |
b12f4544 FC |
551 | for (int j = 0; j < paths.length; ++j) { |
552 | StatisticsTreeNode node = getOrCreate(paths[j], event, traceState, j, false); | |
a2e53983 | 553 | |
b12f4544 FC |
554 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { |
555 | node.getValue().cpuTime += event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
556 | } | |
557 | } | |
558 | // TODO Unstacks cumulative CPU time | |
559 | // TODO Elapsed time? | |
a2e53983 FC |
560 | } |
561 | ||
562 | /* | |
563 | * (non-Javadoc) | |
564 | * | |
565 | * @see | |
566 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
567 | * #increase(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
568 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState, int) | |
569 | */ | |
570 | @Override | |
571 | public void increase(LttngEvent event, LttngTraceState traceState, int values) { | |
b12f4544 FC |
572 | FixedArray[] paths = getNormalPaths(event, traceState); |
573 | Long cpu = event.getCpuId(); | |
3bf5d252 BH |
574 | LttngProcessState process = traceState.getRunning_process().get(cpu); |
575 | ||
576 | // Updating the cumulative CPU time | |
577 | if ((values & Values.STATE_CUMULATIVE_CPU_TIME) != 0) { | |
578 | if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
579 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
580 | long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
581 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
582 | } | |
583 | } | |
584 | if ((values & Values.CUMULATIVE_CPU_TIME) != 0) { | |
585 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
586 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
587 | long delta = event.getTimestamp().getValue() - process.getState().getEntry_LttTime(); | |
588 | long newCumulativeCpuTime = cumulativeCpuTime + delta; | |
589 | process.getState().setCum_cpu_time(newCumulativeCpuTime); | |
590 | } else if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
591 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
592 | long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
593 | long newCumulativeCpuTime = cumulativeCpuTime + delta; | |
594 | process.getState().setCum_cpu_time(newCumulativeCpuTime); | |
595 | } | |
596 | } | |
b12f4544 | 597 | |
3bf5d252 BH |
598 | for (int j = 0; j < paths.length; ++j) { |
599 | StatisticsTreeNode node = getOrCreate(paths[j], event, traceState, j, false); | |
b12f4544 FC |
600 | |
601 | if ((values & Values.CPU_TIME) != 0) { | |
602 | // TODO Uncomment if the event after process_exit need to be | |
603 | // count. | |
604 | if ((process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) /* | |
3bf5d252 | 605 | * || process.getState(). |
b12f4544 | 606 | * getProc_status |
3bf5d252 BH |
607 | * ().equals(ProcessStatus |
608 | * .LTTV_STATE_EXIT) | |
b12f4544 FC |
609 | */) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { |
610 | node.getValue().cpuTime += event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
611 | } | |
612 | } | |
613 | if ((values & Values.CUMULATIVE_CPU_TIME) != 0) { | |
614 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
b12f4544 FC |
615 | node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time(); |
616 | } else if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
3bf5d252 | 617 | node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time(); |
b12f4544 FC |
618 | } |
619 | } | |
620 | if ((values & Values.ELAPSED_TIME) != 0) { | |
621 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
622 | node.getValue().elapsedTime += event.getTimestamp().getValue() - process.getState().getEntry_LttTime(); | |
623 | } | |
624 | } | |
b12f4544 | 625 | } |
a2e53983 FC |
626 | } |
627 | ||
628 | /* | |
629 | * (non-Javadoc) | |
630 | * | |
631 | * @see | |
632 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
633 | * #registerEvent(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
634 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
635 | */ | |
636 | @Override | |
637 | public void registerEvent(LttngEvent event, LttngTraceState traceState) { | |
b12f4544 FC |
638 | FixedArray[] paths = getNormalPaths(event, traceState); |
639 | for (int i = 0; i < paths.length; ++i) | |
640 | ++(getOrCreate(paths[i], event, traceState, i, false).getValue().nbEvents); | |
a2e53983 | 641 | |
b12f4544 FC |
642 | paths = getTypePaths(event, traceState); |
643 | for (int i = 0; i < paths.length; ++i) | |
644 | ++(getOrCreate(paths[i], event, traceState, i, true).getValue().nbEvents); | |
a2e53983 | 645 | |
b12f4544 | 646 | // last_ = event; // TODO Used by endTraceset |
a2e53983 FC |
647 | } |
648 | ||
649 | /* | |
650 | * (non-Javadoc) | |
651 | * | |
652 | * @see | |
653 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
654 | * #registerName | |
655 | * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray) | |
656 | */ | |
657 | @Override | |
b12f4544 FC |
658 | protected void registerName(final FixedArray path) { |
659 | if (path.size() == 1) { | |
660 | if (!path.equals(ROOT)) | |
661 | getKeys().get(ROOT.get(0)).add(path.get(0)); | |
662 | } else if (path.size() % 2 != 0) | |
663 | getKeys().get(path.get(path.size() - 2)).add(path.get(path.size() - 1)); | |
664 | } | |
665 | ||
666 | /** | |
667 | * <h4>Get or create a node.</h4> | |
668 | * | |
669 | * @param path | |
670 | * Path to the node. | |
671 | * @param event | |
672 | * The current event | |
673 | * @param traceState | |
674 | * The current trace state | |
675 | * @param index | |
676 | * The corresponding index of the statistic | |
677 | * @param isType | |
678 | * The type of statistic (type or other) | |
679 | * @return The node. | |
680 | */ | |
681 | public StatisticsTreeNode getOrCreate(final FixedArray path, LttngEvent event, LttngTraceState traceState, int index, boolean isType) { | |
682 | StatisticsTreeNode current = get(path); | |
683 | if (current == null) { | |
684 | // We have to clone the path since the object for the path is | |
685 | // re-used for performance reasons! | |
686 | FixedArray newPath = (FixedArray) path.clone(); | |
687 | ||
688 | // Note that setting of the name is done here only when the node is | |
689 | // created (for performance reasons). | |
690 | String name = (isType) ? getTypeStatsName(event, traceState, index) : getOtherStatsName(event, traceState, index); | |
691 | registerName(path); | |
692 | current = new StatisticsTreeNode(newPath, this, name); | |
693 | put(newPath, current); | |
694 | } | |
f970b04d BH |
695 | else { |
696 | // Special case: Update name if event is of type "exec". This is necessary because the | |
697 | // process name can change at this point (See Bug333114)) | |
698 | if ((index == 3) && !isType && Events.LTT_EVENT_EXEC.getInName().equals(event.getMarkerName())) { | |
699 | String name = getOtherStatsName(event, traceState, index); | |
700 | current.setName(name); | |
701 | } | |
702 | } | |
b12f4544 FC |
703 | return current; |
704 | } | |
705 | ||
706 | /** | |
707 | * <h4>Get the name to be displayed for other statistics than type | |
708 | * statistics</h4> | |
709 | * | |
710 | * @param event | |
711 | * The current event | |
712 | * @param traceState | |
713 | * The current trace state | |
714 | * @param The | |
715 | * corresponding index of the statistic | |
716 | * @return The name | |
717 | */ | |
718 | private String getOtherStatsName(LttngEvent event, LttngTraceState traceState, int index) { | |
719 | Long cpu = event.getCpuId(); | |
720 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
721 | ||
722 | switch (index) { | |
723 | case 0: | |
724 | return traceState.getContext().getTraceId(); | |
725 | case 1: | |
726 | return process.getState().getExec_mode().getInName(); | |
727 | case 2: | |
728 | return process.getState().getExec_submode(); | |
729 | case 3: | |
730 | return getProcessName(process); | |
731 | case 4: | |
732 | return String.valueOf(cpu); | |
733 | case 5: | |
734 | return process.getCurrent_function().toString(); | |
735 | case 6: | |
736 | return process.getState().getExec_mode().getInName(); | |
737 | case 7: | |
738 | return process.getState().getExec_submode(); | |
739 | case 8: | |
740 | return process.getState().getExec_mode().getInName(); | |
741 | case 9: | |
742 | return process.getState().getExec_submode(); | |
743 | case 10: | |
744 | return process.getState().getExec_mode().getInName(); | |
745 | case 11: | |
746 | return process.getState().getExec_submode(); | |
747 | case 12: | |
748 | return String.valueOf(cpu); | |
749 | case 13: | |
750 | return process.getState().getExec_mode().getInName(); | |
751 | case 14: | |
752 | return process.getState().getExec_submode(); | |
753 | default: | |
754 | return ""; //$NON-NLS-1$ | |
755 | } | |
756 | } | |
757 | ||
758 | /** | |
759 | * <h4>Get the name to be displayed for type statistics</h4> | |
760 | * | |
761 | * @param event | |
762 | * The current event | |
763 | * @param traceState | |
764 | * The current state | |
765 | * @param index | |
766 | * The corresponding index of the statistic | |
767 | * @return The strings in a array | |
768 | */ | |
769 | private String getTypeStatsName(LttngEvent event, LttngTraceState traceState, int index) { | |
770 | return event.getMarkerName(); | |
771 | } | |
772 | ||
773 | /** | |
774 | * <h4>Get the name of a process.</h4> | |
775 | * | |
776 | * @param process | |
777 | * The process. | |
778 | * @return The name of the process. //TODO Adding the creation time of the | |
779 | * process may be needed to differentiate two process. | |
780 | */ | |
781 | private String getProcessName(LttngProcessState process) { | |
782 | if (process.getPid() == -1) | |
783 | return Messages.StatisticsData_UnknowProcess; | |
784 | if (process.getName() == null) | |
785 | return mergeString(Messages.StatisticsData_UnknowProcess + " - ", String.valueOf(process.getPid())); //$NON-NLS-1$ | |
786 | if (process.getName().equals("")) //$NON-NLS-1$ | |
787 | return process.getPid().toString(); | |
788 | else | |
789 | return mergeString(process.getName(), " - ", String.valueOf(process.getPid())); //$NON-NLS-1$ | |
790 | } | |
791 | ||
792 | /** | |
793 | * <h4>Converts the integer representation of the category to string.</h4> | |
794 | * | |
795 | * @param value | |
796 | * Integer representation of the category. | |
797 | * @return Category as string. | |
798 | */ | |
799 | public static String getCategoryFromId(int value) { | |
800 | switch (value) { | |
801 | case KernelStatisticsData.HEADER_CPUS_INT: | |
802 | return KernelStatisticsData.HEADER_CPUS; | |
803 | case KernelStatisticsData.HEADER_EVENT_TYPES_INT: | |
804 | return KernelStatisticsData.HEADER_EVENT_TYPES; | |
805 | case KernelStatisticsData.HEADER_FUNCTIONS_INT: | |
806 | return KernelStatisticsData.HEADER_FUNCTIONS; | |
807 | case KernelStatisticsData.HEADER_MODES_INT: | |
808 | return KernelStatisticsData.HEADER_MODES; | |
809 | case KernelStatisticsData.HEADER_PROCESSES_INT: | |
810 | return KernelStatisticsData.HEADER_PROCESSES; | |
811 | case KernelStatisticsData.HEADER_SUBMODES_INT: | |
812 | return KernelStatisticsData.HEADER_SUBMODES; | |
813 | } | |
814 | return ""; //$NON-NLS-1$ | |
a2e53983 | 815 | } |
9dbeec54 | 816 | |
b12f4544 FC |
817 | /** |
818 | * <h4>Provides unique keys for String - Integer pairs.</h4> | |
819 | * | |
f970b04d | 820 | * @author bhufmann |
b12f4544 FC |
821 | * |
822 | */ | |
823 | final private class KeyProvider { | |
824 | ||
825 | /** | |
826 | * <h4>Instance counter for unique ID generation.</h4> | |
827 | */ | |
828 | private int fCount = 0; | |
829 | ||
830 | /** | |
831 | * <h4>Attributes to generate unique IDs for processes.</h4> | |
832 | */ | |
833 | private HashMap<KeyHelper, Integer> fKeyMap = new HashMap<KeyHelper, Integer>(65535); | |
834 | private final KeyHelper fHelper = new KeyHelper(); | |
835 | ||
836 | /** | |
837 | * <h4>Bit mask to apply for the key.</h4> | |
838 | */ | |
839 | private int fBitMask = 0; | |
840 | ||
841 | /** | |
842 | * Constructor | |
843 | * | |
844 | * @param bitMask | |
845 | * <h4>Bit mask to apply for the key.</h4> | |
846 | */ | |
847 | KeyProvider(int bitMask) { | |
848 | this.fBitMask = bitMask; | |
849 | } | |
850 | ||
851 | /** | |
852 | * <h4>Standard Constructor</h4> | |
853 | */ | |
854 | KeyProvider() { | |
855 | this(0); | |
856 | } | |
857 | ||
858 | /** | |
859 | * <h4>Creates unique id for the given input data.</h4> | |
860 | * | |
861 | * @param value | |
862 | * Integer value of the data the key is for | |
863 | * @param name | |
864 | * Name of the data the key is for | |
b12f4544 FC |
865 | * @return Unique id |
866 | */ | |
867 | public int getUniqueId(int value, String name) { | |
868 | fHelper.setName(name); | |
869 | fHelper.setValue(value); | |
870 | ||
871 | Integer returnKey = fKeyMap.get(fHelper); | |
872 | if (returnKey == null) { | |
873 | returnKey = Integer.valueOf((++fCount) | fBitMask); | |
874 | KeyHelper newHelper = fHelper.clone(); | |
875 | fKeyMap.put(newHelper, returnKey); | |
876 | } | |
877 | return returnKey.intValue(); | |
878 | } | |
879 | } | |
880 | ||
881 | /** | |
0c9bad2e | 882 | <h4>Helper class that provides keys for HashMaps depending on an integer |
b12f4544 | 883 | * - string -pair. It provides better performance than using a string as key |
0c9bad2e BH |
884 | * only. However, for optimal performance the integer values should be mostly |
885 | * unique.</h4> | |
b12f4544 | 886 | * |
0c9bad2e | 887 | * @author bhufmann |
b12f4544 FC |
888 | * |
889 | */ | |
890 | private class KeyHelper implements Cloneable { | |
891 | ||
892 | // Short pre-fix | |
893 | private final static String UNKNOWN_PREFIX = "P"; //$NON-NLS-1$ | |
894 | ||
895 | private String fName = UNKNOWN_PREFIX; | |
896 | private int fValue = -1; | |
897 | ||
898 | /* | |
899 | * (non-Javadoc) | |
900 | * | |
901 | * @see java.lang.Object#hashCode() | |
902 | */ | |
903 | @Override | |
904 | public int hashCode() { | |
905 | return fValue; | |
906 | } | |
907 | ||
908 | /* | |
909 | * (non-Javadoc) | |
910 | * | |
911 | * @see java.lang.Object#equals(java.lang.Object) | |
912 | */ | |
913 | @Override | |
914 | public boolean equals(Object o) { | |
915 | if (fValue == ((KeyHelper) o).fValue && fName.equals(((KeyHelper) o).fName)) { | |
916 | return true; | |
917 | } | |
918 | return false; | |
919 | } | |
920 | ||
921 | /* | |
922 | * (non-Javadoc) | |
923 | * | |
924 | * @see java.lang.Object#clone() | |
925 | */ | |
926 | @Override | |
927 | public KeyHelper clone() { | |
928 | KeyHelper clone = null; | |
929 | try { | |
930 | clone = (KeyHelper) super.clone(); | |
931 | clone.fName = fName; | |
932 | clone.fValue = fValue; | |
933 | } catch (CloneNotSupportedException e) { | |
934 | e.printStackTrace(); | |
935 | } | |
936 | return clone; | |
937 | } | |
938 | ||
939 | /** | |
940 | * <h4>Set the name of the key.</h4> | |
941 | * | |
942 | * @param name | |
943 | * The name to set. | |
944 | */ | |
945 | public void setName(String name) { | |
946 | if (fName != null) | |
947 | this.fName = name; | |
948 | else | |
949 | this.fName = UNKNOWN_PREFIX; | |
950 | } | |
951 | ||
952 | /** | |
953 | * <h4>Set the value of the key.</h4> | |
954 | * | |
955 | * @param value | |
956 | */ | |
957 | public void setValue(int value) { | |
958 | this.fValue = value; | |
959 | } | |
960 | } | |
f970b04d BH |
961 | |
962 | /** | |
963 | * <h4>Provides unique keys for given process information. For optimal performance the integer | |
964 | * PIDs need to be mostly unique</h4> | |
965 | * | |
966 | * @author bhufmann | |
967 | * | |
968 | */ | |
969 | final private class ProcessKeyProvider { | |
970 | /** | |
971 | * <h4>Instance counter for unique ID generation.</h4> | |
972 | */ | |
973 | private int fCount = 0; | |
974 | ||
975 | /** | |
976 | * <h4>Attributes to generate unique IDs for processes.</h4> | |
977 | */ | |
978 | private HashMap<ProcessKey, Integer> fKeyMap = new HashMap<ProcessKey, Integer>(65535); | |
979 | private ProcessKey fHelper = new ProcessKey(); | |
980 | ||
981 | /** | |
982 | * <h4>Bit mask to apply for the key.</h4> | |
983 | */ | |
984 | private int fBitMask = 0; | |
985 | ||
986 | /** | |
987 | * Constructor | |
988 | * | |
989 | * @param bitMask | |
990 | * <h4>Bit mask to apply for the key.</h4> | |
991 | */ | |
992 | public ProcessKeyProvider(int bitMask) { | |
993 | fBitMask = bitMask; | |
994 | } | |
995 | ||
996 | /** | |
997 | * <h4>Creates unique id for the given input data.</h4> | |
998 | * | |
999 | * @param value | |
1000 | * Integer value of the data the key is for | |
1001 | * @param cpuId | |
1002 | * The cpuId for the processKey Helper | |
1003 | * @param creationTime | |
1004 | * The creation Time for the processKey Helper | |
1005 | * @return Unique id | |
1006 | */ | |
1007 | public int getUniqueId(int value, int cpuId, long creationTime) { | |
1008 | fHelper.setPid(value); | |
1009 | fHelper.setCpuId(cpuId); | |
1010 | fHelper.setCreationTime(creationTime); | |
1011 | ||
1012 | Integer returnKey = fKeyMap.get(fHelper); | |
1013 | if (returnKey == null) { | |
1014 | returnKey = Integer.valueOf((++fCount) | fBitMask); | |
1015 | ProcessKey newHelper = fHelper.clone(); | |
1016 | fKeyMap.put(newHelper, returnKey); | |
1017 | } | |
1018 | return returnKey.intValue(); | |
1019 | } | |
1020 | } | |
1021 | ||
1022 | /** | |
1023 | <h4>Helper class that provides keys for HashMaps depending on process information.</h4> | |
1024 | * | |
1025 | * @author bhufmann | |
1026 | * | |
1027 | */ | |
1028 | final class ProcessKey implements Cloneable { | |
1029 | private int fPid = 0; | |
1030 | private int fCpuId = 0; | |
1031 | private long fCreationTime = 0; | |
1032 | ||
1033 | /** | |
1034 | * <h4>Set the PID of the key.</h4> | |
1035 | * | |
1036 | * @param pid | |
1037 | */ | |
1038 | public void setPid(int pid) { | |
1039 | this.fPid = pid; | |
1040 | } | |
1041 | ||
1042 | /** | |
1043 | * <h4>Set the cpuTime of the process key.</h4> | |
1044 | * | |
1045 | * @param cpuTime | |
1046 | * The name to set. | |
1047 | */ | |
1048 | public void setCpuId(int cpuId) { | |
1049 | this.fCpuId = cpuId; | |
1050 | } | |
1051 | ||
1052 | /** | |
1053 | * <h4>Set the creationTime of the process key.</h4> | |
1054 | * | |
1055 | * @param creationTime | |
1056 | * The name to set. | |
1057 | */ | |
1058 | public void setCreationTime(long creationTime) { | |
1059 | this.fCreationTime = creationTime; | |
1060 | } | |
1061 | ||
1062 | /* | |
1063 | * (non-Javadoc) | |
1064 | * @see java.lang.Object#equals(java.lang.Object) | |
1065 | */ | |
1066 | @Override | |
1067 | public boolean equals(Object obj) { | |
1068 | ProcessKey procKey = (ProcessKey) obj; | |
1069 | ||
1070 | if (procKey.fPid != this.fPid) { | |
1071 | return false; | |
1072 | } | |
1073 | ||
1074 | if (procKey.fCreationTime != this.fCreationTime) { | |
1075 | return false; | |
1076 | } | |
1077 | ||
1078 | // use the cpu value to validate pid 0 | |
1079 | if (((procKey.fPid == 0L) && (procKey.fCpuId != this.fCpuId))) { | |
1080 | return false; | |
1081 | } | |
1082 | return true; | |
1083 | } | |
1084 | ||
1085 | /* | |
1086 | * (non-Javadoc) | |
1087 | * @see java.lang.Object#hashCode() | |
1088 | */ | |
1089 | @Override | |
1090 | public int hashCode() { | |
1091 | return this.fPid; | |
1092 | } | |
1093 | ||
1094 | /* | |
1095 | * (non-Javadoc) | |
1096 | * @see java.lang.Object#clone() | |
1097 | */ | |
1098 | @Override | |
1099 | public ProcessKey clone() { | |
1100 | ProcessKey clone = null; | |
1101 | try { | |
1102 | clone = (ProcessKey) super.clone(); | |
1103 | clone.fPid = fPid; | |
1104 | clone.fCpuId = fCpuId; | |
1105 | clone.fCreationTime = fCreationTime; | |
1106 | } catch (CloneNotSupportedException e) { | |
1107 | e.printStackTrace(); | |
1108 | } | |
1109 | return clone; | |
1110 | } | |
1111 | } | |
1112 | } |