1 /*******************************************************************************
2 * Copyright (c) 2010 Ericsson
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
10 * Francois Godin (copelnug@gmail.com) - Initial design and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.statistics
.model
;
15 import java
.util
.Collection
;
16 import java
.util
.HashMap
;
17 import java
.util
.HashSet
;
18 import java
.util
.LinkedList
;
22 import org
.eclipse
.linuxtools
.lttng
.LttngConstants
;
23 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
24 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ExecutionMode
;
25 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ProcessStatus
;
26 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngProcessState
;
27 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTraceState
;
30 * <h4>Class that process the LTTng kernel events.</h4>
32 public class KernelStatisticsData
extends StatisticsData
{
34 * <h4>Header for the CPU categories.</h4>
36 public static final String HEADER_CPUS
= Messages
.KernelStatisticsData_CPUs
;
37 public static final int HEADER_CPUS_INT
= 256 | LttngConstants
.STATS_CATEGORY_ID
;
39 * <h4>Header for the event types categories.</h4>
41 public static final String HEADER_EVENT_TYPES
= Messages
.KernelStatisticsData_EventTypes
;
42 public static final int HEADER_EVENT_TYPES_INT
= (HEADER_CPUS_INT
+ 1) | LttngConstants
.STATS_CATEGORY_ID
;
44 * <h4>Header for the function categories.</h4>
46 public static final String HEADER_FUNCTIONS
= Messages
.KernelStatisticsData_Functions
;
47 public static final int HEADER_FUNCTIONS_INT
= (HEADER_EVENT_TYPES_INT
+ 1) | LttngConstants
.STATS_CATEGORY_ID
;
49 * <h4>Header for the mode categories.</h4>
51 public static final String HEADER_MODES
= Messages
.KernelStatisticsData_Modes
;
52 public static final int HEADER_MODES_INT
= (HEADER_FUNCTIONS_INT
+ 1) | LttngConstants
.STATS_CATEGORY_ID
;
54 * <h4>Header for the processes categories.</h4>
56 public static final String HEADER_PROCESSES
= Messages
.KernelStatisticsData_Processes
;
57 public static final int HEADER_PROCESSES_INT
= (HEADER_MODES_INT
+ 1) | LttngConstants
.STATS_CATEGORY_ID
;
59 * <h4>Header for the submode categories.</h4>
61 public static final String HEADER_SUBMODES
= Messages
.KernelStatisticsData_SubModes
;
62 public static final int HEADER_SUBMODES_INT
= (HEADER_PROCESSES_INT
+ 1) | LttngConstants
.STATS_CATEGORY_ID
;
65 * <h4>Class to generate unique IDs for processes.</h4>
67 private KeyProvider fPidKeys
= new KeyProvider(LttngConstants
.STATS_PROCESS_ID
);
70 * <h4>Class to generate unique Ids for event types.</h4>
72 private KeyProvider fTypeKeys
= new KeyProvider(LttngConstants
.STATS_TYPE_ID
);
74 * <h4>Class to generate unique Ids for subModes.</h4>
76 private KeyProvider fSubModeKeys
= new KeyProvider();
79 * <h4>Place Holder in path.</h4>
81 private static final int PLACE_HOLDER
= 0;
84 * For performance reason the following algorithm is applied to the paths:
86 * Each array entry has to be unique to form a unique path. To generate
87 * unique entries a bit mask is used, where the bit mask is applied to the
88 * upper N bits of an integer value. It is assumed, that each value that
89 * will be filled in the place holder below is smaller than 2 ^ (32 - N).
93 * <h4>Pre-created paths for type statistics, which will be filled for each
94 * relevant event.</h4>
96 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
),
97 new FixedArray(PLACE_HOLDER
, HEADER_MODES_INT
, PLACE_HOLDER
, HEADER_SUBMODES_INT
, PLACE_HOLDER
, HEADER_EVENT_TYPES_INT
, PLACE_HOLDER
),
98 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_EVENT_TYPES_INT
, PLACE_HOLDER
),
99 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_CPUS_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_FUNCTIONS_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_MODES_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_SUBMODES_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_MODES_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_SUBMODES_INT
, PLACE_HOLDER
, HEADER_EVENT_TYPES_INT
, PLACE_HOLDER
),
105 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_MODES_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_SUBMODES_INT
, PLACE_HOLDER
, HEADER_EVENT_TYPES_INT
, PLACE_HOLDER
),
107 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
),
108 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 * <h4>Pre-created paths for other statistics, which will be filled for each
111 * relevant event.</h4>
113 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
),
114 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
), new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
),
115 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
, HEADER_FUNCTIONS_INT
, PLACE_HOLDER
),
116 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
, HEADER_FUNCTIONS_INT
, PLACE_HOLDER
, HEADER_MODES_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
, HEADER_SUBMODES_INT
, PLACE_HOLDER
),
118 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
, HEADER_MODES_INT
, PLACE_HOLDER
),
119 new FixedArray(PLACE_HOLDER
, HEADER_PROCESSES_INT
, PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
, HEADER_MODES_INT
, PLACE_HOLDER
, HEADER_SUBMODES_INT
, PLACE_HOLDER
),
120 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
),
121 new FixedArray(PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
), new FixedArray(PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
, HEADER_MODES_INT
, PLACE_HOLDER
),
122 new FixedArray(PLACE_HOLDER
, HEADER_CPUS_INT
, PLACE_HOLDER
, HEADER_MODES_INT
, PLACE_HOLDER
, HEADER_SUBMODES_INT
, PLACE_HOLDER
), };
125 * <h4>Indicate that it's a value.</h4>
127 * Used when checking the possible child node for a node.
130 * It differentiate a category of a value by being appended to a value.
133 private static final Integer NODE
= -1;
134 private static final Integer ROOT_NODE_KEY
= -2;
137 * <h4>Constructor.</h4>
141 public KernelStatisticsData(String traceName
) {
143 Map
<Integer
, Set
<Integer
>> keys
= getKeys();
145 // //////////// Adding category sets
146 keys
.put(HEADER_PROCESSES_INT
, new HashSet
<Integer
>());
147 keys
.put(HEADER_MODES_INT
, new HashSet
<Integer
>());
148 keys
.put(HEADER_CPUS_INT
, new HashSet
<Integer
>(4)); // Over 4 CPUs is
150 keys
.put(HEADER_SUBMODES_INT
, new HashSet
<Integer
>());
151 keys
.put(HEADER_EVENT_TYPES_INT
, new HashSet
<Integer
>());
152 keys
.put(HEADER_FUNCTIONS_INT
, new HashSet
<Integer
>(4)); // Seems to be
155 // /////////// Adding value sets
157 Set
<Integer
> temp
= new HashSet
<Integer
>(8);
158 temp
.add(HEADER_PROCESSES_INT
);
159 temp
.add(HEADER_MODES_INT
);
160 temp
.add(HEADER_CPUS_INT
);
161 temp
.add(HEADER_EVENT_TYPES_INT
);
162 keys
.put(ROOT_NODE_KEY
, temp
);
164 temp
= new HashSet
<Integer
>(4);
165 temp
.add(HEADER_MODES_INT
);
166 temp
.add(HEADER_CPUS_INT
);
167 temp
.add(HEADER_EVENT_TYPES_INT
);
168 keys
.put(HEADER_PROCESSES_INT
* NODE
, temp
);
169 // Under a CPUs : Functions is a special case
170 temp
= new HashSet
<Integer
>(4);
171 temp
.add(HEADER_MODES_INT
);
172 temp
.add(HEADER_EVENT_TYPES_INT
);
173 keys
.put(HEADER_CPUS_INT
* NODE
, temp
);
175 temp
= new HashSet
<Integer
>(4);
176 temp
.add(HEADER_MODES_INT
);
177 temp
.add(HEADER_EVENT_TYPES_INT
);
178 keys
.put(HEADER_FUNCTIONS_INT
* NODE
, temp
);
180 temp
= new HashSet
<Integer
>(4);
181 temp
.add(HEADER_SUBMODES_INT
);
182 temp
.add(HEADER_EVENT_TYPES_INT
);
183 keys
.put(HEADER_MODES_INT
* NODE
, temp
);
185 temp
= new HashSet
<Integer
>(2);
186 temp
.add(HEADER_EVENT_TYPES_INT
);
187 keys
.put(HEADER_SUBMODES_INT
* NODE
, temp
);
188 // Under an event type
189 temp
= new HashSet
<Integer
>(16);
190 keys
.put(HEADER_EVENT_TYPES_INT
* NODE
, temp
);
192 // //////////// CREATE root
193 keys
.put(ROOT
.get(0), new HashSet
<Integer
>(2)); // 1 trace at the time
194 StatisticsTreeNode node
= getOrCreate(ROOT
);
195 node
.setName("root"); //$NON-NLS-1$
202 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
203 * #endTraceset(org.eclipse.linuxtools.lttng.event.LttngEvent,
204 * org.eclipse.linuxtools.lttng.state.model.LttngTraceState)
207 public void endTraceset(LttngEvent event
, LttngTraceState traceState
) {
208 // TODO Should we uncomment the rest?
209 // It include in the cpu time the time between the last event of each
210 // cpu and the time of the last global event.
211 // Because we know that there won't be a change of mode or process
212 // between those time.
214 * if(last_ == null) return;
216 * LttngProcessState process = traceState.getRunning_process().get(0L);
217 * System.out.println(process.getState().getChange_LttTime()); for(long
218 * cpu : traceState.getRunning_process().keySet()) { LttngEventType
219 * newType = new LttngEventType(last_.getType().getTracefileName(), cpu,
220 * last_.getType().getMarkerName(), last_.getType().getLabels());
221 * last_.setType(newType); increase(last_, traceState, Values.CPU_TIME |
222 * Values.CUMULATIVE_CPU_TIME | Values.ELAPSED_TIME |
223 * Values.STATE_CUMULATIVE_CPU_TIME); // TODO Are all those values
232 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
234 * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray)
237 public Collection
<StatisticsTreeNode
> getChildren(final FixedArray path
) {
238 LinkedList
<StatisticsTreeNode
> result
= new LinkedList
<StatisticsTreeNode
>();
240 if (path
.size() % 2 == 0) { // if we are at a Category
241 StatisticsTreeNode current
= null;
242 for (int value
: getKeys().get(path
.get(path
.size() - 1))) {
243 current
= get(path
.append(value
));
244 if (current
!= null && current
.getValue().nbEvents
!= 0)
247 } else if (path
.size() == 1) { // Special case.
248 if (path
.equals(ROOT
)) // Asking for the root.
249 for (int value
: getKeys().get(ROOT
.get(0)))
250 result
.add(getOrCreate(new FixedArray(value
)));
252 // Get value under the root
253 for (int value
: getKeys().get(ROOT_NODE_KEY
)) {
254 StatisticsTreeNode node
= getOrCreate(path
.append(value
));
255 node
.setName(getCategoryFromId(value
));
258 } else {// If we are at a value
259 for (int value
: getKeys().get((path
.get(path
.size() - 2) * NODE
))) { // Search
265 StatisticsTreeNode node
= getOrCreate(path
.append(value
));
266 node
.setName(getCategoryFromId(value
));
270 if (path
.size() == 5 && path
.get(3) == HEADER_CPUS_INT
) { // Special
283 StatisticsTreeNode node
= getOrCreate(path
.append(HEADER_FUNCTIONS_INT
));
284 node
.setName(getCategoryFromId(HEADER_FUNCTIONS_INT
));
293 * <h4>Get the standard paths for an event.</h4>
296 * Event to get the path for.
298 * State of the trace for this event.
299 * @return Array of FixedArray representing the paths.
301 private FixedArray
[] getNormalPaths(LttngEvent event
, LttngTraceState traceState
) {
302 int trace
= (int) traceState
.getContext().getIdentifier(); // No need
307 Long cpu
= event
.getCpuId();
308 int cpus
= cpu
.intValue() | LttngConstants
.STATS_CPU_ID
;
309 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
310 int processName
= fPidKeys
.getUniqueId(process
.getPid().intValue(), process
.getName());
311 int mode
= process
.getState().getExec_mode().ordinal() | LttngConstants
.STATS_MODE_ID
;
312 int submode
= fSubModeKeys
.getUniqueId(process
.getState().getExec_submode_id(), process
.getState().getExec_submode());
313 int function
= process
.getCurrent_function().intValue() | LttngConstants
.STATS_FUNCTION_ID
;
316 * Note that it's faster to re-use the path object, set the relevant
317 * fields and clone the path later when it's time to add to the map
321 fNormalPaths
[0].set(0, trace
);
323 // FixedArray(trace,HEADER_MODES_INT,mode)
324 fNormalPaths
[1].set(0, trace
);
325 fNormalPaths
[1].set(2, mode
);
327 // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode)
328 fNormalPaths
[2].set(0, trace
);
329 fNormalPaths
[2].set(2, mode
);
330 fNormalPaths
[2].set(4, submode
);
332 // FixedArray(trace,HEADER_PROCESSES_INT,processName)
333 fNormalPaths
[3].set(0, trace
);
334 fNormalPaths
[3].set(2, processName
);
336 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus)
337 fNormalPaths
[4].set(0, trace
);
338 fNormalPaths
[4].set(2, processName
);
339 fNormalPaths
[4].set(4, cpus
);
341 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function)
342 fNormalPaths
[5].set(0, trace
);
343 fNormalPaths
[5].set(2, processName
);
344 fNormalPaths
[5].set(4, cpus
);
345 fNormalPaths
[5].set(6, function
);
347 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,
348 // HEADER_MODES_INT, mode)
349 fNormalPaths
[6].set(0, trace
);
350 fNormalPaths
[6].set(2, processName
);
351 fNormalPaths
[6].set(4, cpus
);
352 fNormalPaths
[6].set(6, function
);
353 fNormalPaths
[6].set(8, mode
);
355 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,
356 // HEADER_MODES_INT, mode, HEADER_SUBMODES_INT, submode)
357 fNormalPaths
[7].set(0, trace
);
358 fNormalPaths
[7].set(2, processName
);
359 fNormalPaths
[7].set(4, cpus
);
360 fNormalPaths
[7].set(6, function
);
361 fNormalPaths
[7].set(8, mode
);
362 fNormalPaths
[7].set(10, submode
);
364 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode)
365 fNormalPaths
[8].set(0, trace
);
366 fNormalPaths
[8].set(2, processName
);
367 fNormalPaths
[8].set(4, cpus
);
368 fNormalPaths
[8].set(6, mode
);
370 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode)
371 fNormalPaths
[9].set(0, trace
);
372 fNormalPaths
[9].set(2, processName
);
373 fNormalPaths
[9].set(4, cpus
);
374 fNormalPaths
[9].set(6, mode
);
375 fNormalPaths
[9].set(8, submode
);
377 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode)
378 fNormalPaths
[10].set(0, trace
);
379 fNormalPaths
[10].set(2, processName
);
380 fNormalPaths
[10].set(4, mode
);
382 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode)
383 fNormalPaths
[11].set(0, trace
);
384 fNormalPaths
[11].set(2, processName
);
385 fNormalPaths
[11].set(4, mode
);
386 fNormalPaths
[11].set(6, submode
);
388 // FixedArray(trace,HEADER_CPUS_INT,cpus)
389 fNormalPaths
[12].set(0, trace
);
390 fNormalPaths
[12].set(2, cpus
);
392 // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode)
393 fNormalPaths
[13].set(0, trace
);
394 fNormalPaths
[13].set(2, cpus
);
395 fNormalPaths
[13].set(4, mode
);
397 // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode)
398 fNormalPaths
[14].set(0, trace
);
399 fNormalPaths
[14].set(2, cpus
);
400 fNormalPaths
[14].set(4, mode
);
401 fNormalPaths
[14].set(6, submode
);
408 * <h4>Get the event types paths.</h4>
411 * Event to get the path for.
413 * State of the trace for this event.
414 * @return Array of FixedArray representing the paths.
416 private FixedArray
[] getTypePaths(LttngEvent event
, LttngTraceState traceState
) {
417 int trace
= (int) traceState
.getContext().getIdentifier(); // No need
422 Long cpu
= event
.getCpuId();
423 int cpus
= cpu
.intValue() | LttngConstants
.STATS_CPU_ID
;
424 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
425 int processName
= fPidKeys
.getUniqueId(process
.getPid().intValue(), process
.getName());
426 int mode
= process
.getState().getExec_mode().ordinal() | LttngConstants
.STATS_MODE_ID
;
427 int submode
= fSubModeKeys
.getUniqueId(process
.getState().getExec_submode_id(), process
.getState().getExec_submode());
428 int function
= process
.getCurrent_function().intValue() | LttngConstants
.STATS_FUNCTION_ID
;
429 int type
= fTypeKeys
.getUniqueId(event
.getMarkerId(), event
.getMarkerName());
432 * Note that it's faster to re-use the path object, set the relevant
433 * fields and clone the path later when it's time to add to the map
436 // FixedArray(trace,HEADER_EVENT_TYPES_INT,type)
437 fTypedPaths
[0].set(0, trace
);
438 fTypedPaths
[0].set(2, type
);
440 // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type)
441 fTypedPaths
[1].set(0, trace
);
442 fTypedPaths
[1].set(2, mode
);
443 fTypedPaths
[1].set(4, type
);
445 // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type)
446 fTypedPaths
[2].set(0, trace
);
447 fTypedPaths
[2].set(2, mode
);
448 fTypedPaths
[2].set(4, submode
);
449 fTypedPaths
[2].set(6, type
);
451 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_EVENT_TYPES_INT,type)
452 fTypedPaths
[3].set(0, trace
);
453 fTypedPaths
[3].set(2, processName
);
454 fTypedPaths
[3].set(4, type
);
456 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_EVENT_TYPES_INT,type)
457 fTypedPaths
[4].set(0, trace
);
458 fTypedPaths
[4].set(2, processName
);
459 fTypedPaths
[4].set(4, cpus
);
460 fTypedPaths
[4].set(6, type
);
462 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,HEADER_EVENT_TYPES_INT,type)
463 fTypedPaths
[5].set(0, trace
);
464 fTypedPaths
[5].set(2, processName
);
465 fTypedPaths
[5].set(4, cpus
);
466 fTypedPaths
[5].set(6, function
);
467 fTypedPaths
[5].set(8, type
);
469 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type)
470 fTypedPaths
[6].set(0, trace
);
471 fTypedPaths
[6].set(2, processName
);
472 fTypedPaths
[6].set(4, cpus
);
473 fTypedPaths
[6].set(6, function
);
474 fTypedPaths
[6].set(8, mode
);
475 fTypedPaths
[6].set(10, type
);
477 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,
478 // HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type)
479 fTypedPaths
[7].set(0, trace
);
480 fTypedPaths
[7].set(2, processName
);
481 fTypedPaths
[7].set(4, cpus
);
482 fTypedPaths
[7].set(6, function
);
483 fTypedPaths
[7].set(8, mode
);
484 fTypedPaths
[7].set(10, submode
);
485 fTypedPaths
[7].set(12, type
);
487 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type)
488 fTypedPaths
[8].set(0, trace
);
489 fTypedPaths
[8].set(2, processName
);
490 fTypedPaths
[8].set(4, cpus
);
491 fTypedPaths
[8].set(6, mode
);
492 fTypedPaths
[8].set(8, type
);
494 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type)
495 fTypedPaths
[9].set(0, trace
);
496 fTypedPaths
[9].set(2, processName
);
497 fTypedPaths
[9].set(4, cpus
);
498 fTypedPaths
[9].set(6, mode
);
499 fTypedPaths
[9].set(8, submode
);
500 fTypedPaths
[9].set(10, type
);
502 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type)
503 fTypedPaths
[10].set(0, trace
);
504 fTypedPaths
[10].set(2, processName
);
505 fTypedPaths
[10].set(4, mode
);
506 fTypedPaths
[10].set(6, type
);
508 // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type)
509 fTypedPaths
[11].set(0, trace
);
510 fTypedPaths
[11].set(2, processName
);
511 fTypedPaths
[11].set(4, mode
);
512 fTypedPaths
[11].set(6, submode
);
513 fTypedPaths
[11].set(8, type
);
515 // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_EVENT_TYPES_INT,type)
516 fTypedPaths
[12].set(0, trace
);
517 fTypedPaths
[12].set(2, cpus
);
518 fTypedPaths
[12].set(4, type
);
520 // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type)
521 fTypedPaths
[13].set(0, trace
);
522 fTypedPaths
[13].set(2, cpus
);
523 fTypedPaths
[13].set(4, mode
);
524 fTypedPaths
[13].set(6, type
);
526 // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type)
527 fTypedPaths
[14].set(0, trace
);
528 fTypedPaths
[14].set(2, cpus
);
529 fTypedPaths
[14].set(4, mode
);
530 fTypedPaths
[14].set(6, submode
);
531 fTypedPaths
[14].set(8, type
);
540 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
541 * #process_exit(org.eclipse.linuxtools.lttng.event.LttngEvent,
542 * org.eclipse.linuxtools.lttng.state.model.LttngTraceState)
545 public void process_exit(LttngEvent event
, LttngTraceState traceState
) {
546 FixedArray
[] paths
= getNormalPaths(event
, traceState
);
547 Long cpu
= event
.getCpuId();
548 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
550 for (int j
= 0; j
< paths
.length
; ++j
) {
551 StatisticsTreeNode node
= getOrCreate(paths
[j
], event
, traceState
, j
, false);
553 if (!process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
554 node
.getValue().cpuTime
+= event
.getTimestamp().getValue() - process
.getState().getChange_LttTime();
557 // TODO Unstacks cumulative CPU time
558 // TODO Elapsed time?
565 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
566 * #increase(org.eclipse.linuxtools.lttng.event.LttngEvent,
567 * org.eclipse.linuxtools.lttng.state.model.LttngTraceState, int)
570 public void increase(LttngEvent event
, LttngTraceState traceState
, int values
) {
571 FixedArray
[] paths
= getNormalPaths(event
, traceState
);
572 Long cpu
= event
.getCpuId();
573 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
575 for (int j
= 0; j
< paths
.length
; ++j
) {
576 StatisticsTreeNode node
= getOrCreate(paths
[j
], event
, traceState
, j
, false);
578 if ((values
& Values
.CPU_TIME
) != 0) {
579 // TODO Uncomment if the event after process_exit need to be
581 if ((process
.getState().getProc_status().equals(ProcessStatus
.LTTV_STATE_RUN
) /*
599 */) && !process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
600 node
.getValue().cpuTime
+= event
.getTimestamp().getValue() - process
.getState().getChange_LttTime();
603 if ((values
& Values
.CUMULATIVE_CPU_TIME
) != 0) {
604 if (!process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
605 long cumulativeCpuTime
= process
.getState().getCum_cpu_time();
606 long delta
= event
.getTimestamp().getValue() - process
.getState().getEntry_LttTime();
607 process
.getState().setCum_cpu_time(cumulativeCpuTime
+ delta
);
608 node
.getValue().cumulativeCpuTime
+= process
.getState().getCum_cpu_time();
609 } else if (process
.getState().getProc_status().equals(ProcessStatus
.LTTV_STATE_RUN
) && !process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
610 long cumulativeCpuTime
= process
.getState().getCum_cpu_time();
611 long delta
= event
.getTimestamp().getValue() - process
.getState().getChange_LttTime();
612 process
.getState().setCum_cpu_time(cumulativeCpuTime
+ delta
);
613 node
.getValue().cumulativeCpuTime
+= process
.getState().getCum_cpu_time();
616 if ((values
& Values
.ELAPSED_TIME
) != 0) {
617 if (!process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
618 node
.getValue().elapsedTime
+= event
.getTimestamp().getValue() - process
.getState().getEntry_LttTime();
621 if ((values
& Values
.STATE_CUMULATIVE_CPU_TIME
) != 0) {
622 if (process
.getState().getProc_status().equals(ProcessStatus
.LTTV_STATE_RUN
) && !process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
623 long cumulativeCpuTime
= process
.getState().getCum_cpu_time();
624 long delta
= event
.getTimestamp().getValue() - process
.getState().getChange_LttTime();
625 process
.getState().setCum_cpu_time(cumulativeCpuTime
+ delta
);
635 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
636 * #registerEvent(org.eclipse.linuxtools.lttng.event.LttngEvent,
637 * org.eclipse.linuxtools.lttng.state.model.LttngTraceState)
640 public void registerEvent(LttngEvent event
, LttngTraceState traceState
) {
641 FixedArray
[] paths
= getNormalPaths(event
, traceState
);
642 for (int i
= 0; i
< paths
.length
; ++i
)
643 ++(getOrCreate(paths
[i
], event
, traceState
, i
, false).getValue().nbEvents
);
645 paths
= getTypePaths(event
, traceState
);
646 for (int i
= 0; i
< paths
.length
; ++i
)
647 ++(getOrCreate(paths
[i
], event
, traceState
, i
, true).getValue().nbEvents
);
649 // last_ = event; // TODO Used by endTraceset
656 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
658 * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray)
661 protected void registerName(final FixedArray path
) {
662 if (path
.size() == 1) {
663 if (!path
.equals(ROOT
))
664 getKeys().get(ROOT
.get(0)).add(path
.get(0));
665 } else if (path
.size() % 2 != 0)
666 getKeys().get(path
.get(path
.size() - 2)).add(path
.get(path
.size() - 1));
670 * <h4>Get or create a node.</h4>
677 * The current trace state
679 * The corresponding index of the statistic
681 * The type of statistic (type or other)
684 public StatisticsTreeNode
getOrCreate(final FixedArray path
, LttngEvent event
, LttngTraceState traceState
, int index
, boolean isType
) {
685 StatisticsTreeNode current
= get(path
);
686 if (current
== null) {
687 // We have to clone the path since the object for the path is
688 // re-used for performance reasons!
689 FixedArray newPath
= (FixedArray
) path
.clone();
691 // Note that setting of the name is done here only when the node is
692 // created (for performance reasons).
693 String name
= (isType
) ?
getTypeStatsName(event
, traceState
, index
) : getOtherStatsName(event
, traceState
, index
);
695 current
= new StatisticsTreeNode(newPath
, this, name
);
696 put(newPath
, current
);
702 * <h4>Get the name to be displayed for other statistics than type
708 * The current trace state
710 * corresponding index of the statistic
713 private String
getOtherStatsName(LttngEvent event
, LttngTraceState traceState
, int index
) {
714 Long cpu
= event
.getCpuId();
715 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
719 return traceState
.getContext().getTraceId();
721 return process
.getState().getExec_mode().getInName();
723 return process
.getState().getExec_submode();
725 return getProcessName(process
);
727 return String
.valueOf(cpu
);
729 return process
.getCurrent_function().toString();
731 return process
.getState().getExec_mode().getInName();
733 return process
.getState().getExec_submode();
735 return process
.getState().getExec_mode().getInName();
737 return process
.getState().getExec_submode();
739 return process
.getState().getExec_mode().getInName();
741 return process
.getState().getExec_submode();
743 return String
.valueOf(cpu
);
745 return process
.getState().getExec_mode().getInName();
747 return process
.getState().getExec_submode();
749 return ""; //$NON-NLS-1$
754 * <h4>Get the name to be displayed for type statistics</h4>
761 * The corresponding index of the statistic
762 * @return The strings in a array
764 private String
getTypeStatsName(LttngEvent event
, LttngTraceState traceState
, int index
) {
765 return event
.getMarkerName();
769 * <h4>Get the name of a process.</h4>
773 * @return The name of the process. //TODO Adding the creation time of the
774 * process may be needed to differentiate two process.
776 private String
getProcessName(LttngProcessState process
) {
777 if (process
.getPid() == -1)
778 return Messages
.StatisticsData_UnknowProcess
;
779 if (process
.getName() == null)
780 return mergeString(Messages
.StatisticsData_UnknowProcess
+ " - ", String
.valueOf(process
.getPid())); //$NON-NLS-1$
781 if (process
.getName().equals("")) //$NON-NLS-1$
782 return process
.getPid().toString();
784 return mergeString(process
.getName(), " - ", String
.valueOf(process
.getPid())); //$NON-NLS-1$
788 * <h4>Converts the integer representation of the category to string.</h4>
791 * Integer representation of the category.
792 * @return Category as string.
794 public static String
getCategoryFromId(int value
) {
796 case KernelStatisticsData
.HEADER_CPUS_INT
:
797 return KernelStatisticsData
.HEADER_CPUS
;
798 case KernelStatisticsData
.HEADER_EVENT_TYPES_INT
:
799 return KernelStatisticsData
.HEADER_EVENT_TYPES
;
800 case KernelStatisticsData
.HEADER_FUNCTIONS_INT
:
801 return KernelStatisticsData
.HEADER_FUNCTIONS
;
802 case KernelStatisticsData
.HEADER_MODES_INT
:
803 return KernelStatisticsData
.HEADER_MODES
;
804 case KernelStatisticsData
.HEADER_PROCESSES_INT
:
805 return KernelStatisticsData
.HEADER_PROCESSES
;
806 case KernelStatisticsData
.HEADER_SUBMODES_INT
:
807 return KernelStatisticsData
.HEADER_SUBMODES
;
809 return ""; //$NON-NLS-1$
813 * <h4>Provides unique keys for String - Integer pairs.</h4>
818 final private class KeyProvider
{
821 * <h4>Instance counter for unique ID generation.</h4>
823 private int fCount
= 0;
826 * <h4>Attributes to generate unique IDs for processes.</h4>
828 private HashMap
<KeyHelper
, Integer
> fKeyMap
= new HashMap
<KeyHelper
, Integer
>(65535);
829 private final KeyHelper fHelper
= new KeyHelper();
832 * <h4>Bit mask to apply for the key.</h4>
834 private int fBitMask
= 0;
840 * <h4>Bit mask to apply for the key.</h4>
842 KeyProvider(int bitMask
) {
843 this.fBitMask
= bitMask
;
847 * <h4>Standard Constructor</h4>
854 * <h4>Creates unique id for the given input data.</h4>
857 * Integer value of the data the key is for
859 * Name of the data the key is for
861 * Helper class instance for the data the key is for
863 * The map the keys are tracked
865 * The bit mask to apply for the key
869 public int getUniqueId(int value
, String name
) {
870 fHelper
.setName(name
);
871 fHelper
.setValue(value
);
873 Integer returnKey
= fKeyMap
.get(fHelper
);
874 if (returnKey
== null) {
875 returnKey
= Integer
.valueOf((++fCount
) | fBitMask
);
876 KeyHelper newHelper
= fHelper
.clone();
877 fKeyMap
.put(newHelper
, returnKey
);
879 return returnKey
.intValue();
884 <h4>Helper class that provides keys for HashMaps depending on an integer
885 * - string -pair. It provides better performance than using a string as key
886 * only. However, for optimal performance the integer values should be mostly
892 private class KeyHelper
implements Cloneable
{
895 private final static String UNKNOWN_PREFIX
= "P"; //$NON-NLS-1$
897 private String fName
= UNKNOWN_PREFIX
;
898 private int fValue
= -1;
903 * @see java.lang.Object#hashCode()
906 public int hashCode() {
913 * @see java.lang.Object#equals(java.lang.Object)
916 public boolean equals(Object o
) {
917 if (fValue
== ((KeyHelper
) o
).fValue
&& fName
.equals(((KeyHelper
) o
).fName
)) {
926 * @see java.lang.Object#clone()
929 public KeyHelper
clone() {
930 KeyHelper clone
= null;
932 clone
= (KeyHelper
) super.clone();
934 clone
.fValue
= fValue
;
935 } catch (CloneNotSupportedException e
) {
942 * <h4>Set the name of the key.</h4>
947 public void setName(String name
) {
951 this.fName
= UNKNOWN_PREFIX
;
955 * <h4>Set the value of the key.</h4>
959 public void setValue(int value
) {