Commit | Line | Data |
---|---|---|
aa19e48b NA |
1 | /********************************************************************** |
2 | * Copyright (c) 2016 É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 | package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.kernelmemoryusage; | |
10 | ||
aa19e48b NA |
11 | import java.util.List; |
12 | ||
13 | import org.eclipse.core.runtime.IProgressMonitor; | |
14 | import org.eclipse.swt.SWT; | |
15 | import org.eclipse.swt.widgets.Composite; | |
16 | import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryAnalysisModule; | |
f937c19c | 17 | import org.eclipse.tracecompass.common.core.format.DataSizeWithUnitFormat; |
aa19e48b NA |
18 | import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator; |
19 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; | |
20 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | |
21 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
22 | import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; | |
23 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; | |
629bf3c1 JCK |
24 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; |
25 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
26 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; | |
aa19e48b NA |
27 | import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; |
28 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
29 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; | |
30 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; | |
31 | import org.swtchart.Chart; | |
32 | ||
33 | /** | |
34 | * Memory usage view | |
35 | * | |
36 | * @author Samuel Gagnon | |
37 | * @author Wassim Nasrallah | |
38 | */ | |
39 | public class KernelMemoryUsageViewer extends TmfCommonXLineChartViewer { | |
40 | ||
aa19e48b NA |
41 | private static final String NOT_SELECTED = "-1"; //$NON-NLS-1$ |
42 | ||
43 | private TmfStateSystemAnalysisModule fModule = null; | |
44 | private String fSelectedThread = NOT_SELECTED; | |
45 | ||
46 | /** | |
47 | * Constructor | |
48 | * | |
49 | * @param parent | |
50 | * parent view | |
51 | */ | |
52 | public KernelMemoryUsageViewer(Composite parent) { | |
53 | super(parent, Messages.MemoryUsageViewer_title, Messages.MemoryUsageViewer_xAxis, Messages.MemoryUsageViewer_yAxis); | |
54 | Chart chart = getSwtChart(); | |
c81aca6d | 55 | chart.getAxisSet().getYAxis(0).getTick().setFormat(DataSizeWithUnitFormat.getInstance()); |
aa19e48b | 56 | chart.getLegend().setPosition(SWT.BOTTOM); |
58bc31eb | 57 | chart.getLegend().setVisible(false); |
aa19e48b NA |
58 | } |
59 | ||
60 | @Override | |
61 | protected void initializeDataSource() { | |
62 | ITmfTrace trace = getTrace(); | |
63 | if (trace != null) { | |
64 | fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, TmfStateSystemAnalysisModule.class, KernelMemoryAnalysisModule.ID); | |
65 | if (fModule == null) { | |
66 | return; | |
67 | } | |
68 | fModule.schedule(); | |
69 | } | |
70 | } | |
71 | ||
72 | @Override | |
73 | protected void updateData(long start, long end, int nb, IProgressMonitor monitor) { | |
74 | TmfStateSystemAnalysisModule module = fModule; | |
75 | if (getTrace() == null || module == null) { | |
76 | return; | |
77 | } | |
78 | ||
79 | if (!module.waitForInitialization()) { | |
80 | return; | |
81 | } | |
82 | ||
83 | ITmfStateSystem ss = module.getStateSystem(); | |
84 | if (ss == null) { | |
63949239 | 85 | throw new IllegalStateException("No state system for the module " + module.toString()); //$NON-NLS-1$ |
aa19e48b NA |
86 | } |
87 | ||
88 | double[] xvalues = getXAxis(start, end, nb); | |
89 | if (xvalues.length == 0) { | |
90 | return; | |
91 | } | |
63949239 MK |
92 | long clampedEnd = Math.min(end, ss.getCurrentEndTime()); |
93 | if (clampedEnd < ss.getStartTime()) { | |
94 | return; | |
95 | } | |
aa19e48b NA |
96 | setXAxis(xvalues); |
97 | ||
98 | try { | |
99 | /** | |
100 | * For a given time range, we plot two lines representing the memory | |
101 | * allocation. The first line represent the total memory allocation | |
102 | * of every process. The second line represent the memory allocation | |
103 | * of the selected thread. | |
104 | */ | |
105 | double[] totalKernelMemoryValues = new double[xvalues.length]; | |
106 | double[] selectedThreadValues = new double[xvalues.length]; | |
107 | for (int i = 0; i < xvalues.length; i++) { | |
108 | if (monitor.isCanceled()) { | |
109 | return; | |
110 | } | |
111 | ||
112 | double x = xvalues[i]; | |
113 | long t = (long) x + getTimeOffset(); | |
63949239 MK |
114 | if( ss.getCurrentEndTime() < t || ss.getStartTime() > t) { |
115 | selectedThreadValues[i] = 0; | |
116 | continue; | |
117 | } | |
aa19e48b NA |
118 | List<ITmfStateInterval> kernelState = ss.queryFullState(t); |
119 | ||
120 | /* The subattributes of the root are the different threads */ | |
121 | List<Integer> threadQuarkList = ss.getSubAttributes(-1, false); | |
122 | /* We add the value of each thread to the total quantity */ | |
123 | for (Integer threadQuark : threadQuarkList) { | |
124 | ITmfStateInterval threadMemoryInterval = kernelState.get(threadQuark); | |
125 | long value = threadMemoryInterval.getStateValue().unboxLong(); | |
126 | totalKernelMemoryValues[i] += value; | |
127 | ||
128 | String tid = ss.getAttributeName(threadQuark); | |
129 | if (tid.equals(fSelectedThread)) { | |
130 | selectedThreadValues[i] = value; | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | /** | |
136 | * For each thread, we look for its lowest value since the beginning | |
137 | * of the trace. This way, we can avoid negative values in the plot. | |
138 | */ | |
139 | double totalKernelMemoryValuesShift = 0; | |
140 | double selectThreadValuesShift = 0; | |
141 | ||
142 | /* | |
143 | * The lowest value we are searching is at the end of the current | |
144 | * selected zone | |
145 | */ | |
63949239 | 146 | List<ITmfStateInterval> kernelState = ss.queryFullState(clampedEnd); |
aa19e48b NA |
147 | List<Integer> threadQuarkList = ss.getSubAttributes(-1, false); |
148 | /* We add the lowest value of each thread */ | |
149 | for (Integer threadQuark : threadQuarkList) { | |
150 | int lowestMemoryQuark = ss.getQuarkRelative(threadQuark, KernelMemoryAnalysisModule.THREAD_LOWEST_MEMORY_VALUE); | |
151 | ITmfStateInterval lowestMemoryInterval = kernelState.get(lowestMemoryQuark); | |
152 | long lowestMemoryValue = lowestMemoryInterval.getStateValue().unboxLong(); | |
153 | // We want to add up a positive quantity. | |
154 | totalKernelMemoryValuesShift -= lowestMemoryValue; | |
155 | ||
156 | String tid = ss.getAttributeName(threadQuark); | |
157 | if (tid.equals(fSelectedThread)) { | |
158 | // We want to add up a positive quantity. | |
159 | selectThreadValuesShift = -lowestMemoryValue; | |
160 | } | |
161 | } | |
162 | ||
163 | /** | |
164 | * We shift the two displayed lines up. | |
165 | */ | |
166 | for (int i = 0; i < xvalues.length; i++) { | |
167 | totalKernelMemoryValues[i] += totalKernelMemoryValuesShift; | |
168 | selectedThreadValues[i] += selectThreadValuesShift; | |
169 | } | |
170 | setSeries(Messages.MemoryUsageViewer_Total, totalKernelMemoryValues); | |
171 | if (fSelectedThread != NOT_SELECTED) { | |
172 | setSeries(fSelectedThread, selectedThreadValues); | |
173 | } | |
174 | updateDisplay(); | |
175 | ||
176 | } catch (TimeRangeException | StateSystemDisposedException | AttributeNotFoundException e) { | |
177 | Activator.getDefault().logError(e.getMessage(), e); | |
178 | } | |
179 | } | |
180 | ||
181 | /** | |
182 | * Set the selected thread ID, which will be graphed in this viewer | |
183 | * | |
184 | * @param tid | |
185 | * The selected thread ID | |
186 | */ | |
187 | public void setSelectedThread(String tid) { | |
188 | cancelUpdate(); | |
189 | deleteSeries(fSelectedThread); | |
190 | fSelectedThread = tid; | |
191 | updateContent(); | |
192 | } | |
193 | ||
629bf3c1 JCK |
194 | @Override |
195 | @TmfSignalHandler | |
196 | public void traceSelected(TmfTraceSelectedSignal signal) { | |
197 | setSelectedThread(NOT_SELECTED); | |
198 | super.traceSelected(signal); | |
199 | } | |
200 | ||
201 | @Override | |
202 | @TmfSignalHandler | |
203 | public void traceOpened(TmfTraceOpenedSignal signal) { | |
204 | setSelectedThread(NOT_SELECTED); | |
205 | super.traceOpened(signal); | |
206 | } | |
207 | ||
aa19e48b | 208 | } |