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