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