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
.Events
;
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
;
31 * <h4>Class that process the LTTng kernel events.</h4>
33 public class KernelStatisticsData
extends StatisticsData
{
35 * <h4>Header for the CPU categories.</h4>
37 public static final String HEADER_CPUS
= Messages
.KernelStatisticsData_CPUs
;
38 public static final int HEADER_CPUS_INT
= 256 | LttngConstants
.STATS_CATEGORY_ID
;
40 * <h4>Header for the event types categories.</h4>
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
;
45 * <h4>Header for the function categories.</h4>
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
;
50 * <h4>Header for the mode categories.</h4>
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
;
55 * <h4>Header for the processes categories.</h4>
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
;
60 * <h4>Header for the submode categories.</h4>
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
;
66 * <h4>Class to generate unique IDs for processes.</h4>
68 private ProcessKeyProvider fPidKeys
= new ProcessKeyProvider(LttngConstants
.STATS_PROCESS_ID
);
71 * <h4>Class to generate unique Ids for event types.</h4>
73 private KeyProvider fTypeKeys
= new KeyProvider(LttngConstants
.STATS_TYPE_ID
);
75 * <h4>Class to generate unique Ids for subModes.</h4>
77 private KeyProvider fSubModeKeys
= new KeyProvider();
80 * <h4>Place Holder in path.</h4>
82 private static final int PLACE_HOLDER
= 0;
85 * For performance reason the following algorithm is applied to the paths:
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).
94 * <h4>Pre-created paths for type statistics, which will be filled for each
95 * relevant event.</h4>
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
), };
111 * <h4>Pre-created paths for other statistics, which will be filled for each
112 * relevant event.</h4>
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
), };
126 * <h4>Indicate that it's a value.</h4>
128 * Used when checking the possible child node for a node.
131 * It differentiate a category of a value by being appended to a value.
134 private static final Integer NODE
= -1;
135 private static final Integer ROOT_NODE_KEY
= -2;
138 * <h4>Constructor.</h4>
142 public KernelStatisticsData(String traceName
) {
144 Map
<Integer
, Set
<Integer
>> keys
= getKeys();
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
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
156 // /////////// Adding value sets
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
);
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
);
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
);
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
);
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
);
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$
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)
208 public void endTraceset(LttngEvent event
, LttngTraceState traceState
) {
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.
215 * if(last_ == null) return;
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
233 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
235 * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray)
238 public Collection
<StatisticsTreeNode
> getChildren(final FixedArray path
) {
239 LinkedList
<StatisticsTreeNode
> result
= new LinkedList
<StatisticsTreeNode
>();
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)
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
)));
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
));
259 } else {// If we are at a value
260 for (int value
: getKeys().get((path
.get(path
.size() - 2) * NODE
))) { // Search
266 StatisticsTreeNode node
= getOrCreate(path
.append(value
));
267 node
.setName(getCategoryFromId(value
));
271 if (path
.size() == 5 && path
.get(3) == HEADER_CPUS_INT
) { // Special
284 StatisticsTreeNode node
= getOrCreate(path
.append(HEADER_FUNCTIONS_INT
));
285 node
.setName(getCategoryFromId(HEADER_FUNCTIONS_INT
));
294 * <h4>Get the standard paths for an event.</h4>
297 * Event to get the path for.
299 * State of the trace for this event.
300 * @return Array of FixedArray representing the paths.
302 private FixedArray
[] getNormalPaths(LttngEvent event
, LttngTraceState traceState
) {
303 int trace
= (int) traceState
.getContext().getIdentifier(); // No need
308 Long cpu
= event
.getCpuId();
309 int cpus
= cpu
.intValue() | LttngConstants
.STATS_CPU_ID
;
310 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
311 int processName
= fPidKeys
.getUniqueId(process
.getPid().intValue(), process
.getCpu().intValue(), process
.getCreation_time());
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
;
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
322 fNormalPaths
[0].set(0, trace
);
324 // FixedArray(trace,HEADER_MODES_INT,mode)
325 fNormalPaths
[1].set(0, trace
);
326 fNormalPaths
[1].set(2, mode
);
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
);
333 // FixedArray(trace,HEADER_PROCESSES_INT,processName)
334 fNormalPaths
[3].set(0, trace
);
335 fNormalPaths
[3].set(2, processName
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
389 // FixedArray(trace,HEADER_CPUS_INT,cpus)
390 fNormalPaths
[12].set(0, trace
);
391 fNormalPaths
[12].set(2, cpus
);
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
);
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
);
409 * <h4>Get the event types paths.</h4>
412 * Event to get the path for.
414 * State of the trace for this event.
415 * @return Array of FixedArray representing the paths.
417 private FixedArray
[] getTypePaths(LttngEvent event
, LttngTraceState traceState
) {
418 int trace
= (int) traceState
.getContext().getIdentifier(); // No need
423 Long cpu
= event
.getCpuId();
424 int cpus
= cpu
.intValue() | LttngConstants
.STATS_CPU_ID
;
425 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
426 int processName
= fPidKeys
.getUniqueId(process
.getPid().intValue(), process
.getCpu().intValue(), process
.getCreation_time());
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());
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
437 // FixedArray(trace,HEADER_EVENT_TYPES_INT,type)
438 fTypedPaths
[0].set(0, trace
);
439 fTypedPaths
[0].set(2, type
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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)
546 public void process_exit(LttngEvent event
, LttngTraceState traceState
) {
547 FixedArray
[] paths
= getNormalPaths(event
, traceState
);
548 Long cpu
= event
.getCpuId();
549 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
551 for (int j
= 0; j
< paths
.length
; ++j
) {
552 StatisticsTreeNode node
= getOrCreate(paths
[j
], event
, traceState
, j
, false);
554 if (!process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
555 node
.getValue().cpuTime
+= event
.getTimestamp().getValue() - process
.getState().getChange_LttTime();
558 // TODO Unstacks cumulative CPU time
559 // TODO Elapsed time?
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)
571 public void increase(LttngEvent event
, LttngTraceState traceState
, int values
) {
572 FixedArray
[] paths
= getNormalPaths(event
, traceState
);
573 Long cpu
= event
.getCpuId();
574 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
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
);
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
);
598 for (int j
= 0; j
< paths
.length
; ++j
) {
599 StatisticsTreeNode node
= getOrCreate(paths
[j
], event
, traceState
, j
, false);
601 if ((values
& Values
.CPU_TIME
) != 0) {
602 // TODO Uncomment if the event after process_exit need to be
604 if ((process
.getState().getProc_status().equals(ProcessStatus
.LTTV_STATE_RUN
) /*
605 * || process.getState().
607 * ().equals(ProcessStatus
609 */) && !process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
610 node
.getValue().cpuTime
+= event
.getTimestamp().getValue() - process
.getState().getChange_LttTime();
613 if ((values
& Values
.CUMULATIVE_CPU_TIME
) != 0) {
614 if (!process
.getState().getExec_mode().equals(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
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
)) {
617 node
.getValue().cumulativeCpuTime
+= process
.getState().getCum_cpu_time();
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();
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)
637 public void registerEvent(LttngEvent event
, LttngTraceState traceState
) {
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
);
642 paths
= getTypePaths(event
, traceState
);
643 for (int i
= 0; i
< paths
.length
; ++i
)
644 ++(getOrCreate(paths
[i
], event
, traceState
, i
, true).getValue().nbEvents
);
646 // last_ = event; // TODO Used by endTraceset
653 * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData
655 * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray)
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));
667 * <h4>Get or create a node.</h4>
674 * The current trace state
676 * The corresponding index of the statistic
678 * The type of statistic (type or other)
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();
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
);
692 current
= new StatisticsTreeNode(newPath
, this, name
);
693 put(newPath
, current
);
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
);
707 * <h4>Get the name to be displayed for other statistics than type
713 * The current trace state
715 * corresponding index of the statistic
718 private String
getOtherStatsName(LttngEvent event
, LttngTraceState traceState
, int index
) {
719 Long cpu
= event
.getCpuId();
720 LttngProcessState process
= traceState
.getRunning_process().get(cpu
);
724 return traceState
.getContext().getTraceId();
726 return process
.getState().getExec_mode().getInName();
728 return process
.getState().getExec_submode();
730 return getProcessName(process
);
732 return String
.valueOf(cpu
);
734 return process
.getCurrent_function().toString();
736 return process
.getState().getExec_mode().getInName();
738 return process
.getState().getExec_submode();
740 return process
.getState().getExec_mode().getInName();
742 return process
.getState().getExec_submode();
744 return process
.getState().getExec_mode().getInName();
746 return process
.getState().getExec_submode();
748 return String
.valueOf(cpu
);
750 return process
.getState().getExec_mode().getInName();
752 return process
.getState().getExec_submode();
754 return ""; //$NON-NLS-1$
759 * <h4>Get the name to be displayed for type statistics</h4>
766 * The corresponding index of the statistic
767 * @return The strings in a array
769 private String
getTypeStatsName(LttngEvent event
, LttngTraceState traceState
, int index
) {
770 return event
.getMarkerName();
774 * <h4>Get the name of a process.</h4>
778 * @return The name of the process. //TODO Adding the creation time of the
779 * process may be needed to differentiate two process.
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();
789 return mergeString(process
.getName(), " - ", String
.valueOf(process
.getPid())); //$NON-NLS-1$
793 * <h4>Converts the integer representation of the category to string.</h4>
796 * Integer representation of the category.
797 * @return Category as string.
799 public static String
getCategoryFromId(int 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
;
814 return ""; //$NON-NLS-1$
818 * <h4>Provides unique keys for String - Integer pairs.</h4>
823 final private class KeyProvider
{
826 * <h4>Instance counter for unique ID generation.</h4>
828 private int fCount
= 0;
831 * <h4>Attributes to generate unique IDs for processes.</h4>
833 private HashMap
<KeyHelper
, Integer
> fKeyMap
= new HashMap
<KeyHelper
, Integer
>(65535);
834 private final KeyHelper fHelper
= new KeyHelper();
837 * <h4>Bit mask to apply for the key.</h4>
839 private int fBitMask
= 0;
845 * <h4>Bit mask to apply for the key.</h4>
847 KeyProvider(int bitMask
) {
848 this.fBitMask
= bitMask
;
852 * <h4>Standard Constructor</h4>
859 * <h4>Creates unique id for the given input data.</h4>
862 * Integer value of the data the key is for
864 * Name of the data the key is for
867 public int getUniqueId(int value
, String name
) {
868 fHelper
.setName(name
);
869 fHelper
.setValue(value
);
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
);
877 return returnKey
.intValue();
882 <h4>Helper class that provides keys for HashMaps depending on an integer
883 * - string -pair. It provides better performance than using a string as key
884 * only. However, for optimal performance the integer values should be mostly
890 private class KeyHelper
implements Cloneable
{
893 private final static String UNKNOWN_PREFIX
= "P"; //$NON-NLS-1$
895 private String fName
= UNKNOWN_PREFIX
;
896 private int fValue
= -1;
901 * @see java.lang.Object#hashCode()
904 public int hashCode() {
911 * @see java.lang.Object#equals(java.lang.Object)
914 public boolean equals(Object o
) {
915 if (fValue
== ((KeyHelper
) o
).fValue
&& fName
.equals(((KeyHelper
) o
).fName
)) {
924 * @see java.lang.Object#clone()
927 public KeyHelper
clone() {
928 KeyHelper clone
= null;
930 clone
= (KeyHelper
) super.clone();
932 clone
.fValue
= fValue
;
933 } catch (CloneNotSupportedException e
) {
940 * <h4>Set the name of the key.</h4>
945 public void setName(String name
) {
949 this.fName
= UNKNOWN_PREFIX
;
953 * <h4>Set the value of the key.</h4>
957 public void setValue(int value
) {
963 * <h4>Provides unique keys for given process information. For optimal performance the integer
964 * PIDs need to be mostly unique</h4>
969 final private class ProcessKeyProvider
{
971 * <h4>Instance counter for unique ID generation.</h4>
973 private int fCount
= 0;
976 * <h4>Attributes to generate unique IDs for processes.</h4>
978 private HashMap
<ProcessKey
, Integer
> fKeyMap
= new HashMap
<ProcessKey
, Integer
>(65535);
979 private ProcessKey fHelper
= new ProcessKey();
982 * <h4>Bit mask to apply for the key.</h4>
984 private int fBitMask
= 0;
990 * <h4>Bit mask to apply for the key.</h4>
992 public ProcessKeyProvider(int bitMask
) {
997 * <h4>Creates unique id for the given input data.</h4>
1000 * Integer value of the data the key is for
1002 * The cpuId for the processKey Helper
1003 * @param creationTime
1004 * The creation Time for the processKey Helper
1007 public int getUniqueId(int value
, int cpuId
, long creationTime
) {
1008 fHelper
.setPid(value
);
1009 fHelper
.setCpuId(cpuId
);
1010 fHelper
.setCreationTime(creationTime
);
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
);
1018 return returnKey
.intValue();
1023 <h4>Helper class that provides keys for HashMaps depending on process information.</h4>
1028 final class ProcessKey
implements Cloneable
{
1029 private int fPid
= 0;
1030 private int fCpuId
= 0;
1031 private long fCreationTime
= 0;
1034 * <h4>Set the PID of the key.</h4>
1038 public void setPid(int pid
) {
1043 * <h4>Set the cpuTime of the process key.</h4>
1048 public void setCpuId(int cpuId
) {
1049 this.fCpuId
= cpuId
;
1053 * <h4>Set the creationTime of the process key.</h4>
1055 * @param creationTime
1058 public void setCreationTime(long creationTime
) {
1059 this.fCreationTime
= creationTime
;
1064 * @see java.lang.Object#equals(java.lang.Object)
1067 public boolean equals(Object obj
) {
1068 ProcessKey procKey
= (ProcessKey
) obj
;
1070 if (procKey
.fPid
!= this.fPid
) {
1074 if (procKey
.fCreationTime
!= this.fCreationTime
) {
1078 // use the cpu value to validate pid 0
1079 if (((procKey
.fPid
== 0L) && (procKey
.fCpuId
!= this.fCpuId
))) {
1087 * @see java.lang.Object#hashCode()
1090 public int hashCode() {
1096 * @see java.lang.Object#clone()
1099 public ProcessKey
clone() {
1100 ProcessKey clone
= null;
1102 clone
= (ProcessKey
) super.clone();
1104 clone
.fCpuId
= fCpuId
;
1105 clone
.fCreationTime
= fCreationTime
;
1106 } catch (CloneNotSupportedException e
) {
1107 e
.printStackTrace();