lttng: Add unit tests for the CPU usage analysis
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Wed, 29 Oct 2014 17:06:08 +0000 (13:06 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Wed, 3 Dec 2014 20:12:55 +0000 (15:12 -0500)
The unit tests make use of the XML development trace.

Also correct the fact that a process that hasn't run yet started at -1 instead
of 0. There probably was a reason in the original implementation, but 0 works
fine now.

Change-Id: I3196155c050db32fd6b954abfd73252c1dc89aa3
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/35647
Tested-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF
org.eclipse.tracecompass.lttng2.kernel.core.tests/build.properties
org.eclipse.tracecompass.lttng2.kernel.core.tests/plugin.xml [new file with mode: 0644]
org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/Activator.java [new file with mode: 0644]
org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/AllTests.java
org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/cpuusage/AllTests.java [new file with mode: 0644]
org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/cpuusage/CpuUsageStateProviderTest.java [new file with mode: 0644]
org.eclipse.tracecompass.lttng2.kernel.core.tests/testfiles/cpu_analysis.xml [new file with mode: 0644]
org.eclipse.tracecompass.lttng2.kernel.core/src/org/eclipse/tracecompass/lttng2/kernel/core/analysis/cpuusage/LttngKernelCpuUsageAnalysis.java
org.eclipse.tracecompass.lttng2.kernel.core/src/org/eclipse/tracecompass/lttng2/kernel/core/analysis/cpuusage/LttngKernelCpuUsageStateProvider.java
org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statesystem/TmfStateSystemAnalysisModule.java

index f50cbfc961f38f91a72fcbe492259a6bd2aacfae..4f7ad99a233717db81aa7c4997e91960039558d7 100644 (file)
@@ -5,6 +5,7 @@ Bundle-Vendor: %Bundle-Vendor
 Bundle-Version: 0.1.0.qualifier
 Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.tracecompass.lttng2.kernel.core.tests;singleton:=true
+Bundle-Activator: org.eclipse.tracecompass.lttng2.kernel.core.tests.Activator
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Require-Bundle: org.junit;bundle-version="4.0.0",
index 34a39c903e696b9c100ea986645d61ef63665c5e..74d42da1c609d2381cd2b89e877cda40f8b4a2c7 100644 (file)
@@ -15,7 +15,8 @@ source.. = src/,\
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
-               plugin.properties
+               plugin.properties,\
+               plugin.xml
 src.includes = about.html
 additional.bundles = org.eclipse.jdt.annotation
 jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/plugin.xml b/org.eclipse.tracecompass.lttng2.kernel.core.tests/plugin.xml
new file mode 100644 (file)
index 0000000..a69b0e7
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.linuxtools.tmf.core.analysis">
+      <module
+            analysis_module="org.eclipse.tracecompass.lttng2.kernel.core.analysis.cpuusage.LttngKernelCpuUsageAnalysis"
+            automatic="false"
+            id="lttng2.kernel.core.tests.cpuusage"
+            name="lttng2.kernel.core.tests.cpuusage">
+         <tracetype
+               applies="true"
+               class="org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub">
+         </tracetype>
+      </module>
+      <module
+            analysis_module="org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelAnalysis"
+            automatic="false"
+            id="lttng2.kernel.core.tests.kernel.analysis"
+            name="lttng2.kernel.core.tests.kernel.analysis">
+         <tracetype
+               applies="true"
+               class="org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub">
+         </tracetype>
+      </module>
+   </extension>
+
+</plugin>
diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/Activator.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/Activator.java
new file mode 100644 (file)
index 0000000..2b12ca1
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.lttng2.kernel.core.tests;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Activator for the lttng2.kernel.core.tests plugin
+ *
+ * @author Geneviève Bastien
+ */
+public class Activator extends Plugin {
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    /**
+     * The plug-in ID
+     */
+    public static final String PLUGIN_ID = "org.eclipse.tracecompass.lttng2.kernel.core.tests"; //$NON-NLS-1$
+
+    /**
+     * The shared instance
+     */
+    private static Activator PLUGIN;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * The constructor
+     */
+    public Activator() {
+    }
+
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static Activator getDefault() {
+        return PLUGIN;
+    }
+
+    // ------------------------------------------------------------------------
+    // Operators
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        PLUGIN = this;
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        PLUGIN = null;
+        super.stop(context);
+    }
+
+    /**
+     * Return a path to a file relative to this plugin's base directory
+     *
+     * @param relativePath
+     *            The path relative to the plugin's root directory
+     * @return The path corresponding to the relative path in parameter
+     */
+    public static IPath getAbsoluteFilePath(String relativePath) {
+        Activator plugin = Activator.getDefault();
+        if (plugin == null) {
+            /*
+             * Shouldn't happen but at least throw something to get the test to
+             * fail early
+             */
+            throw new IllegalStateException();
+        }
+        URL location = FileLocator.find(plugin.getBundle(), new Path(relativePath), null);
+        try {
+            return new Path(FileLocator.toFileURL(location).getPath());
+        } catch (IOException e) {
+            throw new IllegalStateException();
+        }
+    }
+}
index 200f2467ff5ded73c1aabf85041583e88b48d5cf..93d6a6b9cc95b001e349dea498e4fb778d9a2c0d 100644 (file)
@@ -21,6 +21,7 @@ import org.junit.runner.RunWith;
 @RunWith(DebugSuite.class)
 @DebugSuite.SuiteClasses({
     ActivatorTest.class,
+    org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.cpuusage.AllTests.class,
     org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.kernel.AllTests.class,
     org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.kernel.statesystem.TestAll.class,
     org.eclipse.tracecompass.lttng2.kernel.core.tests.event.matchandsync.AllTests.class
diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/cpuusage/AllTests.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/cpuusage/AllTests.java
new file mode 100644 (file)
index 0000000..7eb2314
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.cpuusage;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for the lttng2.kernel CPU usage package
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+    CpuUsageStateProviderTest.class
+})
+public class AllTests {
+
+}
\ No newline at end of file
diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/cpuusage/CpuUsageStateProviderTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/cpuusage/CpuUsageStateProviderTest.java
new file mode 100644 (file)
index 0000000..10e32aa
--- /dev/null
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.cpuusage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
+import org.eclipse.tracecompass.lttng2.kernel.core.analysis.cpuusage.LttngKernelCpuUsageAnalysis;
+import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelAnalysis;
+import org.eclipse.tracecompass.lttng2.kernel.core.tests.Activator;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
+import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test suite for the {@link LttngKernelCpuUsageAnalysis} class
+ *
+ * @author Geneviève Bastien
+ */
+public class CpuUsageStateProviderTest {
+
+    private static final String CPU_USAGE_FILE = "testfiles/cpu_analysis.xml";
+    /**
+     * The ID of the cpu usage analysis module for development traces
+     */
+    public static final String CPU_USAGE_ANALYSIS_ID = "lttng2.kernel.core.tests.cpuusage";
+
+    private ITmfTrace fTrace;
+    private LttngKernelCpuUsageAnalysis fModule;
+
+    private static void deleteSuppFiles(ITmfTrace trace) {
+        /* Remove supplementary files */
+        File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
+        for (File file : suppDir.listFiles()) {
+            file.delete();
+        }
+    }
+
+    /**
+     * Setup the trace for the tests
+     */
+    @Before
+    public void setUp() {
+        fTrace = new TmfXmlTraceStub();
+        IPath filePath = Activator.getAbsoluteFilePath(CPU_USAGE_FILE);
+        IStatus status = fTrace.validate(null, filePath.toOSString());
+        if (!status.isOK()) {
+            fail(status.getException().getMessage());
+        }
+        try {
+            fTrace.initTrace(null, filePath.toOSString(), TmfEvent.class);
+        } catch (TmfTraceException e) {
+            fail(e.getMessage());
+        }
+        deleteSuppFiles(fTrace);
+        ((TmfTrace) fTrace).traceOpened(new TmfTraceOpenedSignal(this, fTrace, null));
+        /*
+         * FIXME: Make sure this analysis is finished before running the CPU
+         * analysis. This block can be removed once analysis dependency and
+         * request precedence is implemented
+         */
+        IAnalysisModule module = null;
+        for (IAnalysisModule mod : TmfTraceUtils.getAnalysisModulesOfClass(fTrace, LttngKernelAnalysis.class)) {
+            module = mod;
+        }
+        assertNotNull(module);
+        module.schedule();
+        module.waitForCompletion();
+        /* End of the FIXME block */
+        fModule = TmfTraceUtils.getAnalysisModuleOfClass(fTrace, LttngKernelCpuUsageAnalysis.class, CPU_USAGE_ANALYSIS_ID);
+        assertNotNull(fModule);
+    }
+
+    /**
+     * Clean up
+     */
+    @After
+    public void tearDown() {
+        deleteSuppFiles(fTrace);
+        fTrace.dispose();
+    }
+
+    /**
+     * Test that the analysis executes without problems
+     */
+    @Test
+    public void testAnalysisExecution() {
+        /* Make sure the analysis hasn't run yet */
+        assertNull(fModule.getStateSystem());
+
+        /* Execute the analysis */
+        assertTrue(TmfTestHelper.executeAnalysis(fModule));
+        assertNotNull(fModule.getStateSystem());
+    }
+
+    /**
+     * Test that the state system is returned with the expected results
+     */
+    @Test
+    public void testReturnedStateSystem() {
+        fModule.schedule();
+        fModule.waitForCompletion();
+        ITmfStateSystem ss = fModule.getStateSystem();
+        assertNotNull(ss);
+        assertEquals(1L, ss.getStartTime());
+        assertEquals(25L, ss.getCurrentEndTime());
+
+        try {
+            int cpusQuark = ss.getQuarkAbsolute(Attributes.CPUS);
+
+            /*
+             * There should be 2 CPU entries: 0 and 1 and 3 process entries
+             * under each
+             */
+            List<Integer> cpuQuarks = ss.getSubAttributes(cpusQuark, false);
+            assertEquals(2, cpuQuarks.size());
+            for (Integer cpuQuark : cpuQuarks) {
+                assertEquals(3, ss.getSubAttributes(cpuQuark, false).size());
+            }
+
+            /* Proc 2 on CPU 0 should run from 1 to 20 seconds */
+            int proc2Quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", "2");
+            ITmfStateInterval interval = ss.querySingleState(2L, proc2Quark);
+            assertEquals(1L, interval.getStartTime());
+            assertEquals(19L, interval.getEndTime());
+
+            /*
+             * Query at the end and make sure all processes on all CPU have the
+             * expected values
+             */
+            Map<String, Long> expected = new HashMap<>();
+            expected.put("CPUs/0/1", 0L);
+            expected.put("CPUs/0/2", 19L);
+            expected.put("CPUs/0/3", 5L);
+            expected.put("CPUs/1/1", 5L);
+            expected.put("CPUs/1/3", 6L);
+            expected.put("CPUs/1/4", 8L);
+            List<ITmfStateInterval> intervals = ss.queryFullState(25L);
+            Map<String, Long> intervalMap = new HashMap<>();
+            for (ITmfStateInterval oneInterval : intervals) {
+                if (!oneInterval.getStateValue().isNull()) {
+                    intervalMap.put(ss.getFullAttributePath(oneInterval.getAttribute()), oneInterval.getStateValue().unboxLong());
+                }
+            }
+            assertEquals(expected, intervalMap);
+
+        } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Test the
+     * {@link LttngKernelCpuUsageAnalysis#getCpuUsageInRange(long, long)}
+     * method.
+     */
+    @Test
+    public void testUsageInRange() {
+        fModule.schedule();
+        fModule.waitForCompletion();
+
+        /* This range should query the total range */
+        Map<String, Long> expected = new HashMap<>();
+        expected.put("0/1", 0L);
+        expected.put("0/2", 19L);
+        expected.put("0/3", 5L);
+        expected.put("1/1", 5L);
+        expected.put("1/3", 6L);
+        expected.put("1/4", 13L);
+        expected.put("total", 48L);
+        expected.put("total/1", 5L);
+        expected.put("total/2", 19L);
+        expected.put("total/3", 11L);
+        expected.put("total/4", 13L);
+        expected.put("0", 24L);
+        expected.put("1", 24L);
+        Map<String, Long> resultMap = fModule.getCpuUsageInRange(0L, 30L);
+        assertEquals(expected, resultMap);
+
+        /* Verify a range when a process runs at the start */
+        expected.clear();
+        expected.put("0/1", 0L);
+        expected.put("0/2", 0L);
+        expected.put("0/3", 3L);
+        expected.put("1/1", 0L);
+        expected.put("1/3", 0L);
+        expected.put("1/4", 3L);
+        expected.put("total", 6L);
+        expected.put("total/1", 0L);
+        expected.put("total/2", 0L);
+        expected.put("total/3", 3L);
+        expected.put("total/4", 3L);
+        expected.put("0", 3L);
+        expected.put("1", 3L);
+        resultMap = fModule.getCpuUsageInRange(22L, 25L);
+        assertEquals(expected, resultMap);
+
+        /* Verify a range when a process runs at the end */
+        expected.clear();
+        expected.put("0/1", 0L);
+        expected.put("0/2", 3L);
+        expected.put("0/3", 0L);
+        expected.put("1/1", 0L);
+        expected.put("1/3", 1L);
+        expected.put("1/4", 2L);
+        expected.put("total", 6L);
+        expected.put("total/1", 0L);
+        expected.put("total/2", 3L);
+        expected.put("total/3", 1L);
+        expected.put("total/4", 2L);
+        expected.put("0", 3L);
+        expected.put("1", 3L);
+        resultMap = fModule.getCpuUsageInRange(1L, 4L);
+        assertEquals(expected, resultMap);
+
+        /* Verify a range when a process runs at start and at the end */
+        expected.clear();
+        expected.put("0/1", 0L);
+        expected.put("0/2", 9L);
+        expected.put("0/3", 0L);
+        expected.put("1/1", 0L);
+        expected.put("1/3", 5L);
+        expected.put("1/4", 4L);
+        expected.put("total", 18L);
+        expected.put("total/1", 0L);
+        expected.put("total/2", 9L);
+        expected.put("total/3", 5L);
+        expected.put("total/4", 4L);
+        expected.put("0", 9L);
+        expected.put("1", 9L);
+        resultMap = fModule.getCpuUsageInRange(4L, 13L);
+        assertEquals(expected, resultMap);
+
+    }
+}
diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/testfiles/cpu_analysis.xml b/org.eclipse.tracecompass.lttng2.kernel.core.tests/testfiles/cpu_analysis.xml
new file mode 100644 (file)
index 0000000..e403f3c
--- /dev/null
@@ -0,0 +1,85 @@
+<trace>
+<event timestamp="0" name="set_aspects">
+<field name="cpu" value="1" type="int" />
+</event>
+<event timestamp="1" name="sched_switch">
+<field name="cpu" value="0" type="int" />
+<field name="prev_comm" value="proc1" type="string" />
+<field name="prev_tid" value="1" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc2" type="string" />
+<field name="next_tid" value="2" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="2" name="sched_switch">
+<field name="cpu" value="1" type="int" />
+<field name="prev_comm" value="proc3" type="string" />
+<field name="prev_tid" value="3" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc4" type="string" />
+<field name="next_tid" value="4" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="5" name="sched_switch">
+<field name="cpu" value="1" type="int" />
+<field name="prev_comm" value="proc4" type="string" />
+<field name="prev_tid" value="4" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc3" type="string" />
+<field name="next_tid" value="3" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="10" name="sched_switch">
+<field name="cpu" value="1" type="int" />
+<field name="prev_comm" value="proc3" type="string" />
+<field name="prev_tid" value="3" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc4" type="string" />
+<field name="next_tid" value="4" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="15" name="sched_switch">
+<field name="cpu" value="1" type="int" />
+<field name="prev_comm" value="proc4" type="string" />
+<field name="prev_tid" value="4" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc1" type="string" />
+<field name="next_tid" value="1" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="20" name="sched_switch">
+<field name="cpu" value="1" type="int" />
+<field name="prev_comm" value="proc1" type="string" />
+<field name="prev_tid" value="1" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc4" type="string" />
+<field name="next_tid" value="4" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="20" name="sched_switch">
+<field name="cpu" value="0" type="int" />
+<field name="prev_comm" value="proc2" type="string" />
+<field name="prev_tid" value="2" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc3" type="string" />
+<field name="next_tid" value="3" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+<event timestamp="25" name="sched_switch">
+<field name="cpu" value="0" type="int" />
+<field name="prev_comm" value="proc3" type="string" />
+<field name="prev_tid" value="3" type="long" />
+<field name="prev_prio" value="20" type="int" />
+<field name="prev_state" value="0" type="long" />
+<field name="next_comm" value="proc2" type="string" />
+<field name="next_tid" value="2" type="long" />
+<field name="next_prio" value="20" type="int" />
+</event>
+</trace>
\ No newline at end of file
index 569b0fe71af895e3014f8b070f86fc0965d26cba..4786025d018505fc651aa6e4a029a56842933717 100644 (file)
@@ -115,7 +115,7 @@ public class LttngKernelCpuUsageAnalysis extends TmfStateSystemAnalysisModule {
         if (trace == null || cpuSs == null) {
             return map;
         }
-        ITmfStateSystem kernelSs = TmfStateSystemAnalysisModule.getStateSystem(trace, LttngKernelAnalysis.ID);
+        ITmfStateSystem kernelSs = TmfStateSystemAnalysisModule.getStateSystemByModuleClass(trace, LttngKernelAnalysis.class);
         if (kernelSs == null) {
             return map;
         }
index ce5004bde75fc445af8c0de1d3577e60a5a19cf3..81b044d956789aebc06b000bf4835d4d532bf892 100644 (file)
@@ -46,7 +46,7 @@ import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
  */
 public class LttngKernelCpuUsageStateProvider extends AbstractTmfStateProvider {
 
-    private static final int VERSION = 1;
+    private static final int VERSION = 2;
 
     /* For each CPU, maps the last time a thread was scheduled in */
     private final Map<Integer, Long> fLastStartTimes = new HashMap<>();
@@ -137,7 +137,7 @@ public class LttngKernelCpuUsageStateProvider extends AbstractTmfStateProvider {
                      * time changes when the process is scheduled out. Nothing
                      * happens when the process is scheduled in.
                      */
-                    long prevCumulativeTime = value.unboxLong();
+                    long prevCumulativeTime = Math.max(0, value.unboxLong());
                     long newCumulativeTime = prevCumulativeTime + (ts - startTime);
 
                     value = TmfStateValue.newValueLong(newCumulativeTime);
index 4bc675f8596c31babf208d458dda6754e93debba..ec84d4782a9cd101d6d2cd5f5af831203a9b4eb4 100644 (file)
@@ -93,7 +93,6 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         PARTIAL
     }
 
-
     /**
      * Retrieve a state system belonging to trace, by passing the ID of the
      * relevant analysis module.
@@ -121,6 +120,36 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         return null;
     }
 
+    /**
+     * Retrieve a state system belonging to trace, by passing the class of the
+     * relevant analysis module. If many modules of the same class exists, the
+     * state system of the first one will be returned.
+     *
+     * This will start the execution of the analysis module, and start the
+     * construction of the state system, if needed.
+     *
+     * @param trace
+     *            The trace for which you want the state system
+     * @param clazz
+     *            The class of the state system module to retrieve
+     * @return The state system, or null if there was no match
+     */
+    public static @Nullable ITmfStateSystem getStateSystemByModuleClass(ITmfTrace trace, Class<? extends TmfStateSystemAnalysisModule> clazz) {
+        TmfStateSystemAnalysisModule module = null;
+        for (TmfStateSystemAnalysisModule mod : TmfTraceUtils.getAnalysisModulesOfClass(trace, clazz)) {
+            module = mod;
+            break;
+        }
+        if (module != null) {
+            IStatus status = module.schedule();
+            if (status.isOK()) {
+                module.waitForInitialization();
+                return module.getStateSystem();
+            }
+        }
+        return null;
+    }
+
     /**
      * Get the state provider for this analysis module
      *
This page took 0.034555 seconds and 5 git commands to generate.