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 | ||
14 | package org.eclipse.linuxtools.internal.lttng2.ust.ui.views.memusage; | |
15 | ||
16 | import java.util.HashMap; | |
17 | import java.util.List; | |
18 | import java.util.Map; | |
19 | ||
00968516 | 20 | import org.eclipse.core.runtime.IProgressMonitor; |
5db8e1e9 | 21 | import org.eclipse.linuxtools.internal.lttng2.ust.core.memoryusage.UstMemoryStrings; |
1996f571 | 22 | import org.eclipse.linuxtools.lttng2.ust.core.analysis.memory.UstMemoryAnalysisModule; |
5db8e1e9 | 23 | import org.eclipse.swt.widgets.Composite; |
2bdf0193 | 24 | import org.eclipse.tracecompass.internal.tmf.core.Activator; |
e894a508 AM |
25 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; |
26 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | |
27 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
28 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; | |
29 | import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; | |
30 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; | |
2bdf0193 AM |
31 | import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; |
32 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; | |
5db8e1e9 GB |
33 | |
34 | /** | |
35 | * Memory usage view | |
36 | * | |
37 | * @author Matthew Khouzam | |
38 | */ | |
39 | @SuppressWarnings("restriction") | |
40 | public class MemoryUsageViewer extends TmfCommonXLineChartViewer { | |
41 | ||
42 | private TmfStateSystemAnalysisModule fModule = null; | |
43 | ||
44 | private final Map<Integer, double[]> fYValues = new HashMap<>(); | |
45 | private final Map<Integer, Integer> fMemoryQuarks = new HashMap<>(); | |
46 | private final Map<Integer, String> fSeriesName = new HashMap<>(); | |
47 | ||
48 | private static final int BYTES_TO_KB = 1024; | |
49 | ||
261af2c6 GB |
50 | // Timeout between updates in the updateData thread |
51 | private static final long BUILD_UPDATE_TIMEOUT = 500; | |
52 | ||
5db8e1e9 GB |
53 | /** |
54 | * Constructor | |
55 | * | |
56 | * @param parent | |
57 | * parent view | |
58 | */ | |
59 | public MemoryUsageViewer(Composite parent) { | |
60 | super(parent, Messages.MemoryUsageViewer_Title, Messages.MemoryUsageViewer_XAxis, Messages.MemoryUsageViewer_YAxis); | |
61 | } | |
62 | ||
63 | @Override | |
64 | protected void initializeDataSource() { | |
65 | if (getTrace() != null) { | |
66 | fModule = getTrace().getAnalysisModuleOfClass(TmfStateSystemAnalysisModule.class, UstMemoryAnalysisModule.ID); | |
67 | if (fModule == null) { | |
68 | return; | |
69 | } | |
70 | fModule.schedule(); | |
71 | } | |
72 | } | |
73 | ||
74 | @Override | |
00968516 | 75 | protected void updateData(long start, long end, int nb, IProgressMonitor monitor) { |
5db8e1e9 GB |
76 | try { |
77 | if (getTrace() == null || fModule == null) { | |
78 | return; | |
79 | } | |
261af2c6 | 80 | fModule.waitForInitialization(); |
5db8e1e9 GB |
81 | ITmfStateSystem ss = fModule.getStateSystem(); |
82 | /* Don't wait for the module completion, when it's ready, we'll know */ | |
83 | if (ss == null) { | |
84 | return; | |
85 | } | |
261af2c6 | 86 | |
5db8e1e9 GB |
87 | double[] xvalues = getXAxis(start, end, nb); |
88 | setXAxis(xvalues); | |
5db8e1e9 | 89 | |
261af2c6 GB |
90 | boolean complete = false; |
91 | long currentEnd = start; | |
92 | ||
93 | while (!complete && currentEnd < end) { | |
00968516 GB |
94 | if (monitor.isCanceled()) { |
95 | return; | |
96 | } | |
261af2c6 GB |
97 | complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT); |
98 | currentEnd = ss.getCurrentEndTime(); | |
99 | List<Integer> tidQuarks = ss.getSubAttributes(-1, false); | |
100 | long traceStart = getStartTime(); | |
101 | long traceEnd = getEndTime(); | |
102 | long offset = this.getTimeOffset(); | |
5db8e1e9 | 103 | |
261af2c6 | 104 | /* Initialize quarks and series names */ |
5db8e1e9 | 105 | for (int quark : tidQuarks) { |
261af2c6 GB |
106 | fYValues.put(quark, new double[xvalues.length]); |
107 | fMemoryQuarks.put(quark, ss.getQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_MEMORY_ATTRIBUTE)); | |
108 | int procNameQuark = ss.getQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_PROCNAME_ATTRIBUTE); | |
5db8e1e9 | 109 | try { |
261af2c6 GB |
110 | ITmfStateValue procnameValue = ss.querySingleState(start, procNameQuark).getStateValue(); |
111 | String procname = new String(); | |
112 | if (!procnameValue.isNull()) { | |
113 | procname = procnameValue.unboxStr(); | |
114 | } | |
115 | fSeriesName.put(quark, new String(procname + ' ' + '(' + ss.getAttributeName(quark) + ')').trim()); | |
5db8e1e9 | 116 | } catch (TimeRangeException e) { |
261af2c6 | 117 | fSeriesName.put(quark, '(' + ss.getAttributeName(quark) + ')'); |
5db8e1e9 GB |
118 | } |
119 | } | |
261af2c6 GB |
120 | |
121 | /* | |
122 | * TODO: It should only show active threads in the time range. If a | |
123 | * tid does not have any memory value (only 1 interval in the time | |
124 | * range with value null or 0), then its series should not be | |
125 | * displayed. | |
126 | */ | |
127 | double yvalue = 0.0; | |
128 | for (int i = 0; i < xvalues.length; i++) { | |
129 | if (monitor.isCanceled()) { | |
130 | return; | |
131 | } | |
132 | double x = xvalues[i]; | |
133 | long time = (long) x + offset; | |
134 | // make sure that time is in the trace range after double to | |
135 | // long conversion | |
136 | time = time < traceStart ? traceStart : time; | |
137 | time = time > traceEnd ? traceEnd : time; | |
138 | ||
139 | for (int quark : tidQuarks) { | |
140 | try { | |
141 | yvalue = ss.querySingleState(time, fMemoryQuarks.get(quark)).getStateValue().unboxLong() / BYTES_TO_KB; | |
142 | fYValues.get(quark)[i] = yvalue; | |
143 | } catch (TimeRangeException e) { | |
144 | fYValues.get(quark)[i] = 0; | |
145 | } | |
146 | } | |
147 | } | |
148 | for (int quark : tidQuarks) { | |
149 | setSeries(fSeriesName.get(quark), fYValues.get(quark)); | |
150 | } | |
151 | updateDisplay(); | |
5db8e1e9 | 152 | } |
5db8e1e9 GB |
153 | } catch (AttributeNotFoundException | StateValueTypeException | StateSystemDisposedException e) { |
154 | Activator.logError("Error updating the data of the Memory usage view", e); //$NON-NLS-1$ | |
155 | } | |
156 | } | |
157 | ||
158 | } |