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