tmf: Null-annotate state system API classes
[deliverable/tracecompass.git] / org.eclipse.tracecompass.lttng2.kernel.core / src / org / eclipse / tracecompass / lttng2 / kernel / core / analysis / cpuusage / LttngKernelCpuUsageStateProvider.java
CommitLineData
e693075d
FR
1/*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
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 * François Rajotte - Initial API and implementation
11 * Geneviève Bastien - Revision of the initial implementation
12 *******************************************************************************/
13
42d5b5f2 14package org.eclipse.tracecompass.lttng2.kernel.core.analysis.cpuusage;
e693075d 15
d0c7e4ba
AM
16import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
e693075d
FR
18import java.util.HashMap;
19import java.util.Map;
20
7411cd67 21import org.eclipse.jdt.annotation.NonNull;
9bc60be7
AM
22import org.eclipse.tracecompass.internal.lttng2.kernel.core.Activator;
23import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
7411cd67 24import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
d0c7e4ba 25import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
e894a508
AM
26import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
27import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
28import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
29import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
30import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
1786026d 31import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
2bdf0193
AM
32import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
33import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
1786026d 34import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
e693075d
FR
35
36/**
37 * Creates a state system with the total time spent on CPU for each thread and
38 * for each CPU from a kernel trace.
39 *
40 * This state system in itself keeps the total time on CPU since last time the
41 * process was scheduled out. The state system queries will only be accurate
42 * when the process is not in a running state. To have exact CPU usage when
43 * running, this state system needs to be used along the LTTng Kernel analysis.
44 *
45 * It requires only the 'sched_switch' events enabled on the trace.
46 *
47 * @author François Rajotte
48 * @since 3.0
49 */
42d5b5f2 50public class LttngKernelCpuUsageStateProvider extends AbstractTmfStateProvider {
e693075d 51
96811390 52 private static final int VERSION = 2;
e693075d
FR
53
54 /* For each CPU, maps the last time a thread was scheduled in */
1786026d 55 private final Map<Integer, Long> fLastStartTimes = new HashMap<>();
e693075d 56 private final long fTraceStart;
7411cd67 57 private final @NonNull IKernelAnalysisEventLayout fLayout;
e693075d
FR
58
59 /**
60 * Constructor
61 *
62 * @param trace
63 * The trace from which to get the CPU usage
7411cd67
AM
64 * @param layout
65 * The event layout to use for this state provider.
e693075d 66 */
d0c7e4ba
AM
67 public LttngKernelCpuUsageStateProvider(@NonNull ITmfTrace trace,
68 @NonNull IKernelAnalysisEventLayout layout) {
e693075d
FR
69 super(trace, ITmfEvent.class, "LTTng Kernel CPU usage"); //$NON-NLS-1$
70 fTraceStart = trace.getStartTime().getValue();
7411cd67 71 fLayout = layout;
e693075d
FR
72 }
73
74 // ------------------------------------------------------------------------
75 // ITmfStateProvider
76 // ------------------------------------------------------------------------
77
78 @Override
79 public int getVersion() {
80 return VERSION;
81 }
82
83 @Override
42d5b5f2 84 public LttngKernelCpuUsageStateProvider getNewInstance() {
7411cd67 85 return new LttngKernelCpuUsageStateProvider(this.getTrace(), this.fLayout);
e693075d
FR
86 }
87
88 @Override
1786026d 89 protected void eventHandle(ITmfEvent event) {
d0c7e4ba 90 final ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
e693075d
FR
91 final String eventName = event.getType().getName();
92
7411cd67 93 if (eventName.equals(fLayout.eventSchedSwitch())) {
1786026d
GB
94 Integer cpu = null;
95 Iterable<TmfCpuAspect> aspects = TmfTraceUtils.getEventAspectsOfClass(event.getTrace(), TmfCpuAspect.class);
96 for (TmfCpuAspect aspect : aspects) {
97 if (!aspect.resolve(event).equals(TmfCpuAspect.CPU_UNAVAILABLE)) {
98 cpu = aspect.resolve(event);
99 break;
100 }
101 }
102 if (cpu == null) {
103 /* We couldn't find any CPU information, ignore this event */
104 return;
105 }
106
e693075d
FR
107 /*
108 * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64
109 * prev_state, string next_comm, int32 next_tid, int32 next_prio
110 */
e693075d
FR
111 ITmfEventField content = event.getContent();
112 long ts = event.getTimestamp().getValue();
e693075d 113
7411cd67 114 Long prevTid = (Long) content.getField(fLayout.fieldPrevTid()).getValue();
e693075d
FR
115
116 try {
d0c7e4ba 117 Integer currentCPUNode = ss.getQuarkRelativeAndAdd(getNodeCPUs(ss), cpu.toString());
e693075d
FR
118
119 /*
120 * This quark contains the value of the cumulative time spent on
121 * the source CPU by the currently running thread
122 */
123 Integer cumulativeTimeQuark = ss.getQuarkRelativeAndAdd(currentCPUNode, prevTid.toString());
124 Long startTime = fLastStartTimes.get(cpu);
125 /*
126 * If start time is null, we haven't seen the start of the
127 * process, so we assume beginning of the trace
128 */
129 if (startTime == null) {
130 startTime = fTraceStart;
131 }
132
133 /*
134 * We add the time from startTime until now to the cumulative
135 * time of the thread
136 */
137 if (startTime != null) {
138 ITmfStateValue value = ss.queryOngoingState(cumulativeTimeQuark);
139
140 /*
141 * Modify cumulative time for this CPU/TID combo: The total
142 * time changes when the process is scheduled out. Nothing
143 * happens when the process is scheduled in.
144 */
96811390 145 long prevCumulativeTime = Math.max(0, value.unboxLong());
e693075d
FR
146 long newCumulativeTime = prevCumulativeTime + (ts - startTime);
147
148 value = TmfStateValue.newValueLong(newCumulativeTime);
149 ss.modifyAttribute(ts, value, cumulativeTimeQuark);
150 fLastStartTimes.put(cpu, ts);
151 }
152 } catch (AttributeNotFoundException e) {
153 Activator.getDefault().logError("Attribute not found in LttngKernelCpuStateProvider", e); //$NON-NLS-1$
154 }
155
156 }
157 }
158
159 /* Shortcut for the "current CPU" attribute node */
d0c7e4ba
AM
160 private static int getNodeCPUs(ITmfStateSystemBuilder ssb) {
161 return ssb.getQuarkAbsoluteAndAdd(Attributes.CPUS);
e693075d
FR
162 }
163
164}
This page took 0.042898 seconds and 5 git commands to generate.