gdbtrace: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.ui / src / org / eclipse / linuxtools / internal / lttng2 / kernel / ui / views / cpuusage / CpuUsageXYViewer.java
1 /*******************************************************************************
2 * Copyright (c) 2014 É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 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.cpuusage;
14
15 import java.util.Arrays;
16 import java.util.HashMap;
17 import java.util.LinkedHashMap;
18 import java.util.Map;
19 import java.util.Map.Entry;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Activator;
23 import org.eclipse.linuxtools.lttng2.kernel.core.cpuusage.LttngKernelCpuUsageAnalysis;
24 import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
25 import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
26 import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer;
27 import org.eclipse.swt.widgets.Composite;
28
29 /**
30 * CPU usage viewer with XY line chart. It displays the total CPU usage and that
31 * of the threads selected in the CPU usage tree viewer.
32 *
33 * @author Geneviève Bastien
34 */
35 public class CpuUsageXYViewer extends TmfCommonXLineChartViewer {
36
37 private LttngKernelCpuUsageAnalysis fModule = null;
38
39 /* Maps a thread ID to a list of y values */
40 private final Map<String, double[]> fYValues = new LinkedHashMap<>();
41 /*
42 * To avoid up and downs CPU usage when process is in and out of CPU
43 * frequently, use a smaller resolution to get better averages.
44 */
45 private static final double RESOLUTION = 0.4;
46
47 // Timeout between updates in the updateData thread
48 private static final long BUILD_UPDATE_TIMEOUT = 500;
49
50 private long fSelectedThread = -1;
51
52 /**
53 * Constructor
54 *
55 * @param parent
56 * parent composite
57 */
58 public CpuUsageXYViewer(Composite parent) {
59 super(parent, Messages.CpuUsageXYViewer_Title, Messages.CpuUsageXYViewer_TimeXAxis, Messages.CpuUsageXYViewer_CpuYAxis);
60 setResolution(RESOLUTION);
61 }
62
63 @Override
64 protected void initializeDataSource() {
65 if (getTrace() != null) {
66 fModule = getTrace().getAnalysisModuleOfClass(LttngKernelCpuUsageAnalysis.class, LttngKernelCpuUsageAnalysis.ID);
67 if (fModule == null) {
68 return;
69 }
70 fModule.schedule();
71 }
72 }
73
74 private static double[] zeroFill(int nb) {
75 double[] arr = new double[nb];
76 Arrays.fill(arr, 0.0);
77 return arr;
78 }
79
80 @Override
81 protected void updateData(long start, long end, int nb, IProgressMonitor monitor) {
82 try {
83 if (getTrace() == null || fModule == null) {
84 return;
85 }
86 fModule.waitForInitialization();
87 ITmfStateSystem ss = fModule.getStateSystem();
88 if (ss == null) {
89 return;
90 }
91 double[] xvalues = getXAxis(start, end, nb);
92 if (xvalues.length == 0) {
93 return;
94 }
95 setXAxis(xvalues);
96
97 boolean complete = false;
98 long currentEnd = start;
99
100 while (!complete && currentEnd < end) {
101
102 if (monitor.isCanceled()) {
103 return;
104 }
105
106 long traceStart = getStartTime();
107 long traceEnd = getEndTime();
108 long offset = getTimeOffset();
109 long selectedThread = fSelectedThread;
110
111 complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
112 currentEnd = ss.getCurrentEndTime();
113
114 /* Initialize the data */
115 Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, traceStart), Math.min(end, traceEnd));
116 Map<String, String> totalEntries = new HashMap<>();
117 fYValues.clear();
118 fYValues.put(Messages.CpuUsageXYViewer_Total, zeroFill(xvalues.length));
119 String stringSelectedThread = Long.toString(selectedThread);
120 if (selectedThread != -1) {
121 fYValues.put(stringSelectedThread, zeroFill(xvalues.length));
122 }
123
124 for (Entry<String, Long> entry : cpuUsageMap.entrySet()) {
125 /*
126 * Process only entries representing the total of all CPUs
127 * and that have time on CPU
128 */
129 if (entry.getValue() == 0) {
130 continue;
131 }
132 if (!entry.getKey().startsWith(LttngKernelCpuUsageAnalysis.TOTAL)) {
133 continue;
134 }
135 String[] strings = entry.getKey().split(LttngKernelCpuUsageAnalysis.SPLIT_STRING, 2);
136
137 if ((strings.length > 1) && !(strings[1].equals(LttngKernelCpuUsageAnalysis.TID_ZERO))) {
138 /* This is the total cpu usage for a thread */
139 totalEntries.put(strings[1], entry.getKey());
140 }
141 }
142
143 double prevX = xvalues[0];
144 long prevTime = (long) prevX + offset;
145 /*
146 * make sure that time is in the trace range after double to
147 * long conversion
148 */
149 prevTime = Math.max(traceStart, prevTime);
150 prevTime = Math.min(traceEnd, prevTime);
151 /* Get CPU usage statistics for each x value */
152 for (int i = 1; i < xvalues.length; i++) {
153 if (monitor.isCanceled()) {
154 return;
155 }
156 long totalCpu = 0;
157 double x = xvalues[i];
158 long time = (long) x + offset;
159 time = Math.max(traceStart, time);
160 time = Math.min(traceEnd, time);
161
162 cpuUsageMap = fModule.getCpuUsageInRange(prevTime, time);
163
164 /*
165 * Calculate the sum of all total entries, and add a data
166 * point to the selected one
167 */
168 for (Entry<String, String> entry : totalEntries.entrySet()) {
169 Long cpuEntry = cpuUsageMap.get(entry.getValue());
170 cpuEntry = cpuEntry != null ? cpuEntry : 0L;
171
172 totalCpu += cpuEntry;
173
174 if (entry.getKey().equals(stringSelectedThread)) {
175 /* This is the total cpu usage for a thread */
176 fYValues.get(entry.getKey())[i] = (double) cpuEntry / (double) (time - prevTime) * 100;
177 }
178
179 }
180 fYValues.get(Messages.CpuUsageXYViewer_Total)[i] = (double) totalCpu / (double) (time - prevTime) * 100;
181 prevTime = time;
182 }
183 for (Entry<String, double[]> entry : fYValues.entrySet()) {
184 setSeries(entry.getKey(), entry.getValue());
185 }
186 if (monitor.isCanceled()) {
187 return;
188 }
189 updateDisplay();
190 }
191 } catch (StateValueTypeException e) {
192 Activator.getDefault().logError("Error updating the data of the CPU usage view", e); //$NON-NLS-1$
193 }
194
195 }
196
197 /**
198 * Set the selected thread ID, which will be graphed in this viewer
199 *
200 * @param tid
201 * The selected thread ID
202 */
203 public void setSelectedThread(long tid) {
204 cancelUpdate();
205 deleteSeries(Long.toString(fSelectedThread));
206 fSelectedThread = tid;
207 updateContent();
208 }
209
210 }
This page took 0.054787 seconds and 5 git commands to generate.