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; | |
16 | import java.util.HashSet; | |
17 | import java.util.LinkedList; | |
18 | import java.util.Set; | |
19 | import java.util.Map; | |
20 | ||
21 | import org.eclipse.linuxtools.lttng.event.LttngEvent; | |
22 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; | |
23 | import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; | |
24 | import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; | |
25 | import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; | |
26 | ||
27 | /** | |
28 | * <h4>Class that process the LTTng kernel events.</h4> | |
29 | */ | |
30 | public class KernelStatisticsData extends StatisticsData { | |
31 | /** | |
32 | * <h4>Header for the mode categories.</h4> | |
33 | */ | |
34 | private static final String HEADER_CPUS = "CPUs"; | |
35 | /** | |
36 | * <h4>Header for the event types categories.</h4> | |
37 | */ | |
38 | private static final String HEADER_EVENT_TYPES = "Event Types"; | |
39 | /** | |
40 | * <h4>Header for the function categories.</h4> | |
41 | */ | |
42 | private static final String HEADER_FUNCTIONS = "Functions"; | |
43 | /** | |
44 | * <h4>Header for the mode categories.</h4> | |
45 | */ | |
46 | private static final String HEADER_MODES = "Modes"; | |
47 | /** | |
48 | * <h4>Header for the processes categories.</h4> | |
49 | */ | |
50 | private static final String HEADER_PROCESSES = "Processes"; | |
51 | /** | |
52 | * <h4>Header for the submode categories.</h4> | |
53 | */ | |
54 | private static final String HEADER_SUBMODES ="Submodes"; | |
55 | /** | |
56 | * <h4>Indicate that it's a value.</h4> | |
57 | * <p>Used when checking the possible child node for a node.</p> | |
58 | * <p>It differentiate a category of a value by being appended to a value.</p> | |
59 | */ | |
60 | private static final String NODE = "z"; | |
61 | private static final String ROOT_NODE_KEY = mergeString(ROOT.get(0), NODE); | |
62 | /** | |
63 | * <h4>Constructor.</h4> | |
64 | * @param traceName | |
65 | */ | |
66 | public KernelStatisticsData(String traceName) { | |
67 | super(); | |
68 | Map<String, Set<String>> keys = getKeys(); | |
69 | ||
70 | ////////////// Adding category sets | |
71 | keys.put(HEADER_PROCESSES, new HashSet<String>()); | |
72 | keys.put(HEADER_MODES, new HashSet<String>()); | |
73 | keys.put(HEADER_CPUS, new HashSet<String>(4)); // Over 4 CPUs is not common | |
74 | keys.put(HEADER_SUBMODES, new HashSet<String>()); | |
75 | keys.put(HEADER_EVENT_TYPES, new HashSet<String>()); | |
76 | keys.put(HEADER_FUNCTIONS, new HashSet<String>(4)); // Seems to be always one. | |
77 | ||
78 | ///////////// Adding value sets | |
79 | // Under a trace | |
80 | Set<String> temp = new HashSet<String>(8); | |
81 | temp.add(HEADER_PROCESSES); | |
82 | temp.add(HEADER_MODES); | |
83 | temp.add(HEADER_CPUS); | |
84 | temp.add(HEADER_EVENT_TYPES); | |
85 | keys.put(ROOT_NODE_KEY, temp); | |
86 | // Under a process | |
87 | temp = new HashSet<String>(4); | |
88 | temp.add(HEADER_MODES); | |
89 | temp.add(HEADER_CPUS); | |
90 | temp.add(HEADER_EVENT_TYPES); | |
91 | keys.put(mergeString(HEADER_PROCESSES,NODE), temp); | |
92 | // Under a CPUs : Functions is a special case | |
93 | temp = new HashSet<String>(4); | |
94 | temp.add(HEADER_MODES); | |
95 | temp.add(HEADER_EVENT_TYPES); | |
96 | keys.put(mergeString(HEADER_CPUS,NODE), temp); | |
97 | // Under a functions | |
98 | temp = new HashSet<String>(4); | |
99 | temp.add(HEADER_MODES); | |
100 | temp.add(HEADER_EVENT_TYPES); | |
101 | keys.put(mergeString(HEADER_FUNCTIONS,NODE), temp); | |
102 | // Under a mode | |
103 | temp = new HashSet<String>(4); | |
104 | temp.add(HEADER_SUBMODES); | |
105 | temp.add(HEADER_EVENT_TYPES); | |
106 | keys.put(mergeString(HEADER_MODES,NODE), temp); | |
107 | // Under a submodes | |
108 | temp = new HashSet<String>(2); | |
109 | temp.add(HEADER_EVENT_TYPES); | |
110 | keys.put(mergeString(HEADER_SUBMODES,NODE), temp); | |
111 | // Under an event type | |
112 | temp = new HashSet<String>(16); | |
113 | keys.put(mergeString(HEADER_EVENT_TYPES,NODE),temp); | |
114 | ||
115 | ////////////// CREATE root | |
116 | keys.put(ROOT.get(0), new HashSet<String>(2)); // 1 trace at the time | |
117 | getOrCreate(ROOT); | |
118 | } | |
119 | /* | |
120 | * (non-Javadoc) | |
121 | * @see org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData#endTraceset(org.eclipse.linuxtools.lttng.event.LttngEvent, org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
122 | */ | |
123 | @Override | |
124 | public void endTraceset(LttngEvent event, LttngTraceState traceState) { | |
125 | // TODO Should we uncomment the rest? | |
126 | // It include in the cpu time the time between the last event of each cpu and the time of the last global event. | |
127 | // Because we know that there won't be a change of mode or process between those time. | |
128 | /*if(last_ == null) | |
129 | return; | |
130 | ||
131 | LttngProcessState process = traceState.getRunning_process().get(0L); | |
132 | System.out.println(process.getState().getChange_LttTime()); | |
133 | for(long cpu : traceState.getRunning_process().keySet()) { | |
134 | LttngEventType newType = new LttngEventType(last_.getType().getTracefileName(), cpu, last_.getType().getMarkerName(), last_.getType().getLabels()); | |
135 | last_.setType(newType); | |
136 | increase(last_, traceState, | |
137 | Values.CPU_TIME | Values.CUMULATIVE_CPU_TIME | Values.ELAPSED_TIME | Values.STATE_CUMULATIVE_CPU_TIME); | |
138 | // TODO Are all those values required? | |
139 | }*/ | |
140 | } | |
141 | /* | |
142 | * (non-Javadoc) | |
143 | * @see org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData#getChildren(org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray) | |
144 | */ | |
145 | @Override | |
146 | public Collection<StatisticsTreeNode> getChildren(final FixedArray<String> path) { | |
147 | LinkedList<StatisticsTreeNode> result = new LinkedList<StatisticsTreeNode>(); | |
148 | ||
149 | if(path.size() % 2 == 0) { // if we are at a Category | |
150 | StatisticsTreeNode current = null; | |
151 | for(String value : getKeys().get(path.get(path.size() - 1))) { | |
152 | current = get(path.append(value)); | |
153 | if(current != null && current.getValue().nbEvents != 0) | |
154 | result.add(current); | |
155 | } | |
156 | } | |
157 | else if(path.size() == 1) { // Special case. | |
158 | if(path.equals(ROOT)) // Asking for the root. | |
159 | for(String value : getKeys().get(ROOT.get(0))) | |
160 | result.add(getOrCreate(new FixedArray<String>(value))); | |
161 | else // Get value under the root | |
162 | for (String value : getKeys().get(ROOT_NODE_KEY)) | |
163 | result.add(getOrCreate(path.append(value))); | |
164 | } | |
165 | else {// If we are at a value | |
166 | for(String value : getKeys().get(mergeString(path.get(path.size() -2),NODE))) // Search the parent name + NODE | |
167 | result.add(getOrCreate(path.append(value))); | |
168 | ||
169 | if(path.size() == 5 && path.get(3).equals(HEADER_CPUS)) // Special the Functions is just there. We want the fourth element but it start at 0. So #3 | |
170 | result.add(getOrCreate(path.append(HEADER_FUNCTIONS))); | |
171 | } | |
172 | ||
173 | return result; | |
174 | } | |
175 | /** | |
176 | * <h4>Get the standard paths for an event.</h4> | |
177 | * @param event Event to get the path for. | |
178 | * @param traceState State of the trace for this event. | |
179 | * @return Array of FixedArray representing the paths. | |
180 | */ | |
181 | @SuppressWarnings({ "rawtypes", "unchecked" }) | |
182 | private FixedArray<String>[] getNormalPaths(LttngEvent event, LttngTraceState traceState) { | |
183 | String trace = traceState.getContext().getTraceId(); | |
184 | Long cpu = event.getCpuId(); | |
185 | String cpus = String.valueOf(cpu); | |
186 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
187 | String processName = getProcessName(process); | |
188 | String mode = process.getState().getExec_mode().getInName(); | |
189 | String submode = process.getState().getExec_submode(); | |
190 | String function = process.getCurrent_function().toString(); | |
191 | ||
192 | FixedArray[] paths = { | |
193 | new FixedArray<String>(trace), | |
194 | new FixedArray<String>(trace,HEADER_MODES,mode), | |
195 | new FixedArray<String>(trace,HEADER_MODES,mode,HEADER_SUBMODES,submode), | |
196 | new FixedArray<String>(trace,HEADER_PROCESSES,processName), | |
197 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus), | |
198 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_FUNCTIONS,function), | |
199 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_FUNCTIONS,function, HEADER_MODES, mode), | |
200 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_FUNCTIONS,function, HEADER_MODES, mode, HEADER_SUBMODES, submode), | |
201 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_MODES,mode), | |
202 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_MODES,mode,HEADER_SUBMODES,submode), | |
203 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_MODES,mode), | |
204 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_MODES,mode,HEADER_SUBMODES,submode), | |
205 | new FixedArray<String>(trace,HEADER_CPUS,cpus), | |
206 | new FixedArray<String>(trace,HEADER_CPUS,cpus,HEADER_MODES,mode), | |
207 | new FixedArray<String>(trace,HEADER_CPUS,cpus,HEADER_MODES,mode,HEADER_SUBMODES,submode), | |
208 | }; | |
209 | ||
210 | return paths; | |
211 | } | |
212 | /** | |
213 | * <h4>Get the event types paths.</h4> | |
214 | * @param event Event to get the path for. | |
215 | * @param traceState State of the trace for this event. | |
216 | * @return Array of FixedArray representing the paths. | |
217 | */ | |
218 | @SuppressWarnings({ "rawtypes", "unchecked" }) | |
219 | private FixedArray<String>[] getTypePaths(LttngEvent event, LttngTraceState traceState) { | |
220 | String trace = traceState.getContext().getTraceId(); | |
221 | Long cpu = event.getCpuId(); | |
222 | String cpus = String.valueOf(cpu); | |
223 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
224 | String processName = getProcessName(process); | |
225 | String mode = process.getState().getExec_mode().getInName(); | |
226 | String submode = process.getState().getExec_submode(); | |
227 | String function = process.getCurrent_function().toString(); | |
228 | //String type = event.getType().getTypeId(); // Add too much informations | |
229 | String type = event.getMarkerName(); | |
230 | ||
231 | FixedArray[] paths = { | |
232 | new FixedArray<String>(trace,HEADER_EVENT_TYPES,type), | |
233 | new FixedArray<String>(trace,HEADER_MODES,mode,HEADER_EVENT_TYPES,type), | |
234 | new FixedArray<String>(trace,HEADER_MODES,mode,HEADER_SUBMODES,submode,HEADER_EVENT_TYPES,type), | |
235 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_EVENT_TYPES,type), | |
236 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_EVENT_TYPES,type), | |
237 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_FUNCTIONS,function,HEADER_EVENT_TYPES,type), | |
238 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_FUNCTIONS,function, HEADER_MODES, mode,HEADER_EVENT_TYPES,type), | |
239 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_FUNCTIONS,function, HEADER_MODES, mode, HEADER_SUBMODES, submode,HEADER_EVENT_TYPES,type), | |
240 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_MODES,mode,HEADER_EVENT_TYPES,type), | |
241 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_CPUS,cpus,HEADER_MODES,mode,HEADER_SUBMODES,submode,HEADER_EVENT_TYPES,type), | |
242 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_MODES,mode,HEADER_EVENT_TYPES,type), | |
243 | new FixedArray<String>(trace,HEADER_PROCESSES,processName,HEADER_MODES,mode,HEADER_SUBMODES,submode,HEADER_EVENT_TYPES,type), | |
244 | new FixedArray<String>(trace,HEADER_CPUS,cpus,HEADER_EVENT_TYPES,type), | |
245 | new FixedArray<String>(trace,HEADER_CPUS,cpus,HEADER_MODES,mode,HEADER_EVENT_TYPES,type), | |
246 | new FixedArray<String>(trace,HEADER_CPUS,cpus,HEADER_MODES,mode,HEADER_SUBMODES,submode,HEADER_EVENT_TYPES,type), | |
247 | }; | |
248 | ||
249 | return paths; | |
250 | } | |
251 | /* | |
252 | * (non-Javadoc) | |
253 | * @see org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData#process_exit(org.eclipse.linuxtools.lttng.event.LttngEvent, org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
254 | */ | |
255 | @Override | |
256 | public void process_exit(LttngEvent event, LttngTraceState traceState) { | |
257 | FixedArray<String>[] paths = getNormalPaths(event,traceState); | |
258 | Long cpu = event.getCpuId(); | |
259 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
260 | ||
261 | for(FixedArray<String> path : paths) { | |
262 | StatisticsTreeNode node = getOrCreate(path); | |
263 | ||
264 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
265 | node.getValue().cpuTime += event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
266 | } | |
267 | } | |
268 | ||
269 | // TODO Unstacks cumulative CPU time | |
270 | // TODO Elapsed time? | |
271 | } | |
272 | /* | |
273 | * (non-Javadoc) | |
274 | * @see org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData#increase(org.eclipse.linuxtools.lttng.event.LttngEvent, org.eclipse.linuxtools.lttng.state.model.LttngTraceState, int) | |
275 | */ | |
276 | @Override | |
277 | public void increase(LttngEvent event, LttngTraceState traceState, int values) { | |
278 | FixedArray<String>[] paths = getNormalPaths(event, traceState); | |
279 | Long cpu = event.getCpuId(); | |
280 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
281 | ||
282 | for(FixedArray<String> path : paths) | |
283 | { | |
284 | StatisticsTreeNode node = getOrCreate(path); | |
285 | ||
286 | if((values & Values.CPU_TIME) != 0) { | |
287 | // TODO Uncomment if the event after process_exit need to be count. | |
288 | if ((process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) /*|| process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_EXIT)*/) && | |
289 | !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
290 | node.getValue().cpuTime += event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
291 | } | |
292 | } | |
293 | if((values & Values.CUMULATIVE_CPU_TIME) != 0) { | |
294 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
295 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
296 | long delta = event.getTimestamp().getValue() - process.getState().getEntry_LttTime(); | |
297 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
298 | node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time(); | |
299 | } | |
300 | else if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && | |
301 | !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
302 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
303 | long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
304 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
305 | node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time(); | |
306 | } | |
307 | } | |
308 | if((values & Values.ELAPSED_TIME) != 0) { | |
309 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
310 | node.getValue().elapsedTime += event.getTimestamp().getValue() | |
311 | - process.getState().getEntry_LttTime(); | |
312 | } | |
313 | } | |
314 | if((values & Values.STATE_CUMULATIVE_CPU_TIME) != 0) { | |
315 | if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && | |
316 | !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
317 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
318 | long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
319 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
320 | } | |
321 | } | |
322 | } | |
323 | } | |
324 | /* | |
325 | * (non-Javadoc) | |
326 | * @see org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData#registerEvent(org.eclipse.linuxtools.lttng.event.LttngEvent, org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
327 | */ | |
328 | @Override | |
329 | public void registerEvent(LttngEvent event, LttngTraceState traceState) { | |
330 | FixedArray<String>[] paths = getNormalPaths(event, traceState); | |
331 | for(FixedArray<String> path : paths) | |
332 | ++(getOrCreate(path).getValue().nbEvents); | |
333 | ||
334 | paths = getTypePaths(event, traceState); | |
335 | for(FixedArray<String> path : paths) | |
336 | ++(getOrCreate(path).getValue().nbEvents); | |
337 | ||
338 | //last_ = event; // TODO Used by endTraceset | |
339 | } | |
340 | /* | |
341 | * (non-Javadoc) | |
342 | * @see org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData#registerName(org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray) | |
343 | */ | |
344 | @Override | |
345 | protected void registerName(final FixedArray<String> path) { | |
346 | if(path.size() == 1) { | |
347 | if(!path.equals(ROOT)) | |
348 | getKeys().get(ROOT.get(0)).add(path.get(0)); | |
349 | } | |
350 | else if(path.size() % 2 != 0) | |
351 | getKeys().get(path.get(path.size() - 2)).add(path.get(path.size() - 1)); | |
352 | } | |
353 | ||
354 | } |