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