linux.ui: make Kernel Memory view handle out of range requests
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.ui / src / org / eclipse / tracecompass / internal / analysis / os / linux / ui / views / kernelmemoryusage / KernelMemoryUsageTreeViewer.java
CommitLineData
aa19e48b
NA
1/**********************************************************************
2 * Copyright (c) 2016 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 **********************************************************************/
9package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.kernelmemoryusage;
10
11import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
12
13import java.util.ArrayList;
14import java.util.Collections;
15import java.util.HashMap;
16import java.util.List;
17import java.util.Map;
18
19import org.eclipse.jface.viewers.Viewer;
20import org.eclipse.jface.viewers.ViewerComparator;
21import org.eclipse.swt.widgets.Composite;
22import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
23import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelThreadInformationProvider;
24import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryAnalysisModule;
25import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryStateProvider;
26import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
27import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
aa19e48b
NA
28import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
29import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
30import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
31import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
32import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer;
33import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider;
34import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry;
35import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData;
36import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry;
37
38/**
39 * Tree viewer to select which process to display in the kernel memory usage
40 * chart.
41 *
42 * @author Mahdi Zolnouri
43 * @author Wassim Nasrallah
44 * @author Najib Arbaoui
45 */
46public class KernelMemoryUsageTreeViewer extends AbstractTmfTreeViewer {
47
48 private KernelMemoryAnalysisModule fModule = null;
49 private String fSelectedThread = null;
50 private static final String[] COLUMN_NAMES = new String[] {
51 Messages.KernelMemoryUsageComposite_ColumnTID,
52 Messages.KernelMemoryUsageComposite_ColumnProcess
53 };
54
55 /* A map that saves the mapping of a thread ID to its executable name */
56 private final Map<String, String> fProcessNameMap = new HashMap<>();
57
58 /** Provides label for the Kernel memory usage tree viewer cells */
59 protected static class KernelMemoryLabelProvider extends TreeLabelProvider {
60
61 @Override
62 public String getColumnText(Object element, int columnIndex) {
63 KernelMemoryUsageEntry obj = (KernelMemoryUsageEntry) element;
64 if (columnIndex == 0) {
65 return obj.getTid();
66 } else if (columnIndex == 1) {
67 return obj.getProcessName();
68 }
69 return element.toString();
70 }
71 }
72
73 /**
74 * Constructor
75 *
76 * @param parent
77 * The parent composite that holds this viewer
78 */
79 public KernelMemoryUsageTreeViewer(Composite parent) {
80 super(parent, false);
81 setLabelProvider(new KernelMemoryLabelProvider());
82 }
83
84 @Override
85 protected ITmfTreeColumnDataProvider getColumnDataProvider() {
86 return new ITmfTreeColumnDataProvider() {
87
88 @Override
89 public List<TmfTreeColumnData> getColumnData() {
90 /* All columns are sortable */
91 List<TmfTreeColumnData> columns = new ArrayList<>();
92 TmfTreeColumnData column = new TmfTreeColumnData(COLUMN_NAMES[0]);
93 column.setComparator(new ViewerComparator() {
94 @Override
95 public int compare(Viewer viewer, Object e1, Object e2) {
96 KernelMemoryUsageEntry n1 = (KernelMemoryUsageEntry) e1;
97 KernelMemoryUsageEntry n2 = (KernelMemoryUsageEntry) e2;
98
99 return n1.getTid().compareTo(n2.getTid());
100 }
101 });
102 columns.add(column);
103 column = new TmfTreeColumnData(COLUMN_NAMES[1]);
104 column.setComparator(new ViewerComparator() {
105 @Override
106 public int compare(Viewer viewer, Object e1, Object e2) {
107 KernelMemoryUsageEntry n1 = (KernelMemoryUsageEntry) e1;
108 KernelMemoryUsageEntry n2 = (KernelMemoryUsageEntry) e2;
109
110 return n1.getProcessName().compareTo(n2.getProcessName());
111 }
112 });
113 columns.add(column);
114 return columns;
115 }
116 };
117 }
118
119 // ------------------------------------------------------------------------
120 // Operations
121 // ------------------------------------------------------------------------
122
123 @Override
124 protected void contentChanged(ITmfTreeViewerEntry rootEntry) {
125 String selectedThread = fSelectedThread;
126 if (selectedThread != null) {
127 /* Find the selected thread among the inputs */
128 for (ITmfTreeViewerEntry entry : rootEntry.getChildren()) {
129 if (entry instanceof KernelMemoryUsageEntry) {
130 if (selectedThread.equals(((KernelMemoryUsageEntry) entry).getTid())) {
131 List<ITmfTreeViewerEntry> list = Collections.singletonList(entry);
132 super.setSelection(list);
133 return;
134 }
135 }
136 }
137 }
138 }
139
140 @Override
141 public void initializeDataSource() {
142 /* Should not be called while trace is still null */
143 ITmfTrace trace = checkNotNull(getTrace());
144
145 fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelMemoryAnalysisModule.class, KernelMemoryAnalysisModule.ID);
146 if (fModule == null) {
147 return;
148 }
149 fModule.schedule();
150 fModule.waitForInitialization();
151 fProcessNameMap.clear();
152 }
153
154 @Override
155 protected ITmfTreeViewerEntry updateElements(long start, long end, boolean isSelection) {
156 if (isSelection || (start == end)) {
157 return null;
158 }
159 KernelMemoryAnalysisModule module = fModule;
160 if (getTrace() == null || module == null) {
161 return null;
162 }
163 module.waitForInitialization();
164 ITmfStateSystem ss = module.getStateSystem();
165 if (ss == null) {
166 return null;
167 }
168 ss.waitUntilBuilt();
169 TmfTreeViewerEntry root = new TmfTreeViewerEntry(""); //$NON-NLS-1$
170 List<ITmfTreeViewerEntry> entryList = root.getChildren();
171
172 try {
63949239
MK
173 long newStart = Math.max(start, ss.getStartTime());
174 long newEnd = Math.min(end, ss.getCurrentEndTime());
175 if (ss.getStartTime() > newEnd || ss.getCurrentEndTime() < start) {
176 return root;
177 }
178 List<ITmfStateInterval> memoryStates = ss.queryFullState(newStart);
aa19e48b
NA
179 List<Integer> threadQuarkList = ss.getSubAttributes(ITmfStateSystem.ROOT_ATTRIBUTE, false);
180
181 for (Integer threadQuark : threadQuarkList) {
182 ITmfStateInterval threadMemoryInterval = memoryStates.get(threadQuark);
183 if (threadMemoryInterval.getEndTime() < end) {
184 String tid = ss.getAttributeName(threadQuark);
185 String procname = getProcessName(tid);
186 KernelMemoryUsageEntry obj = new KernelMemoryUsageEntry(tid, procname);
187 entryList.add(obj);
188 }
189 }
ed48dc75 190 } catch (StateSystemDisposedException e) {
aa19e48b
NA
191 Activator.getDefault().logError(e.getMessage(), e);
192 }
193 return root;
194 }
195
196 /*
197 * Get the process name from its TID by using the LTTng kernel analysis
198 * module
199 */
200 private String getProcessName(String tid) {
201 String execName = fProcessNameMap.get(tid);
202 if (execName != null) {
203 return execName;
204 }
205 if (tid.equals(KernelMemoryStateProvider.OTHER_TID)) {
206 fProcessNameMap.put(tid, tid);
207 return tid;
208 }
209 ITmfTrace trace = checkNotNull(getTrace());
210 KernelAnalysisModule kernelModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
211 if (kernelModule == null) {
212 return tid;
213 }
214 execName = KernelThreadInformationProvider.getExecutableName(kernelModule, Integer.parseInt(tid));
215 if (execName == null) {
216 return tid;
217 }
218 fProcessNameMap.put(tid, execName);
219 return execName;
220 }
221
222 /**
223 * Set the currently selected thread ID
224 *
225 * @param tid
226 * The selected thread ID
227 */
228 public void setSelectedThread(String tid) {
229 fSelectedThread = tid;
230 }
231}
This page took 0.034683 seconds and 5 git commands to generate.