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