Commit | Line | Data |
---|---|---|
5db8e1e9 GB |
1 | /********************************************************************** |
2 | * Copyright (c) 2014 Ericsson, É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 | * Bernd Hufmann - Initial API and implementation | |
11 | * Geneviève Bastien - Create and use base class for XY plots | |
12 | **********************************************************************/ | |
13 | ||
9bc60be7 | 14 | package org.eclipse.tracecompass.internal.lttng2.ust.ui.views.memusage; |
5db8e1e9 | 15 | |
202956f1 AM |
16 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
17 | ||
40ed3a08 | 18 | import java.util.Collections; |
5db8e1e9 GB |
19 | import java.util.HashMap; |
20 | import java.util.List; | |
21 | import java.util.Map; | |
22 | ||
00968516 | 23 | import org.eclipse.core.runtime.IProgressMonitor; |
194b7bfe | 24 | import org.eclipse.swt.SWT; |
5db8e1e9 | 25 | import org.eclipse.swt.widgets.Composite; |
27f942b4 | 26 | import org.eclipse.swt.widgets.Display; |
61c1650e | 27 | import org.eclipse.tracecompass.common.core.format.DataSizeWithUnitFormat; |
116738ad | 28 | import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.memory.UstMemoryStrings; |
0feae9f8 | 29 | import org.eclipse.tracecompass.internal.lttng2.ust.ui.Activator; |
9bc60be7 | 30 | import org.eclipse.tracecompass.lttng2.ust.core.analysis.memory.UstMemoryAnalysisModule; |
e894a508 AM |
31 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; |
32 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | |
33 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
34 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; | |
35 | import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; | |
ccf0e1a6 | 36 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; |
e894a508 | 37 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; |
2bdf0193 | 38 | import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; |
1d83ed07 | 39 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
b8585c7c | 40 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; |
2bdf0193 | 41 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; |
61c1650e | 42 | import org.swtchart.Chart; |
5db8e1e9 GB |
43 | |
44 | /** | |
45 | * Memory usage view | |
46 | * | |
47 | * @author Matthew Khouzam | |
48 | */ | |
5db8e1e9 GB |
49 | public class MemoryUsageViewer extends TmfCommonXLineChartViewer { |
50 | ||
51 | private TmfStateSystemAnalysisModule fModule = null; | |
52 | ||
53 | private final Map<Integer, double[]> fYValues = new HashMap<>(); | |
54 | private final Map<Integer, Integer> fMemoryQuarks = new HashMap<>(); | |
55 | private final Map<Integer, String> fSeriesName = new HashMap<>(); | |
56 | ||
261af2c6 GB |
57 | // Timeout between updates in the updateData thread |
58 | private static final long BUILD_UPDATE_TIMEOUT = 500; | |
59 | ||
5db8e1e9 GB |
60 | /** |
61 | * Constructor | |
62 | * | |
63 | * @param parent | |
64 | * parent view | |
65 | */ | |
66 | public MemoryUsageViewer(Composite parent) { | |
67 | super(parent, Messages.MemoryUsageViewer_Title, Messages.MemoryUsageViewer_XAxis, Messages.MemoryUsageViewer_YAxis); | |
61c1650e | 68 | Chart chart = getSwtChart(); |
194b7bfe | 69 | chart.getLegend().setPosition(SWT.LEFT); |
c81aca6d | 70 | chart.getAxisSet().getYAxis(0).getTick().setFormat(DataSizeWithUnitFormat.getInstance()); |
5db8e1e9 GB |
71 | } |
72 | ||
73 | @Override | |
74 | protected void initializeDataSource() { | |
1d83ed07 AM |
75 | ITmfTrace trace = getTrace(); |
76 | if (trace != null) { | |
77 | fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, TmfStateSystemAnalysisModule.class, UstMemoryAnalysisModule.ID); | |
5db8e1e9 GB |
78 | if (fModule == null) { |
79 | return; | |
80 | } | |
81 | fModule.schedule(); | |
82 | } | |
83 | } | |
84 | ||
85 | @Override | |
00968516 | 86 | protected void updateData(long start, long end, int nb, IProgressMonitor monitor) { |
5db8e1e9 GB |
87 | try { |
88 | if (getTrace() == null || fModule == null) { | |
89 | return; | |
90 | } | |
c81ffdf2 JCK |
91 | if (!fModule.waitForInitialization()) { |
92 | return; | |
93 | } | |
5db8e1e9 GB |
94 | ITmfStateSystem ss = fModule.getStateSystem(); |
95 | /* Don't wait for the module completion, when it's ready, we'll know */ | |
96 | if (ss == null) { | |
97 | return; | |
98 | } | |
261af2c6 | 99 | |
5db8e1e9 GB |
100 | double[] xvalues = getXAxis(start, end, nb); |
101 | setXAxis(xvalues); | |
5db8e1e9 | 102 | |
40ed3a08 | 103 | |
261af2c6 | 104 | boolean complete = false; |
40ed3a08 | 105 | long currentEnd = Math.max(ss.getStartTime(), start); |
261af2c6 GB |
106 | |
107 | while (!complete && currentEnd < end) { | |
00968516 GB |
108 | if (monitor.isCanceled()) { |
109 | return; | |
110 | } | |
261af2c6 GB |
111 | complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT); |
112 | currentEnd = ss.getCurrentEndTime(); | |
113 | List<Integer> tidQuarks = ss.getSubAttributes(-1, false); | |
40ed3a08 | 114 | long traceStart = Math.max(getStartTime(), ss.getStartTime()); |
261af2c6 GB |
115 | long traceEnd = getEndTime(); |
116 | long offset = this.getTimeOffset(); | |
5db8e1e9 | 117 | |
261af2c6 | 118 | /* Initialize quarks and series names */ |
40ed3a08 BH |
119 | long queryStart = Math.max(ss.getStartTime(), start); |
120 | List<ITmfStateInterval> fullState = Collections.emptyList(); | |
121 | if (queryStart <= currentEnd) { | |
122 | fullState = ss.queryFullState(queryStart); | |
123 | for (int quark : tidQuarks) { | |
124 | fYValues.put(quark, new double[xvalues.length]); | |
125 | fMemoryQuarks.put(quark, ss.getQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_MEMORY_ATTRIBUTE)); | |
126 | int procNameQuark = ss.getQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_PROCNAME_ATTRIBUTE); | |
127 | String oldSeriesName = fSeriesName.get(quark); | |
128 | String seriesName = null; | |
129 | try { | |
130 | ITmfStateValue procnameValue = fullState.get(procNameQuark).getStateValue(); | |
131 | String procname = ""; //$NON-NLS-1$ | |
132 | if (!procnameValue.isNull()) { | |
133 | procname = procnameValue.unboxStr(); | |
134 | } | |
135 | seriesName = (procname + ' ' + '(' + ss.getAttributeName(quark) + ')').trim(); | |
136 | } catch (TimeRangeException e) { | |
137 | seriesName = '(' + ss.getAttributeName(quark) + ')'; | |
261af2c6 | 138 | } |
6206fd75 | 139 | |
40ed3a08 BH |
140 | if (oldSeriesName != null && !oldSeriesName.equals(seriesName)) { |
141 | Display display = Display.getDefault(); | |
142 | if (!display.isDisposed()) { | |
143 | display.syncExec(() -> { | |
144 | deleteSeries(oldSeriesName); | |
145 | }); | |
146 | } | |
27f942b4 | 147 | } |
40ed3a08 | 148 | fSeriesName.put(quark, seriesName); |
6206fd75 | 149 | } |
40ed3a08 BH |
150 | } else { |
151 | Display.getDefault().asyncExec(() -> { | |
152 | clearContent(); | |
153 | }); | |
154 | continue; | |
5db8e1e9 | 155 | } |
261af2c6 | 156 | /* |
1157a348 ACL |
157 | * TODO: It should only show active threads in the time range. |
158 | * If a tid does not have any memory value (only 1 interval in | |
159 | * the time range with value null or 0), then its series should | |
160 | * not be displayed. | |
261af2c6 GB |
161 | */ |
162 | double yvalue = 0.0; | |
163 | for (int i = 0; i < xvalues.length; i++) { | |
164 | if (monitor.isCanceled()) { | |
165 | return; | |
166 | } | |
167 | double x = xvalues[i]; | |
168 | long time = (long) x + offset; | |
169 | // make sure that time is in the trace range after double to | |
170 | // long conversion | |
171 | time = time < traceStart ? traceStart : time; | |
172 | time = time > traceEnd ? traceEnd : time; | |
ccf0e1a6 LPD |
173 | try { |
174 | fullState = ss.queryFullState(time); | |
175 | for (int quark : tidQuarks) { | |
176 | double[] values = checkNotNull(fYValues.get(quark)); | |
261af2c6 | 177 | |
202956f1 | 178 | Integer memQuark = checkNotNull(fMemoryQuarks.get(quark)); |
ccf0e1a6 | 179 | yvalue = fullState.get(memQuark.intValue()).getStateValue().unboxLong(); |
202956f1 | 180 | values[i] = yvalue; |
ccf0e1a6 LPD |
181 | } |
182 | } catch (TimeRangeException e) { | |
183 | for (int quark : tidQuarks) { | |
184 | double[] values = checkNotNull(fYValues.get(quark)); | |
202956f1 | 185 | values[i] = 0; |
261af2c6 GB |
186 | } |
187 | } | |
188 | } | |
189 | for (int quark : tidQuarks) { | |
190 | setSeries(fSeriesName.get(quark), fYValues.get(quark)); | |
191 | } | |
192 | updateDisplay(); | |
5db8e1e9 | 193 | } |
e1c415b3 | 194 | } catch (AttributeNotFoundException | StateValueTypeException e) { |
0feae9f8 | 195 | Activator.getDefault().logError("Error updating the data of the Memory usage view", e); //$NON-NLS-1$ |
e1c415b3 BH |
196 | } catch (StateSystemDisposedException e) { |
197 | /* State system is closing down, no point continuing */ | |
5db8e1e9 GB |
198 | } |
199 | } | |
200 | ||
201 | } |