1 /*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
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 * François Rajotte - Initial API and implementation
11 * Geneviève Bastien - Revision of the initial implementation
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.lttng2
.kernel
.core
.cpuusage
;
16 import java
.util
.HashMap
;
19 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.Activator
;
20 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.Attributes
;
21 import org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.core
.LttngStrings
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.AbstractTmfStateProvider
;
28 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
31 * Creates a state system with the total time spent on CPU for each thread and
32 * for each CPU from a kernel trace.
34 * This state system in itself keeps the total time on CPU since last time the
35 * process was scheduled out. The state system queries will only be accurate
36 * when the process is not in a running state. To have exact CPU usage when
37 * running, this state system needs to be used along the LTTng Kernel analysis.
39 * It requires only the 'sched_switch' events enabled on the trace.
41 * @author François Rajotte
44 public class LttngKernelCpuStateProvider
extends AbstractTmfStateProvider
{
46 private static final int VERSION
= 1;
48 /* For each CPU, maps the last time a thread was scheduled in */
49 private final Map
<String
, Long
> fLastStartTimes
= new HashMap
<>();
50 private final long fTraceStart
;
56 * The trace from which to get the CPU usage
58 public LttngKernelCpuStateProvider(ITmfTrace trace
) {
59 super(trace
, ITmfEvent
.class, "LTTng Kernel CPU usage"); //$NON-NLS-1$
60 fTraceStart
= trace
.getStartTime().getValue();
63 // ------------------------------------------------------------------------
65 // ------------------------------------------------------------------------
68 public int getVersion() {
73 public LttngKernelCpuStateProvider
getNewInstance() {
74 return new LttngKernelCpuStateProvider(this.getTrace());
78 protected void eventHandle(ITmfEvent event
) {
79 final String eventName
= event
.getType().getName();
81 if (eventName
.equals(LttngStrings
.SCHED_SWITCH
)) {
83 * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64
84 * prev_state, string next_comm, int32 next_tid, int32 next_prio
87 ITmfEventField content
= event
.getContent();
88 long ts
= event
.getTimestamp().getValue();
89 String cpu
= event
.getSource();
91 Long prevTid
= (Long
) content
.getField(LttngStrings
.PREV_TID
).getValue();
94 Integer currentCPUNode
= ss
.getQuarkRelativeAndAdd(getNodeCPUs(), cpu
);
97 * This quark contains the value of the cumulative time spent on
98 * the source CPU by the currently running thread
100 Integer cumulativeTimeQuark
= ss
.getQuarkRelativeAndAdd(currentCPUNode
, prevTid
.toString());
101 Long startTime
= fLastStartTimes
.get(cpu
);
103 * If start time is null, we haven't seen the start of the
104 * process, so we assume beginning of the trace
106 if (startTime
== null) {
107 startTime
= fTraceStart
;
111 * We add the time from startTime until now to the cumulative
114 if (startTime
!= null) {
115 ITmfStateValue value
= ss
.queryOngoingState(cumulativeTimeQuark
);
118 * Modify cumulative time for this CPU/TID combo: The total
119 * time changes when the process is scheduled out. Nothing
120 * happens when the process is scheduled in.
122 long prevCumulativeTime
= value
.unboxLong();
123 long newCumulativeTime
= prevCumulativeTime
+ (ts
- startTime
);
125 value
= TmfStateValue
.newValueLong(newCumulativeTime
);
126 ss
.modifyAttribute(ts
, value
, cumulativeTimeQuark
);
127 fLastStartTimes
.put(cpu
, ts
);
129 } catch (AttributeNotFoundException e
) {
130 Activator
.getDefault().logError("Attribute not found in LttngKernelCpuStateProvider", e
); //$NON-NLS-1$
136 /* Shortcut for the "current CPU" attribute node */
137 private int getNodeCPUs() {
138 return ss
.getQuarkAbsoluteAndAdd(Attributes
.CPUS
);