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