analysis: add per-cpu cpu usage to analysis
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Thu, 28 Jan 2016 22:35:43 +0000 (17:35 -0500)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Tue, 8 Mar 2016 17:01:34 +0000 (12:01 -0500)
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 <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/65418
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Reviewed-by: Hudson CI
analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageStateProviderTest.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/KernelCpuUsageAnalysis.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageComposite.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java

index 9f7a7be4b3f4cb50e0619614f806ef6a997871e5..875cc12fcbd5c4292f895ad339e22183de6ebf88 100644 (file)
@@ -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.
+     * <p>
+     * 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<String, Long> resultMap = fModule.getCpuUsageInRange(0L, 30L);
+        Map<String, Long> 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<String, Long> 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<String, Long> 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);
 
     }
index 7d713e68e474b118a57e4e2bd4fbb38ba9deeba2..24e496d3a1756b727c9b9bfc1fc1f99eaa6e4298 100644 (file)
@@ -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<String, Long> getCpuUsageInRange(long start, long end) {
+    public Map<String, Long> getCpuUsageInRange(Set<@NonNull Integer> cpus, long start, long end) {
         Map<String, Long> map = new HashMap<>();
         Map<String, Long> totalMap = new HashMap<>();
 
@@ -138,7 +169,10 @@ public class KernelCpuUsageAnalysis extends TmfStateSystemAnalysisModule {
             int cpusNode = cpuSs.getQuarkAbsolute(Attributes.CPUS);
             Map<Integer, List<Integer>> 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 */
index ec51353a92ef4b51e0441505e636d322f69660ce..f1b7e03655a70d87913278d17b663471647762ff 100644 (file)
@@ -230,7 +230,7 @@ public class CpuUsageComposite extends AbstractTmfTreeViewer {
         }
 
         /* Initialize the data */
-        Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, getStartTime()), Math.min(end, getEndTime()));
+        Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, Math.max(start, getStartTime()), Math.min(end, getEndTime()));
 
         TmfTreeViewerEntry root = new TmfTreeViewerEntry(""); //$NON-NLS-1$
         List<ITmfTreeViewerEntry> entryList = root.getChildren();
index e1e1478c14219fc304563a70c709fe3abe4aa904..3b6d05e7865f8236afba9b3efdf88cdfd5a3f492 100644 (file)
@@ -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<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Math.max(start, traceStart), Math.min(end, traceEnd));
+                Map<String, Long> cpuUsageMap = fModule.getCpuUsageInRange(Collections.EMPTY_SET, Math.max(start, traceStart), Math.min(end, traceEnd));
                 Map<String, String> 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
This page took 0.031075 seconds and 5 git commands to generate.