import java.util.Map.Entry;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Activator;
import org.eclipse.linuxtools.lttng2.kernel.core.cpuusage.LttngKernelCpuUsageAnalysis;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
-import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
+import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer;
import org.eclipse.swt.widgets.Composite;
*/
private static final double RESOLUTION = 0.4;
+ // Timeout between updates in the updateData thread
+ private static final long BUILD_UPDATE_TIMEOUT = 500;
+
private long fSelectedThread = -1;
/**
*
* @param parent
* parent composite
- * @param treeViewer
- * The tree viewer containing the list of threads with CPU usage.
- * A listener will be added to that viewer so it can synchronize
- * with the selection from the viewer.
*/
- public CpuUsageXYViewer(Composite parent, CpuUsageComposite treeViewer) {
+ public CpuUsageXYViewer(Composite parent) {
super(parent, Messages.CpuUsageXYViewer_Title, Messages.CpuUsageXYViewer_TimeXAxis, Messages.CpuUsageXYViewer_CpuYAxis);
setResolution(RESOLUTION);
-
- /* Add selection listener to tree viewer */
- treeViewer.addSelectionChangeListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- if (event.getSelection() instanceof IStructuredSelection) {
- Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
- if (selection instanceof CpuUsageEntry) {
- CpuUsageEntry entry = (CpuUsageEntry) selection;
- setSelectedThread(Long.valueOf(entry.getTid()));
- }
- }
- }
- });
}
@Override
if (getTrace() == null || fModule == null) {
return;
}
+ fModule.waitForInitialization();
ITmfStateSystem ss = fModule.getStateSystem();
- /*
- * Don't wait for the module completion or initialization, when it's
- * ready, we'll know
- */
if (ss == null) {
return;
}
}
setXAxis(xvalues);
- long traceStart = getStartTime();
- long traceEnd = getEndTime();
- long offset = getTimeOffset();
- long selectedThread = fSelectedThread;
-
- /* Initialize the data */
- Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, traceStart), Math.min(end, traceEnd));
- Map<String, String> totalEntries = new HashMap<>();
- fYValues.clear();
- fYValues.put(Messages.CpuUsageXYViewer_Total, zeroFill(xvalues.length));
- String stringSelectedThread = Long.toString(selectedThread);
- if (selectedThread != -1) {
- fYValues.put(stringSelectedThread, zeroFill(xvalues.length));
- }
+ boolean complete = false;
+ long currentEnd = start;
- for (Entry<String, Long> entry : cpuUsageMap.entrySet()) {
- /*
- * Process only entries representing the total of all CPUs and
- * that have time on CPU
- */
- if (entry.getValue() == 0) {
- continue;
- }
- if (!entry.getKey().startsWith(LttngKernelCpuUsageAnalysis.TOTAL)) {
- continue;
- }
- String[] strings = entry.getKey().split(LttngKernelCpuUsageAnalysis.SPLIT_STRING, 2);
-
- if ((strings.length > 1) && !(strings[1].equals(LttngKernelCpuUsageAnalysis.TID_ZERO))) {
- /* This is the total cpu usage for a thread */
- totalEntries.put(strings[1], entry.getKey());
- }
- }
+ while (!complete && currentEnd < end) {
- double prevX = xvalues[0];
- long prevTime = (long) prevX + offset;
- /*
- * make sure that time is in the trace range after double to long
- * conversion
- */
- prevTime = Math.max(traceStart, prevTime);
- prevTime = Math.min(traceEnd, prevTime);
- /* Get CPU usage statistics for each x value */
- for (int i = 1; i < xvalues.length; i++) {
if (monitor.isCanceled()) {
return;
}
- long totalCpu = 0;
- double x = xvalues[i];
- long time = (long) x + offset;
- time = Math.max(traceStart, time);
- time = Math.min(traceEnd, time);
- cpuUsageMap = fModule.getCpuUsageInRange(prevTime, time);
+ long traceStart = getStartTime();
+ long traceEnd = getEndTime();
+ long offset = getTimeOffset();
+ long selectedThread = fSelectedThread;
+
+ complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
+ currentEnd = ss.getCurrentEndTime();
+
+ /* Initialize the data */
+ Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, traceStart), Math.min(end, traceEnd));
+ Map<String, String> totalEntries = new HashMap<>();
+ fYValues.clear();
+ fYValues.put(Messages.CpuUsageXYViewer_Total, zeroFill(xvalues.length));
+ String stringSelectedThread = Long.toString(selectedThread);
+ if (selectedThread != -1) {
+ fYValues.put(stringSelectedThread, zeroFill(xvalues.length));
+ }
+
+ for (Entry<String, Long> entry : cpuUsageMap.entrySet()) {
+ /*
+ * Process only entries representing the total of all CPUs
+ * and that have time on CPU
+ */
+ if (entry.getValue() == 0) {
+ continue;
+ }
+ if (!entry.getKey().startsWith(LttngKernelCpuUsageAnalysis.TOTAL)) {
+ continue;
+ }
+ String[] strings = entry.getKey().split(LttngKernelCpuUsageAnalysis.SPLIT_STRING, 2);
+
+ if ((strings.length > 1) && !(strings[1].equals(LttngKernelCpuUsageAnalysis.TID_ZERO))) {
+ /* This is the total cpu usage for a thread */
+ totalEntries.put(strings[1], entry.getKey());
+ }
+ }
+ double prevX = xvalues[0];
+ long prevTime = (long) prevX + offset;
/*
- * Calculate the sum of all total entries, and add a data point
- * to the selected one
+ * make sure that time is in the trace range after double to
+ * long conversion
*/
- for (Entry<String, String> entry : totalEntries.entrySet()) {
- Long cpuEntry = cpuUsageMap.get(entry.getValue());
- cpuEntry = cpuEntry != null ? cpuEntry : 0L;
+ prevTime = Math.max(traceStart, prevTime);
+ prevTime = Math.min(traceEnd, prevTime);
+ /* Get CPU usage statistics for each x value */
+ for (int i = 1; i < xvalues.length; i++) {
+ if (monitor.isCanceled()) {
+ return;
+ }
+ long totalCpu = 0;
+ double x = xvalues[i];
+ long time = (long) x + offset;
+ time = Math.max(traceStart, time);
+ time = Math.min(traceEnd, time);
- totalCpu += cpuEntry;
+ cpuUsageMap = fModule.getCpuUsageInRange(prevTime, time);
- if (entry.getKey().equals(stringSelectedThread)) {
- /* This is the total cpu usage for a thread */
- fYValues.get(entry.getKey())[i] = (double) cpuEntry / (double) (time - prevTime) * 100;
- }
+ /*
+ * Calculate the sum of all total entries, and add a data
+ * point to the selected one
+ */
+ for (Entry<String, String> entry : totalEntries.entrySet()) {
+ Long cpuEntry = cpuUsageMap.get(entry.getValue());
+ cpuEntry = cpuEntry != null ? cpuEntry : 0L;
+
+ totalCpu += cpuEntry;
+
+ if (entry.getKey().equals(stringSelectedThread)) {
+ /* This is the total cpu usage for a thread */
+ fYValues.get(entry.getKey())[i] = (double) cpuEntry / (double) (time - prevTime) * 100;
+ }
+ }
+ fYValues.get(Messages.CpuUsageXYViewer_Total)[i] = (double) totalCpu / (double) (time - prevTime) * 100;
+ prevTime = time;
}
- fYValues.get(Messages.CpuUsageXYViewer_Total)[i] = (double) totalCpu / (double) (time - prevTime) * 100;
- prevTime = time;
- }
- for (Entry<String, double[]> entry : fYValues.entrySet()) {
- setSeries(entry.getKey(), entry.getValue());
- }
- if (monitor.isCanceled()) {
- return;
+ for (Entry<String, double[]> entry : fYValues.entrySet()) {
+ setSeries(entry.getKey(), entry.getValue());
+ }
+ if (monitor.isCanceled()) {
+ return;
+ }
+ updateDisplay();
}
- updateDisplay();
} catch (StateValueTypeException e) {
Activator.getDefault().logError("Error updating the data of the CPU usage view", e); //$NON-NLS-1$
}