Build using a target definition file
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.ui / src / org / eclipse / linuxtools / internal / lttng2 / kernel / ui / views / cpuusage / CpuUsageComposite.java
CommitLineData
dffc234f
GB
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 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.cpuusage;
14
15import java.util.ArrayList;
16import java.util.HashMap;
17import java.util.List;
18import java.util.Map;
19import java.util.Map.Entry;
20
21import org.eclipse.jface.viewers.Viewer;
22import org.eclipse.jface.viewers.ViewerComparator;
23import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
24import org.eclipse.linuxtools.lttng2.kernel.core.analysis.LttngKernelAnalysisModule;
25import org.eclipse.linuxtools.lttng2.kernel.core.cpuusage.LttngKernelCpuUsageAnalysis;
bcec0116
AM
26import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
27import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
28import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException;
29import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval;
30import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
dffc234f 31import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule;
dffc234f
GB
32import org.eclipse.linuxtools.tmf.ui.viewers.tree.AbstractTmfTreeViewer;
33import org.eclipse.linuxtools.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider;
34import org.eclipse.linuxtools.tmf.ui.viewers.tree.ITmfTreeViewerEntry;
35import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeColumnData;
36import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeColumnData.ITmfColumnPercentageProvider;
37import org.eclipse.linuxtools.tmf.ui.viewers.tree.TmfTreeViewerEntry;
38import org.eclipse.osgi.util.NLS;
39import org.eclipse.swt.widgets.Composite;
40
41/**
42 * Tree viewer to display CPU usage information in a specified time range. It
43 * shows the process's TID, its name, the time spent on the CPU during that
44 * range, in % and absolute value.
45 *
46 * @author Geneviève Bastien
47 */
48public class CpuUsageComposite extends AbstractTmfTreeViewer {
49
d48661f2
GB
50 // Timeout between to wait for in the updateElements method
51 private static final long BUILD_UPDATE_TIMEOUT = 500;
52
dffc234f
GB
53 private LttngKernelCpuUsageAnalysis fModule = null;
54
55 private static final String[] COLUMN_NAMES = new String[] {
56 Messages.CpuUsageComposite_ColumnTID,
57 Messages.CpuUsageComposite_ColumnProcess,
58 Messages.CpuUsageComposite_ColumnPercent,
59 Messages.CpuUsageComposite_ColumnTime
60 };
61
62 /* A map that saves the mapping of a thread ID to its executable name */
63 private final Map<String, String> fProcessNameMap = new HashMap<>();
64
65 /** Provides label for the CPU usage tree viewer cells */
66 protected static class CpuLabelProvider extends TreeLabelProvider {
67
68 @Override
69 public String getColumnText(Object element, int columnIndex) {
70 CpuUsageEntry obj = (CpuUsageEntry) element;
71 if (columnIndex == 0) {
72 return obj.getTid();
73 } else if (columnIndex == 1) {
74 return obj.getProcessName();
75 } else if (columnIndex == 2) {
76 return String.format(Messages.CpuUsageComposite_TextPercent, obj.getPercent());
77 } else if (columnIndex == 3) {
78 return NLS.bind(Messages.CpuUsageComposite_TextTime, obj.getTime());
79 }
80
81 return element.toString();
82 }
83
84 }
85
86 /**
87 * Constructor
88 *
89 * @param parent
90 * The parent composite that holds this viewer
91 */
92 public CpuUsageComposite(Composite parent) {
93 super(parent, false);
94 setLabelProvider(new CpuLabelProvider());
95 }
96
97 @Override
98 protected ITmfTreeColumnDataProvider getColumnDataProvider() {
99 return new ITmfTreeColumnDataProvider() {
100
101 @Override
102 public List<TmfTreeColumnData> getColumnData() {
103 /* All columns are sortable */
104 List<TmfTreeColumnData> columns = new ArrayList<>();
105 TmfTreeColumnData column = new TmfTreeColumnData(COLUMN_NAMES[0]);
106 column.setComparator(new ViewerComparator() {
107 @Override
108 public int compare(Viewer viewer, Object e1, Object e2) {
109 CpuUsageEntry n1 = (CpuUsageEntry) e1;
110 CpuUsageEntry n2 = (CpuUsageEntry) e2;
111
112 return n1.getTid().compareTo(n2.getTid());
113
114 }
115 });
116 columns.add(column);
117 column = new TmfTreeColumnData(COLUMN_NAMES[1]);
118 column.setComparator(new ViewerComparator() {
119 @Override
120 public int compare(Viewer viewer, Object e1, Object e2) {
121 CpuUsageEntry n1 = (CpuUsageEntry) e1;
122 CpuUsageEntry n2 = (CpuUsageEntry) e2;
123
124 return n1.getProcessName().compareTo(n2.getProcessName());
125
126 }
127 });
128 columns.add(column);
129 column = new TmfTreeColumnData(COLUMN_NAMES[2]);
130 column.setComparator(new ViewerComparator() {
131 @Override
132 public int compare(Viewer viewer, Object e1, Object e2) {
133 CpuUsageEntry n1 = (CpuUsageEntry) e1;
134 CpuUsageEntry n2 = (CpuUsageEntry) e2;
135
136 return n1.getPercent().compareTo(n2.getPercent());
137
138 }
139 });
140 column.setPercentageProvider(new ITmfColumnPercentageProvider() {
141
142 @Override
143 public double getPercentage(Object data) {
144 CpuUsageEntry parent = (CpuUsageEntry) data;
145 return parent.getPercent() / 100;
146 }
147 });
148 columns.add(column);
149 column = new TmfTreeColumnData(COLUMN_NAMES[3]);
150 column.setComparator(new ViewerComparator() {
151 @Override
152 public int compare(Viewer viewer, Object e1, Object e2) {
153 CpuUsageEntry n1 = (CpuUsageEntry) e1;
154 CpuUsageEntry n2 = (CpuUsageEntry) e2;
155
156 return n1.getTime().compareTo(n2.getTime());
157
158 }
159 });
160 columns.add(column);
161
162 return columns;
163 }
164
165 };
166 }
167
168 // ------------------------------------------------------------------------
169 // Operations
170 // ------------------------------------------------------------------------
171
172 @Override
173 public void initializeDataSource() {
174 fModule = getTrace().getAnalysisModuleOfClass(LttngKernelCpuUsageAnalysis.class, LttngKernelCpuUsageAnalysis.ID);
175 if (fModule == null) {
176 return;
177 }
178 fModule.schedule();
179 fModule.waitForInitialization();
180 fProcessNameMap.clear();
181 }
182
183 @Override
184 protected ITmfTreeViewerEntry updateElements(long start, long end, boolean isSelection) {
185 if (isSelection || (start == end)) {
186 return null;
187 }
188 if (getTrace() == null || fModule == null) {
189 return null;
190 }
d48661f2 191 fModule.waitForInitialization();
dffc234f 192 ITmfStateSystem ss = fModule.getStateSystem();
dffc234f
GB
193 if (ss == null) {
194 return null;
195 }
196
d48661f2
GB
197 boolean complete = false;
198 long currentEnd = start;
199
200 while (!complete && currentEnd < end) {
201 complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
202 currentEnd = ss.getCurrentEndTime();
203 }
204
dffc234f
GB
205 /* Initialize the data */
206 Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, getStartTime()), Math.min(end, getEndTime()));
207
208 TmfTreeViewerEntry root = new TmfTreeViewerEntry(""); //$NON-NLS-1$
209 List<ITmfTreeViewerEntry> entryList = root.getChildren();
210
211 for (Entry<String, Long> entry : cpuUsageMap.entrySet()) {
212 /*
213 * Process only entries representing the total of all CPUs and that
214 * have time on CPU
215 */
216 if (entry.getValue() == 0) {
217 continue;
218 }
219 if (!entry.getKey().startsWith(LttngKernelCpuUsageAnalysis.TOTAL)) {
220 continue;
221 }
222 String[] strings = entry.getKey().split(LttngKernelCpuUsageAnalysis.SPLIT_STRING, 2);
223
224 if ((strings.length > 1) && !(strings[1].equals(LttngKernelCpuUsageAnalysis.TID_ZERO))) {
225 CpuUsageEntry obj = new CpuUsageEntry(strings[1], getProcessName(strings[1]), (double) entry.getValue() / (double) (end - start) * 100, entry.getValue());
226 entryList.add(obj);
227 }
228 }
229
230 return root;
231 }
232
233 /*
234 * Get the process name from its TID by using the LTTng kernel analysis
235 * module
236 */
237 private String getProcessName(String tid) {
238 String execName = fProcessNameMap.get(tid);
239 if (execName != null) {
240 return execName;
241 }
242 TmfStateSystemAnalysisModule module = getTrace().getAnalysisModuleOfClass(TmfStateSystemAnalysisModule.class, LttngKernelAnalysisModule.ID);
243 if (module == null) {
244 return tid;
245 }
246 /*
247 * Do not schedule the analysis here. It should have been executed when
248 * the CPU usage analysis was executed. If it's not available, there
249 * might be a good reason (disk space?) so don't force it.
250 */
251 ITmfStateSystem kernelSs = module.getStateSystem();
252 if (kernelSs == null) {
253 return tid;
254 }
255
256 try {
257 int cpusNode = kernelSs.getQuarkAbsolute(Attributes.THREADS);
258
259 /* Get the quarks for each cpu */
260 List<Integer> cpuNodes = kernelSs.getSubAttributes(cpusNode, false);
261
262 for (Integer tidQuark : cpuNodes) {
263 if (kernelSs.getAttributeName(tidQuark).equals(tid)) {
264 int execNameQuark;
265 List<ITmfStateInterval> execNameIntervals;
266 try {
267 execNameQuark = kernelSs.getQuarkRelative(tidQuark, Attributes.EXEC_NAME);
268 execNameIntervals = kernelSs.queryHistoryRange(execNameQuark, getStartTime(), getEndTime());
269 } catch (AttributeNotFoundException e) {
270 /* No information on this thread (yet?), skip it for now */
271 continue;
272 } catch (StateSystemDisposedException e) {
273 /* State system is closing down, no point continuing */
274 break;
275 }
276
277 for (ITmfStateInterval execNameInterval : execNameIntervals) {
278 if (!execNameInterval.getStateValue().isNull() &&
279 execNameInterval.getStateValue().getType() == ITmfStateValue.Type.STRING) {
280 execName = execNameInterval.getStateValue().unboxStr();
281 fProcessNameMap.put(tid, execName);
282 return execName;
283 }
284 }
285 }
286 }
287
288 } catch (AttributeNotFoundException e) {
289 /* can't find the process name, just return the tid instead */
290 }
291 return tid;
292 }
293
294}
This page took 0.044585 seconds and 5 git commands to generate.