Merge Kernel state system input provider
authorAlexandre Montplaisir <alexandre.montplaisir@gmail.com>
Wed, 14 Mar 2012 21:27:09 +0000 (17:27 -0400)
committerFrancois Chouinard <fchouinard@gmail.com>
Mon, 19 Mar 2012 21:43:59 +0000 (17:43 -0400)
which goes in the lttng2.kernel.core plugin

org.eclipse.linuxtools.lttng2.kernel.core.tests/META-INF/MANIFEST.MF
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFDummyInputTest.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFKernelStateInputTest.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFTestFiles.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core/META-INF/MANIFEST.MF
org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFDummyInput.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFKernelHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFKernelStateInput.java [new file with mode: 0644]

index 358462c01980371255d12a1c99028d0af973da4c..b23b5f2a51df8734201b972b29cf8c6fec5e68e2 100644 (file)
@@ -8,7 +8,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Require-Bundle: org.junit;bundle-version="3.8.2",
  org.eclipse.core.runtime;bundle-version="3.7.0",
  org.eclipse.core.resources;bundle-version="3.7.100",
- org.eclipse.linuxtools.lttng.core;bundle-version="0.4.0"
+ org.eclipse.linuxtools.lttng2.kernel.core;bundle-version="0.1.0",
+ org.eclipse.linuxtools.tmf.core;bundle-version="0.5.0"
 Bundle-Localization: plugin
 Bundle-Activator: org.eclipse.linuxtools.lttng2.kernel.core.tests.Activator
 Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFDummyInputTest.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFDummyInputTest.java
new file mode 100644 (file)
index 0000000..0576a55
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;
+
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CTFDummyInput;
+import org.junit.BeforeClass;
+
+/**
+ * Test the dummy CTF input plugin
+ * 
+ * @author alexmont
+ *
+ */
+public class CTFDummyInputTest extends CTFKernelStateInputTest {
+
+    /* Hiding superclass method */
+    @BeforeClass
+    public static void initialize() {
+        input = new CTFDummyInput(CTFTestFiles.getTestTrace());
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFKernelStateInputTest.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFKernelStateInputTest.java
new file mode 100644 (file)
index 0000000..411052b
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;
+
+import static org.junit.Assert.*;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateSystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateChangeInput;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CTFKernelStateInput;
+
+/**
+ * Tests for the LTTng 2.0 kernel state provider
+ * 
+ * @author alexmont
+ *
+ */
+public class CTFKernelStateInputTest {
+
+    protected static IStateChangeInput input;
+
+    @BeforeClass
+    public static void initialize() {
+        input = new CTFKernelStateInput(CTFTestFiles.getTestTrace());
+
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        //
+    }
+
+    @Test
+    public void testOpening() {
+        long testStartTime;
+        testStartTime = input.getStartTime();
+        assertTrue(testStartTime == CTFTestFiles.startTime1);
+    }
+
+    @Test
+    public void testRunning() {
+        StateSystem ss = new StateSystem();
+        input.assignTargetStateSystem(ss);
+        input.getStateSystem(); /* Let's pad that coverage... */
+        input.run();
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFTestFiles.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/CTFTestFiles.java
new file mode 100644 (file)
index 0000000..8348dfd
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;
+
+import java.io.FileNotFoundException;
+
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+
+/**
+ * Definitions used by all tests using CTF trace files
+ * 
+ * @author alexmont
+ * 
+ */
+public abstract class CTFTestFiles {
+
+    public final static long NANOSECS_PER_SEC = 1000000000L;
+
+    /*
+     * To run these tests, you will need to download the following trace, at:
+     * http://www.dorsal.polymtl.ca/~alexmont/data/trace1.tar.bz2
+     * 
+     * and extract it at the root of the project. You can also set up a custom
+     * path below.
+     */
+    public final static String traceFile1 = "trace1/kernel"; //$NON-NLS-1$
+    public final static long startTime1 = 17620320801208L;
+
+    public static CtfTmfTrace trace1 = null;
+
+    public static CtfTmfTrace getTestTrace() {
+        if (trace1 == null) {
+            trace1 = new CtfTmfTrace();
+            try {
+                trace1.initTrace("test-trace1", traceFile1, CtfTmfEvent.class); //$NON-NLS-1$
+            } catch (FileNotFoundException e) {
+                /* If we don't have the file, we shouldn't even try the tests... */
+                e.printStackTrace();
+                return null;
+            }
+        }
+        return trace1;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java
new file mode 100644 (file)
index 0000000..8830f80
--- /dev/null
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
+import org.eclipse.linuxtools.tmf.core.statesystem.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateHistorySystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.HistoryTreeBackend;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.HistoryBuilder;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateChangeInput;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateHistoryBackend;
+import org.eclipse.linuxtools.tmf.core.statevalue.StateValueTypeException;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CTFKernelStateInput;
+import org.junit.*;
+
+/**
+ * Unit tests for the StateHistorySystem, which uses a full (non-partial)
+ * history and the non-threaded CTF kernel handler.
+ * 
+ * @author alexmont
+ * 
+ */
+@SuppressWarnings("nls")
+public class StateSystemFullHistoryTest {
+
+    protected static File stateFile;
+    protected static File stateFileBenchmark;
+
+    protected static HistoryBuilder builder;
+    protected static IStateChangeInput input;
+    protected static IStateHistoryBackend hp;
+    protected static StateHistorySystem shs;
+
+    protected static String getTestFileName() {
+        return "/tmp/statefile.ht"; //$NON-NLS-1$
+    }
+
+    @BeforeClass
+    public static void initialize() {
+        stateFile = new File(getTestFileName());
+        stateFileBenchmark = new File(getTestFileName() + ".benchmark"); //$NON-NLS-1$
+        try {
+            input = new CTFKernelStateInput(CTFTestFiles.getTestTrace());
+            hp = new HistoryTreeBackend(stateFile, input.getStartTime());
+            builder = new HistoryBuilder(input, hp);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        builder.run();
+        shs = (StateHistorySystem) builder.getSS();
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        stateFile.delete();
+        stateFileBenchmark.delete();
+    }
+
+    /**
+     * Rebuild independently so we can benchmark it. Too bad JUnit doesn't allow
+     * us to @Test the @BeforeClass...
+     */
+    @Test
+    public void testBuild() {
+        HistoryBuilder zebuilder;
+        IStateChangeInput zeinput;
+        IStateHistoryBackend zehp;
+
+        try {
+            zeinput = new CTFKernelStateInput(CTFTestFiles.getTestTrace());
+            zehp = new HistoryTreeBackend(stateFileBenchmark,
+                    zeinput.getStartTime());
+            zebuilder = new HistoryBuilder(zeinput, zehp);
+            zebuilder.run();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testOpenExistingStateFile() {
+        IStateHistoryBackend hp2 = null;
+        StateHistorySystem shs2 = null;
+        try {
+            /* 'newStateFile' should have already been created */
+            hp2 = new HistoryTreeBackend(stateFile);
+            shs2 = new StateHistorySystem(hp2, false);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        assertTrue(shs2 != null);
+    }
+
+    @Test
+    public void testFullQuery1() throws StateValueTypeException,
+            AttributeNotFoundException, TimeRangeException {
+
+        ITmfStateInterval interval;
+        int quark, valueInt;
+        String valueStr;
+
+        shs.loadStateAtTime(17622841472359L);
+
+        quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        interval = shs.queryState(quark);
+        valueInt = interval.getStateValue().unboxInt();
+        assertTrue(valueInt == 1929);
+
+        quark = shs.getQuarkAbsolute("Threads", "1197", "Exec_name");
+        interval = shs.queryState(quark);
+        valueStr = interval.getStateValue().unboxStr();
+        assertTrue(valueStr.equals("apache2"));
+
+        // FIXME fails at the moment (attribute type is int, and = 3129??), I'll
+        // figure it out later
+        // quark = shs.getQuarkAbsolute("Threads", "3109", "Exec_mode_stack");
+        // interval = shs.getState(quark);
+        // valueStr = interval.getStateValue().unboxStr();
+        // assertTrue( valueStr.equals("bloup") );
+    }
+
+    @Test
+    public void testFullQuery2() {
+        //
+    }
+
+    @Test
+    public void testFullQuery3() {
+        //
+    }
+
+    @Test
+    public void testSingleQuery1() throws AttributeNotFoundException,
+            TimeRangeException, StateValueTypeException {
+
+        long timestamp = 17622841472359L;
+        int quark;
+        ITmfStateInterval interval;
+        String valueStr;
+
+        quark = shs.getQuarkAbsolute("Threads", "1197", "Exec_name");
+        interval = shs.querySingleState(timestamp, quark);
+        valueStr = interval.getStateValue().unboxStr();
+        assertTrue(valueStr.equals("apache2"));
+    }
+
+    @Test
+    public void testSingleQuery2() {
+        //
+    }
+
+    @Test
+    public void testSingleQuery3() {
+        //
+    }
+
+    @Test
+    public void testRangeQuery1() throws AttributeNotFoundException,
+            TimeRangeException, StateValueTypeException {
+
+        long time1 = 17622841472359L;
+        long time2 = time1 + 1L * CTFTestFiles.NANOSECS_PER_SEC;
+        int quark;
+        List<ITmfStateInterval> intervals;
+
+        quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        intervals = shs.queryHistoryRange(quark, time1, time2);
+        assertTrue(intervals.size() == 1018); /* Number of context switches! */
+        assertTrue(intervals.get(100).getStateValue().unboxInt() == 2974);
+        assertTrue(intervals.get(205).getEndTime() == 17622977386059L);
+    }
+
+    /**
+     * Ask for a time range outside of the trace's range
+     * 
+     * @throws TimeRangeException
+     */
+    @Test(expected = TimeRangeException.class)
+    public void testFullQueryInvalidTime1() throws TimeRangeException {
+        shs.loadStateAtTime(CTFTestFiles.startTime1 + 20L
+                * CTFTestFiles.NANOSECS_PER_SEC);
+
+    }
+
+    @Test(expected = TimeRangeException.class)
+    public void testFullQueryInvalidTime2() throws TimeRangeException {
+        shs.loadStateAtTime(CTFTestFiles.startTime1 - 20L
+                * CTFTestFiles.NANOSECS_PER_SEC);
+
+    }
+
+    @Test(expected = TimeRangeException.class)
+    public void testSingleQueryInvalidTime1()
+            throws AttributeNotFoundException, TimeRangeException {
+
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        long time = CTFTestFiles.startTime1 + 20L
+                * CTFTestFiles.NANOSECS_PER_SEC;
+        shs.querySingleState(time, quark);
+    }
+
+    @Test(expected = TimeRangeException.class)
+    public void testSingleQueryInvalidTime2()
+            throws AttributeNotFoundException, TimeRangeException {
+
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        long time = CTFTestFiles.startTime1 - 20L
+                * CTFTestFiles.NANOSECS_PER_SEC;
+        shs.querySingleState(time, quark);
+    }
+
+    @Test(expected = TimeRangeException.class)
+    public void testRangeQueryInvalidTime1() throws AttributeNotFoundException,
+            TimeRangeException {
+
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        long time1 = CTFTestFiles.startTime1 - 20L
+                * CTFTestFiles.NANOSECS_PER_SEC; /* invalid */
+        long time2 = CTFTestFiles.startTime1 + 1L
+                * CTFTestFiles.NANOSECS_PER_SEC; /* valid */
+
+        shs.queryHistoryRange(quark, time1, time2);
+    }
+
+    @Test(expected = TimeRangeException.class)
+    public void testRangeQueryInvalidTime2() throws TimeRangeException,
+            AttributeNotFoundException {
+
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        long time1 = CTFTestFiles.startTime1 + 1L
+                * CTFTestFiles.NANOSECS_PER_SEC; /* valid */
+        long time2 = CTFTestFiles.startTime1 + 20L
+                * CTFTestFiles.NANOSECS_PER_SEC; /* invalid */
+
+        shs.queryHistoryRange(quark, time1, time2);
+    }
+
+    @Test(expected = TimeRangeException.class)
+    public void testRangeQueryInvalidTime3() throws TimeRangeException,
+            AttributeNotFoundException {
+
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        long time1 = CTFTestFiles.startTime1 - 1L
+                * CTFTestFiles.NANOSECS_PER_SEC; /* invalid */
+        long time2 = CTFTestFiles.startTime1 + 20L
+                * CTFTestFiles.NANOSECS_PER_SEC; /* invalid */
+
+        shs.queryHistoryRange(quark, time1, time2);
+    }
+
+    /**
+     * Ask for a non-existing attribute
+     * 
+     * @throws AttributeNotFoundException
+     */
+    @Test(expected = AttributeNotFoundException.class)
+    public void testQueryInvalidAttribute() throws AttributeNotFoundException {
+
+        shs.getQuarkAbsolute("There", "is", "no", "cow", "level");
+    }
+
+    /**
+     * Query but with the wrong State Value type
+     * 
+     * @throws StateValueTypeException
+     * @throws AttributeNotFoundException
+     * @throws TimeRangeException
+     */
+    @Test(expected = StateValueTypeException.class)
+    public void testQueryInvalidValuetype1() throws StateValueTypeException,
+            AttributeNotFoundException, TimeRangeException {
+
+        ITmfStateInterval interval;
+        int quark;
+
+        shs.loadStateAtTime(17622841472359L);
+
+        quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        interval = shs.queryState(quark);
+        interval.getStateValue().unboxStr(); /*
+                                              * This is supposed to be a int
+                                              * value
+                                              */
+    }
+
+    @Test(expected = StateValueTypeException.class)
+    public void testQueryInvalidValuetype2() throws StateValueTypeException,
+            AttributeNotFoundException, TimeRangeException {
+
+        ITmfStateInterval interval;
+        int quark;
+
+        shs.loadStateAtTime(17622841472359L);
+
+        quark = shs.getQuarkAbsolute("Threads", "1197", "Exec_name");
+        interval = shs.queryState(quark);
+        interval.getStateValue().unboxInt(); /*
+                                              * This is supposed to be a String
+                                              * value
+                                              */
+    }
+
+    @Test
+    public void testFullAttributeName() throws AttributeNotFoundException {
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
+        String name = shs.getFullAttributePath(quark);
+        assertTrue(name.equals("CPUs/0/Current_thread"));
+    }
+
+    @Test
+    public void testDebugPrinting() throws FileNotFoundException {
+        shs.debugPrint(new PrintWriter(new File("/dev/null")));
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java
new file mode 100644 (file)
index 0000000..c72c24d
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;
+
+import java.io.File;
+
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CTFKernelStateInput;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateHistorySystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.ThreadedHistoryTreeBackend;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.HistoryBuilder;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateChangeInput;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateHistoryBackend;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Variant of the StateSystemFullHistoryTest, which uses the threaded event
+ * handler instead.
+ * 
+ * @author alexmont
+ * 
+ */
+public class StateSystemFullThreadedHistoryTest extends
+        StateSystemFullHistoryTest {
+
+    /* Hiding the static method in the superclass */
+    protected static String getTestFileName() {
+        return "/tmp/statefile-threaded.ht"; //$NON-NLS-1$
+    }
+
+    @BeforeClass
+    public static void initialize() {
+        stateFile = new File(getTestFileName());
+        stateFileBenchmark = new File(getTestFileName() + ".benchmark"); //$NON-NLS-1$
+        try {
+            input = new CTFKernelStateInput(CTFTestFiles.getTestTrace());
+            hp = new ThreadedHistoryTreeBackend(stateFile,
+                    input.getStartTime(), 2000);
+            builder = new HistoryBuilder(input, hp);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        builder.run();
+        shs = (StateHistorySystem) builder.getSS();
+    }
+
+    @Override
+    @Test
+    public void testBuild() {
+        HistoryBuilder zebuilder;
+        IStateChangeInput zeinput;
+        IStateHistoryBackend zehp;
+
+        try {
+            zeinput = new CTFKernelStateInput(CTFTestFiles.getTestTrace());
+            zehp = new ThreadedHistoryTreeBackend(stateFileBenchmark,
+                    zeinput.getStartTime(), 2000);
+            zebuilder = new HistoryBuilder(zeinput, zehp);
+            zebuilder.run();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java
new file mode 100644 (file)
index 0000000..e53f2e8
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * 
+ * 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:
+ *   Alexandre Montplaisir - Initial implementation
+ ******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all of
+ * the tests within its package as well as within any subpackages of its
+ * package.
+ * 
+ * @author ematkho
+ * @version $Revision: 1.0 $
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ CTFDummyInputTest.class, CTFKernelStateInputTest.class,
+    StateSystemFullHistoryTest.class, StateSystemFullThreadedHistoryTest.class})
+public class TestAll {
+
+    /**
+     * Launch the test.
+     * 
+     * @param args
+     *            the command line arguments
+     */
+    public static void main(String[] args) {
+        JUnitCore.runClasses(new Class[] { TestAll.class });
+    }
+}
index 556f7acddb8cad29360d66e1e278b955e5db2afb..8d87338c60c98185245d04510c712ab2d8952b39 100644 (file)
@@ -7,6 +7,8 @@ Bundle-Activator: org.eclipse.linuxtools.internal.lttng2.kernel.core.Activator
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.linuxtools.internal.lttng2.kernel.core;x-internal:=true
+Export-Package: org.eclipse.linuxtools.internal.lttng2.kernel.core;x-friends:="org.eclipse.linuxtools.lttng2.kernel.core.tests",
+ org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;x-friends:="org.eclipse.linuxtools.lttng2.kernel.core.tests"
 Bundle-Localization: plugin
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0"
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
+ org.eclipse.linuxtools.tmf.core;bundle-version="0.5.0"
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFDummyInput.java b/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFDummyInput.java
new file mode 100644 (file)
index 0000000..af46d9a
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
+
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfIterator;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateSystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateChangeInput;
+
+/**
+ * "Dummy" version of the CTF event input plugin. This one only reads events
+ * (and creates the Event/EventWrapper objects) but discards them instead of
+ * inserting them in the Queue.
+ * 
+ * Only useful for benchmarking purposes.
+ * 
+ * @author alexmont
+ * 
+ */
+public class CTFDummyInput implements IStateChangeInput {
+
+    private final CtfIterator iterator;
+
+    /**
+     * Create a new dummy CTF state change input.
+     * 
+     * @param traceFile
+     *            The CTF trace to read from (can be any type of CTF trace)
+     */
+    public CTFDummyInput(CtfTmfTrace trace) {
+        this.iterator = new CtfIterator(trace);
+
+    }
+
+    @SuppressWarnings("unused")
+    @Override
+    public void run() {
+        /* We know currentEvent is unused here, it's by design! */
+        CtfTmfEvent currentEvent;
+        currentEvent = iterator.getCurrentEvent();
+        while (iterator.advance()) {
+            currentEvent = iterator.getCurrentEvent();
+        }
+    }
+
+    @Override
+    public long getStartTime() {
+        return iterator.getLocation().getLocation();
+    }
+
+    /**
+     * This dummy input does not insert any state changes anywhere, so this
+     * method does nothing.
+     */
+    @Override
+    public void assignTargetStateSystem(StateSystem ss) {
+        //
+    }
+
+    /**
+     * Since there is no target state system in the dummy input, this always
+     * returns null.
+     */
+    @Override
+    public StateSystem getStateSystem() {
+        return null;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFKernelHandler.java b/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFKernelHandler.java
new file mode 100644 (file)
index 0000000..c0fb8c4
--- /dev/null
@@ -0,0 +1,448 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
+
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.concurrent.BlockingQueue;
+
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.statesystem.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateHistorySystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateSystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
+import org.eclipse.linuxtools.tmf.core.statevalue.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
+
+/**
+ * This is the reference "state provider" for LTTng 2.0 kernel traces.
+ * 
+ * @author alexmont
+ * 
+ */
+class CTFKernelHandler implements Runnable {
+
+    private final BlockingQueue<CtfTmfEvent> inQueue;
+    private StateSystem ss;
+
+    private CtfTmfEvent currentEvent;
+
+    /*
+     * We can keep handles to some Attribute Nodes so these don't need to be
+     * re-found (re-hashed Strings etc.) every new event
+     */
+    Vector<Integer> currentCPUNodes;
+    Vector<Integer> currentThreadNodes;
+
+    /* Event names HashMap. TODO: This can be discarded once we move to Java 7 */
+    private final HashMap<String, Integer> knownEventNames;
+
+    CTFKernelHandler(BlockingQueue<CtfTmfEvent> eventsQueue) {
+        assert (eventsQueue != null);
+        this.inQueue = eventsQueue;
+        currentCPUNodes = new Vector<Integer>();
+        currentThreadNodes = new Vector<Integer>();
+
+        knownEventNames = fillEventNames();
+    }
+
+    void assignStateSystem(StateSystem targetSS) {
+        this.ss = targetSS;
+    }
+
+    StateSystem getStateSystem() {
+        return ss;
+    }
+
+    @Override
+    public void run() {
+        if (ss == null) {
+            System.err.println("Cannot run event manager without assigning a target state system first!"); //$NON-NLS-1$
+            return;
+        }
+        CtfTmfEvent event;
+
+        try {
+            event = inQueue.take();
+            while (event.getTimestamp() != null) {
+                processEvent(event);
+                event = inQueue.take();
+            }
+            /* We've received the last event, clean up */
+            closeStateSystem();
+            return;
+        } catch (InterruptedException e) {
+            /* We've been interrupted abnormally */
+            System.out.println("Event handler interrupted!"); //$NON-NLS-1$
+            e.printStackTrace();
+        }
+    }
+
+    private void closeStateSystem() {
+        /* Close the History system, if there is one */
+        if (ss.getClass() == StateHistorySystem.class) {
+            try {
+                ((StateHistorySystem) ss).closeHistory(currentEvent.getTimestamp().getValue());
+            } catch (TimeRangeException e) {
+                /*
+                 * Since we're using currentEvent.getTimestamp, this shouldn't
+                 * cause any problem
+                 */
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @SuppressWarnings("nls")
+    private void processEvent(CtfTmfEvent event) {
+        currentEvent = event;
+        ITmfEventField content = event.getContent();
+        String eventName = event.getType().getName();
+
+        long ts = event.getTimestamp().getValue();
+        int quark;
+        ITmfStateValue value;
+        Integer eventCpu = event.getCPU();
+        Integer currentCPUNode, currentThreadNode, tidNode;
+
+        /* Adjust the current nodes Vectors if we see a new CPU in an event */
+        if (eventCpu >= currentCPUNodes.size()) {
+            /* We need to add this node to the vector */
+            for (Integer i = currentCPUNodes.size(); i < eventCpu + 1; i++) {
+                quark = ss.getQuarkAbsoluteAndAdd("CPUs", i.toString());
+                currentCPUNodes.add(quark);
+
+                quark = ss.getQuarkAbsoluteAndAdd("Threads", "unknown");
+                currentThreadNodes.add(quark);
+            }
+        }
+
+        currentCPUNode = currentCPUNodes.get(eventCpu);
+        currentThreadNode = currentThreadNodes.get(eventCpu);
+        assert (currentCPUNode != null);
+        assert (currentThreadNode != null);
+
+        try {
+            /*
+             * Feed event to the history system if it's known to cause a state
+             * transition See:
+             * https://projectwiki.dorsal.polymtl.ca/index.php/State_transitions
+             */
+            switch (getEventIndex(eventName)) {
+
+            case 1: // "exit_syscall":
+                /* Fields: int64 ret */
+                /* Pop "syscall" from the Exec_mode_stack */
+                quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
+                        "Exec_mode_stack");
+                try {
+                    ss.popAttribute(ts, quark);
+                } catch (AttributeNotFoundException e1) {
+                    /*
+                     * meh, can happen if we're missing events, we'll just
+                     * silently ignore it.
+                     */
+                    System.err.println(event.getTimestamp()
+                            + " Popping empty attribute: " + e1.getMessage()); //$NON-NLS-1$
+                }
+                break;
+
+            case 2: // "irq_handler_entry":
+                /* Fields: int32 irq, string name */
+                Integer irqId = ((Long) content.getField("irq").getValue()).intValue();
+
+                /* Push the IRQ to the CPU's IRQ_stack */
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, "IRQ_stack");
+                value = TmfStateValue.newValueInt(irqId);
+                ss.pushAttribute(ts, value, quark);
+
+                /* Change the status of the running process to interrupted */
+                quark = ss.getQuarkRelativeAndAdd(currentThreadNode, "Status");
+                value = TmfStateValue.newValueInt(STATE_PROCESS_STATUS_WAIT_CPU);
+                ss.modifyAttribute(ts, value, quark);
+                break;
+
+            case 3: // "irq_handler_exit":
+                /* Fields: int32 irq, int32 ret */
+                int stackDepth = 0;
+
+                /* Pop the IRQ from the CPU's IRQ_stack */
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode, "IRQ_stack");
+                try {
+                    ss.popAttribute(ts, quark);
+                } catch (AttributeNotFoundException e1) {
+                    System.err.print(event.getTimestamp()
+                            + " Popping empty attribute: " + e1.getMessage());
+                }
+
+                /*
+                 * If this was the last IRQ on the stack, set the process back
+                 * to running
+                 */
+                /* 'quark' should still be valid */
+                try {
+                    stackDepth = ss.queryOngoingState(quark).unboxInt();
+                } catch (StateValueTypeException e) {
+                    /* IRQ_stack SHOULD be of int type, this shouldn't happen */
+                    e.printStackTrace();
+                }
+                if (stackDepth == 0) {
+                    quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
+                            "Status");
+                    value = TmfStateValue.newValueInt(STATE_PROCESS_STATUS_RUN);
+                    ss.modifyAttribute(ts, value, quark);
+                }
+                break;
+
+            case 4: // "softirq_entry":
+                /* Fields: int32 vec */
+                break;
+
+            case 5: // "softirq_exit":
+                /* Fields: int32 vec */
+                break;
+
+            case 6: // "softirq_raise":
+                /* Fields: int32 vec */
+                break;
+
+            case 7: // "sched_switch":
+                /*
+                 * Fields: string prev_comm, int32 prev_tid, int32 prev_prio,
+                 * int64 prev_state, string next_comm, int32 next_tid, int32
+                 * next_prio
+                 */
+
+                // prev_comm doesn't seem to get populated...
+                String prevProcessName = (String) content.getField("prev_comm").getValue();
+                Integer prevTid = ((Long) content.getField("prev_tid").getValue()).intValue();
+                Long prevState = (Long) content.getField("prev_state").getValue();
+
+                String nextProcessName = (String) content.getField("next_comm").getValue();
+                Integer nextTid = ((Long) content.getField("next_tid").getValue()).intValue();
+
+                /* Update the name of the process going out (if needed) */
+                quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
+                        "Exec_name");
+                value = TmfStateValue.newValueString(prevProcessName);
+                ss.updateOngoingState(value, quark);
+
+                /* Update the currentThreadNodes pointer */
+                Integer newCurrentThreadNode = ss.getQuarkAbsoluteAndAdd(
+                        "Threads", nextTid.toString());
+                currentThreadNodes.set(eventCpu, newCurrentThreadNode);
+
+                /* Set the status of the new scheduled process */
+                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode,
+                        "Status");
+                value = TmfStateValue.newValueInt(STATE_PROCESS_STATUS_RUN);
+                ss.modifyAttribute(ts, value, quark);
+
+                /* Set the exec name of the new process */
+                quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode,
+                        "Exec_name");
+                value = TmfStateValue.newValueString(nextProcessName);
+                ss.modifyAttribute(ts, value, quark);
+
+                /* Set the status of the process that got scheduled out */
+                quark = ss.getQuarkAbsoluteAndAdd("Threads",
+                        prevTid.toString(), "Status");
+                value = TmfStateValue.newValueInt(prevState.intValue());
+                ss.modifyAttribute(ts, value, quark);
+
+                /* Set the current scheduled process on the relevant CPU */
+                quark = ss.getQuarkRelativeAndAdd(currentCPUNode,
+                        "Current_thread");
+                value = TmfStateValue.newValueInt(nextTid);
+                ss.modifyAttribute(ts, value, quark);
+                break;
+
+            case 8: // "sched_process_fork":
+                /*
+                 * Fields: string parent_comm, int32 parent_tid, string
+                 * child_comm, int32 child_tid
+                 */
+
+                // String parentProcessName = (String)
+                // event.getFieldValue("parent_comm");
+                String childProcessName = (String) content.getField("child_comm").getValue();
+                // assert ( parentProcessName.equals(childProcessName) );
+
+                Integer parentTid = ((Long) content.getField("parent_tid").getValue()).intValue();
+                Integer childTid = ((Long) content.getField("child_tid").getValue()).intValue();
+
+                tidNode = ss.getQuarkAbsoluteAndAdd("Threads",
+                        childTid.toString());
+
+                /*
+                 * Add the new process with its known TID, PPID, and initial
+                 * Exec_name
+                 */
+                quark = ss.getQuarkRelativeAndAdd(tidNode, "PPID");
+                value = TmfStateValue.newValueInt(parentTid);
+                ss.modifyAttribute(ts, value, quark);
+
+                /* Set the new process' exec_name */
+                quark = ss.getQuarkRelativeAndAdd(tidNode, "Exec_name");
+                value = TmfStateValue.newValueString(childProcessName);
+                ss.modifyAttribute(ts, value, quark);
+                break;
+
+            case 9: // "sched_process_exit":
+                /* Fields: string comm, int32 tid, int32 prio */
+                String processName = (String) content.getField("comm").getValue();
+                Integer tid = ((Long) content.getField("tid").getValue()).intValue();
+
+                /* Update the process' name, if we don't have it */
+                quark = ss.getQuarkAbsoluteAndAdd("Threads", tid.toString(),
+                        "Exec_name");
+                value = TmfStateValue.newValueString(processName);
+                ss.updateOngoingState(value, quark);
+
+                /*
+                 * Remove the process and all its sub-attributes from the
+                 * current state
+                 */
+                quark = ss.getQuarkAbsoluteAndAdd("Threads", tid.toString());
+                ss.removeAttribute(ts, quark);
+                break;
+
+            case 10: // "sched_process_free":
+                /* Fields: string comm, int32 tid, int32 prio */
+                break;
+
+            // FIXME Not available with CTF. Use event context?
+            // case LTT_EVENT_EXEC:
+            // filename = new String((byte[]) event.getField(0));
+            //
+            // /* Change the Exec_name of the process */
+            // quark = ss.getQuarkRelativePath(true, currentThreadNode,
+            // "Exec_name");
+            // ss.modifyAttribute(ts, filename, quark);
+            // break;
+
+            default:
+                /* Other event types not covered by the main switch */
+
+                if (eventName.startsWith("sys_")
+                        || eventName.startsWith("compat_sys_")) {
+                    /*
+                     * This is a replacement for the old sys_enter event. Now
+                     * syscall names are listed into the event type
+                     */
+
+                    /*
+                     * Push the syscall name on the Exec_mode_stack of the
+                     * relevant PID
+                     */
+                    quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
+                            "Exec_mode_stack");
+                    value = TmfStateValue.newValueString(eventName);
+                    ss.pushAttribute(ts, value, quark);
+                }
+
+                break;
+            } // End of switch
+
+            /*
+             * Statistics
+             */
+
+            /* Nb of events total */
+            try {
+                quark = ss.getQuarkAbsoluteAndAdd("Stats", "Event_types",
+                        eventName);
+                ss.incrementAttribute(ts, quark);
+
+                // /* Nb of events per CPU */
+                // ss.incrementAttribute(ts,
+                // ss.getAttributeQuarkAndAdd(currentCPUNode, "Stats",
+                // "Event_types", eventType.toString()));
+                //
+                // /* Nb of events per process */
+                // ss.incrementAttribute(ts,
+                // ss.getAttributeQuarkAndAdd(currentThreadNode, "Stats",
+                // "Event_types", eventType.toString()));
+
+            } catch (StateValueTypeException sve) {
+                /*
+                 * Here's hoping we don't have string values in statistics
+                 * attributes...
+                 */
+                sve.printStackTrace();
+            }
+
+            // end of big non-indented try
+        } catch (AttributeNotFoundException ae) {
+            /*
+             * This would indicate a problem with the logic of the manager here,
+             * so it shouldn't happen.
+             */
+            ae.printStackTrace();
+
+        } catch (TimeRangeException tre) {
+            /*
+             * This would happen if the events in the trace aren't ordered
+             * chronologically, which should never be the case ...
+             */
+            System.err.println("TimeRangeExcpetion caught in the state system's event manager.");
+            System.err.println("Are the events in the trace correctly ordered?");
+            tre.printStackTrace();
+
+        } catch (StateValueTypeException sve) {
+            /*
+             * This would happen if we were trying to push/pop attributes not of
+             * type integer. Which, once again, should never happen.
+             */
+            sve.printStackTrace();
+        }
+
+    }
+
+    @SuppressWarnings("nls")
+    private static HashMap<String, Integer> fillEventNames() {
+        /*
+         * TODO Replace with straight strings in the switch/case once we move to
+         * Java 7
+         */
+        /*
+         * This is still, imo, cleaner than the wtf-were-they-thinking Java
+         * Enums
+         */
+        HashMap<String, Integer> map = new HashMap<String, Integer>();
+
+        map.put("exit_syscall", 1);
+        map.put("irq_handler_entry", 2);
+        map.put("irq_handler_exit", 3);
+        map.put("softirq_entry", 4);
+        map.put("softirq_exit", 5);
+        map.put("softirq_raise", 6);
+        map.put("sched_switch", 7);
+        map.put("sched_process_fork", 8);
+        map.put("sched_process_exit", 9);
+        map.put("sched_process_free", 10);
+
+        return map;
+    }
+
+    private int getEventIndex(String eventName) {
+        Integer ret = knownEventNames.get(eventName);
+        return (ret != null) ? ret : -1;
+    }
+
+    /* Process status */
+    private final static int STATE_PROCESS_STATUS_WAIT_CPU = 1;
+    private final static int STATE_PROCESS_STATUS_RUN = 2;
+}
diff --git a/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFKernelStateInput.java b/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/stateprovider/CTFKernelStateInput.java
new file mode 100644 (file)
index 0000000..f279599
--- /dev/null
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * 
+ * 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
+ * 
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
+
+import java.io.IOException;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfIterator;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.statesystem.StateSystem;
+import org.eclipse.linuxtools.tmf.core.statesystem.helpers.IStateChangeInput;
+
+/**
+ * This is the state change input plugin for TMF's state system which handles
+ * the LTTng 2.0 kernel traces in CTF format.
+ * 
+ * It uses the reference handler defined in CTFKernelHandler.java.
+ * 
+ * @author alexmont
+ * 
+ */
+public class CTFKernelStateInput implements IStateChangeInput {
+
+    final static int EVENTS_QUEUE_SIZE = 10000;
+
+    private final BlockingQueue<CtfTmfEvent> eventsQueue;
+
+    private final CtfIterator traceReader;
+    private final CTFKernelHandler eventHandler;
+
+    private final Thread eventHandlerThread;
+
+    private boolean ssAssigned;
+
+    /**
+     * Instantiate a new state provider plugin.
+     * 
+     * @param traceFile
+     *            The LTTng 2.0 kernel trace directory
+     * @throws IOException
+     *             If the directory was not found, or not recognized as a CTF
+     *             trace.
+     */
+    public CTFKernelStateInput(CtfTmfTrace trace) {
+        eventsQueue = new ArrayBlockingQueue<CtfTmfEvent>(EVENTS_QUEUE_SIZE);
+        traceReader = new CtfIterator(trace);
+        eventHandler = new CTFKernelHandler(eventsQueue);
+        ssAssigned = false;
+
+        eventHandlerThread = new Thread(eventHandler,
+                "CTF Kernel Event Handler"); //$NON-NLS-1$
+    }
+
+    @Override
+    public void run() {
+        if (!ssAssigned) {
+            System.err.println("Cannot start Input thread without a target state system"); //$NON-NLS-1$
+            return;
+        }
+
+        CtfTmfEvent currentEvent;
+
+        eventHandlerThread.start();
+
+        try {
+            currentEvent = traceReader.getCurrentEvent();
+            while (currentEvent != null) {
+                traceReader.advance();
+                eventsQueue.put(currentEvent);
+                currentEvent = traceReader.getCurrentEvent();
+            }
+            /*
+             * We're done reading the trace, insert a null event in the queue to
+             * stop the handler
+             */
+            eventsQueue.put(CtfTmfEvent.getNullEvent());
+            eventHandlerThread.join();
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void assignTargetStateSystem(StateSystem ss) {
+        eventHandler.assignStateSystem(ss);
+        ssAssigned = true;
+    }
+
+    @Override
+    public StateSystem getStateSystem() {
+        return eventHandler.getStateSystem();
+    }
+
+    @Override
+    public long getStartTime() {
+        return traceReader.getCtfTmfTrace().getStartTime().getValue();
+    }
+}
This page took 0.067439 seconds and 5 git commands to generate.