From 17a3454d10d511587f2a7e597fb5251ed123b653 Mon Sep 17 00:00:00 2001 From: Matthew Khouzam Date: Thu, 28 Jan 2016 17:35:43 -0500 Subject: [PATCH] analysis: add per-cpu cpu usage to analysis Query with a set of desired cpus, or an empty set for everything. This allows the analyses to filter on a per-cpu basis. The cpu analysis now can be queried as follows: This example has 4 cpus named, 0 to 3 module.getCpuUsageInRange( {}, tStart, tEnd) will get all cpus. module.getCpuUsageInRange( {0,1,2,3}, tStart, tEnd) returns the same. module.getCpuUsageInRange( {0}, tStart, tEnd) will return a subset of the previous queries, affecting only CPU 0. Note that this affects the totals too, the total is calculated on the fly. Change-Id: Ie6a606763f4331aeef06b2916a7f98d9c73fc9d5 Signed-off-by: Matthew Khouzam Reviewed-on: https://git.eclipse.org/r/65418 Reviewed-by: Genevieve Bastien Tested-by: Genevieve Bastien Reviewed-by: Hudson CI --- .../cpuusage/CpuUsageStateProviderTest.java | 52 +++++++++++++++++-- .../core/cpuusage/KernelCpuUsageAnalysis.java | 38 +++++++++++++- .../ui/views/cpuusage/CpuUsageComposite.java | 2 +- .../ui/views/cpuusage/CpuUsageXYViewer.java | 5 +- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageStateProviderTest.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageStateProviderTest.java index 9f7a7be4b3..875cc12fcb 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageStateProviderTest.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageStateProviderTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.fail; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -52,6 +53,8 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import com.google.common.collect.ImmutableSet; + /** * Test suite for the {@link KernelCpuUsageAnalysis} class * @@ -200,8 +203,11 @@ public class CpuUsageStateProviderTest { } /** - * Test the {@link KernelCpuUsageAnalysis#getCpuUsageInRange(long, long)} + * Test the + * {@link KernelCpuUsageAnalysis#getCpuUsageInRange(java.util.Set, long, long)} * method. + *

+ * TODO: extend! */ @Test public void testUsageInRange() { @@ -223,7 +229,7 @@ public class CpuUsageStateProviderTest { expected.put("total/4", 13L); expected.put("0", 24L); expected.put("1", 24L); - Map resultMap = fModule.getCpuUsageInRange(0L, 30L); + Map resultMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, 0L, 30L); assertEquals(expected, resultMap); /* Verify a range when a process runs at the start */ @@ -241,7 +247,7 @@ public class CpuUsageStateProviderTest { expected.put("total/4", 3L); expected.put("0", 3L); expected.put("1", 3L); - resultMap = fModule.getCpuUsageInRange(22L, 25L); + resultMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, 22L, 25L); assertEquals(expected, resultMap); /* Verify a range when a process runs at the end */ @@ -259,7 +265,7 @@ public class CpuUsageStateProviderTest { expected.put("total/4", 2L); expected.put("0", 3L); expected.put("1", 3L); - resultMap = fModule.getCpuUsageInRange(1L, 4L); + resultMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, 1L, 4L); assertEquals(expected, resultMap); /* Verify a range when a process runs at start and at the end */ @@ -277,7 +283,43 @@ public class CpuUsageStateProviderTest { expected.put("total/4", 4L); expected.put("0", 9L); expected.put("1", 9L); - resultMap = fModule.getCpuUsageInRange(4L, 13L); + resultMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, 4L, 13L); + assertEquals(expected, resultMap); + } + + /** + * Tests the cpu usage for a cpu subset within a range + */ + @Test + public void testInRangeWithCpuSubset() { + + fModule.schedule(); + fModule.waitForCompletion(); + + /* Verify a range when a process runs at start and at the end */ + Map expected = new HashMap<>(); + expected.put("0/1", 0L); + expected.put("0/2", 9L); + expected.put("0/3", 0L); + expected.put("total/1", 0L); + expected.put("total/2", 9L); + expected.put("total/3", 0L); + expected.put("0", 9L); + expected.put("total", 9L); + Map resultMap = fModule.getCpuUsageInRange(Collections.<@NonNull Integer> singleton(0), 4L, 13L); + assertEquals(expected, resultMap); + + /* Verify a range when a process runs at start and at the end */ + expected.clear(); + expected.put("1/1", 0L); + expected.put("1/3", 5L); + expected.put("1/4", 4L); + expected.put("total/1", 0L); + expected.put("total/3", 5L); + expected.put("total/4", 4L); + expected.put("1", 9L); + expected.put("total", 9L); + resultMap = fModule.getCpuUsageInRange(ImmutableSet.of(1,2), 4L, 13L); assertEquals(expected, resultMap); } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/KernelCpuUsageAnalysis.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/KernelCpuUsageAnalysis.java index 7d713e68e4..24e496d3a1 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/KernelCpuUsageAnalysis.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/KernelCpuUsageAnalysis.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes; import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysisModule; import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout; @@ -97,16 +98,46 @@ public class KernelCpuUsageAnalysis extends TmfStateSystemAnalysisModule { return modules; } + /** + * Gets the maximum number of cores detected + * + * @return the number of cores + * @since 2.0 + */ + public int getNumberOfCores() { + + ITmfStateSystem cpuSs = getStateSystem(); + if (cpuSs != null) { + try { + int cpusNode = cpuSs.getQuarkAbsolute(Attributes.CPUS); + final @NonNull List<@NonNull Integer> subAttributes = cpuSs.getSubAttributes(cpusNode, false); + int cpus = Integer.MIN_VALUE; + for (Integer quark : subAttributes) { + cpus = Math.max(Integer.parseInt(cpuSs.getAttributeName(quark)), cpus); + } + return Math.max(subAttributes.size(), cpus); + } catch (AttributeNotFoundException e) { + Activator.getDefault().logError(e.getMessage(), e); + } + } + return -1; + + } + /** * Get a map of time spent on CPU by various threads during a time range. * + * @param cpus + * A set of the desired CPUs to get. An empty set gets all the + * cores * @param start * Start time of requested range * @param end * End time of requested range * @return A map of TID -> time spent on CPU in the [start, end] interval + * @since 2.0 */ - public Map getCpuUsageInRange(long start, long end) { + public Map getCpuUsageInRange(Set<@NonNull Integer> cpus, long start, long end) { Map map = new HashMap<>(); Map totalMap = new HashMap<>(); @@ -138,7 +169,10 @@ public class KernelCpuUsageAnalysis extends TmfStateSystemAnalysisModule { int cpusNode = cpuSs.getQuarkAbsolute(Attributes.CPUS); Map> tidsPerCpu = new HashMap<>(); for (int cpuNode : cpuSs.getSubAttributes(cpusNode, false)) { - tidsPerCpu.put(cpuNode, cpuSs.getSubAttributes(cpuNode, false)); + final @NonNull List<@NonNull Integer> cpuSubAttributes = cpuSs.getSubAttributes(cpuNode, false); + if (cpus.isEmpty() || cpus.contains(Integer.parseInt(cpuSs.getAttributeName(cpuNode)))) { + tidsPerCpu.put(cpuNode, cpuSubAttributes); + } } /* Query full states at start and end times */ diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageComposite.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageComposite.java index ec51353a92..f1b7e03655 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageComposite.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageComposite.java @@ -230,7 +230,7 @@ public class CpuUsageComposite extends AbstractTmfTreeViewer { } /* Initialize the data */ - Map cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, getStartTime()), Math.min(end, getEndTime())); + Map cpuUsageMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, Math.max(start, getStartTime()), Math.min(end, getEndTime())); TmfTreeViewerEntry root = new TmfTreeViewerEntry(""); //$NON-NLS-1$ List entryList = root.getChildren(); diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java index e1e1478c14..3b6d05e786 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java @@ -15,6 +15,7 @@ package org.eclipse.tracecompass.analysis.os.linux.ui.views.cpuusage; import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -117,7 +118,7 @@ public class CpuUsageXYViewer extends TmfCommonXLineChartViewer { currentEnd = ss.getCurrentEndTime(); /* Initialize the data */ - Map cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, traceStart), Math.min(end, traceEnd)); + Map cpuUsageMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, Math.max(start, traceStart), Math.min(end, traceEnd)); Map totalEntries = new HashMap<>(); fYValues.clear(); fYValues.put(Messages.CpuUsageXYViewer_Total, zeroFill(xvalues.length)); @@ -171,7 +172,7 @@ public class CpuUsageXYViewer extends TmfCommonXLineChartViewer { prevTime = time - 1; } - cpuUsageMap = fModule.getCpuUsageInRange(prevTime, time); + cpuUsageMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, prevTime, time); /* * Calculate the sum of all total entries, and add a data -- 2.34.1