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