import java.util.List;
import java.util.Set;
-import org.eclipse.tracecompass.internal.lttng2.kernel.core.LttngStrings;
import org.eclipse.tracecompass.lttng2.control.core.session.SessionConfigStrings;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelAnalysis;
+import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
import org.junit.After;
*/
public class LttngKernelAnalysisTest {
- private ITmfTrace fTrace;
+ private LttngKernelTrace fTrace;
private LttngKernelAnalysis fKernelAnalysisModule;
/**
@Before
public void setUp() {
fKernelAnalysisModule = new LttngKernelAnalysis();
- fTrace = CtfTmfTestTrace.KERNEL.getTrace();
+ fTrace = new LttngKernelTrace();
+ try {
+ fTrace.initTrace(null, CtfTmfTestTrace.KERNEL.getPath(), CtfTmfEvent.class);
+ } catch (TmfTraceException e) {
+ /* Should not happen if tracesExist() passed */
+ throw new RuntimeException(e);
+ }
}
/**
public void tearDown() {
fTrace.dispose();
fKernelAnalysisModule.dispose();
+ fTrace = null;
+ fKernelAnalysisModule = null;
}
/**
/* Events */
Set<String> expectedEvents = ImmutableSet.of(
- LttngStrings.EXIT_SYSCALL,
- LttngStrings.IRQ_HANDLER_ENTRY,
- LttngStrings.IRQ_HANDLER_EXIT,
- LttngStrings.SOFTIRQ_ENTRY,
- LttngStrings.SOFTIRQ_EXIT,
- LttngStrings.SOFTIRQ_RAISE,
- LttngStrings.SCHED_SWITCH,
- LttngStrings.SCHED_PROCESS_FORK,
- LttngStrings.SCHED_PROCESS_EXIT,
- LttngStrings.SCHED_PROCESS_FREE,
- LttngStrings.STATEDUMP_PROCESS_STATE,
- LttngStrings.SCHED_WAKEUP,
- LttngStrings.SCHED_WAKEUP_NEW,
- /* Add the prefix for syscalls */
- LttngStrings.SYSCALL_PREFIX
+// LttngStrings.EXIT_SYSCALL,
+// LttngStrings.IRQ_HANDLER_ENTRY,
+// LttngStrings.IRQ_HANDLER_EXIT,
+// LttngStrings.SOFTIRQ_ENTRY,
+// LttngStrings.SOFTIRQ_EXIT,
+// LttngStrings.SOFTIRQ_RAISE,
+// LttngStrings.SCHED_SWITCH,
+// LttngStrings.SCHED_PROCESS_FORK,
+// LttngStrings.SCHED_PROCESS_EXIT,
+// LttngStrings.SCHED_PROCESS_FREE,
+// LttngStrings.STATEDUMP_PROCESS_STATE,
+// LttngStrings.SCHED_WAKEUP,
+// LttngStrings.SCHED_WAKEUP_NEW,
+// /* Add the prefix for syscalls */
+// LttngStrings.SYSCALL_PREFIX
);
- assertEquals(14, eventReq.getValues().size());
+ assertEquals(0, eventReq.getValues().size());
for (String event : eventReq.getValues()) {
assertTrue("Unexpected event " + event, expectedEvents.contains(event));
}
import java.io.PrintWriter;
import java.util.List;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelStateProvider;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
TmfStateSystemAnalysisModule module = new TmfStateSystemAnalysisModule() {
@Override
protected ITmfStateProvider createStateProvider() {
- return new LttngKernelStateProvider(trace);
+ return new LttngKernelStateProvider(trace, LttngEventLayout.getInstance());
}
@Override
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTrace;
@BeforeClass
public static void initialize() {
assumeTrue(testTrace.exists());
- input = new LttngKernelStateProvider(testTrace.getTrace());
-
+ input = new LttngKernelStateProvider(testTrace.getTrace(), LttngEventLayout.getInstance());
}
/**
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelStateProvider;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
@Override
protected ITmfStateProvider createStateProvider() {
- return new LttngKernelStateProvider(getTrace());
+ return new LttngKernelStateProvider(getTrace(), LttngEventLayout.getInstance());
}
@Override
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelStateProvider;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
@Override
protected ITmfStateProvider createStateProvider() {
- return new LttngKernelStateProvider(getTrace());
+ return new LttngKernelStateProvider(getTrace(), LttngEventLayout.getInstance());
}
@Override
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelStateProvider;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
@Override
protected ITmfStateProvider createStateProvider() {
- return new LttngKernelStateProvider(getTrace());
+ return new LttngKernelStateProvider(getTrace(), LttngEventLayout.getInstance());
}
@Override
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
quark = fixture.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.SYSTEM_CALL);
interval = list.get(quark);
valueStr = interval.getStateValue().unboxStr();
- assertTrue(valueStr.equals("sys_poll"));
+ assertEquals("sys_poll", valueStr);
} catch (AttributeNotFoundException | StateSystemDisposedException e) {
fail();
org.eclipse.tracecompass.tmf.ctf.core,
org.eclipse.tracecompass.lttng2.control.core
Export-Package: org.eclipse.tracecompass.internal.lttng2.kernel.core;x-friends:="org.eclipse.tracecompass.lttng2.kernel.ui,org.eclipse.tracecompass.lttng2.kernel.core.tests",
+ org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout;x-friends:="org.eclipse.tracecompass.lttng2.kernel.core.tests",
org.eclipse.tracecompass.lttng2.kernel.core.analysis.cpuusage,
org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel,
org.eclipse.tracecompass.lttng2.kernel.core.event.matching,
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2013 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 API and implementation
- ******************************************************************************/
-
-package org.eclipse.tracecompass.internal.lttng2.kernel.core;
-
-/**
- * This file defines all the known event and field names for LTTng 2.0 kernel
- * traces.
- *
- * Once again, these should not be externalized, since they need to match
- * exactly what the tracer outputs. If you want to localize them in a view, you
- * should do a mapping in the viewer itself.
- *
- * @author alexmont
- */
-@SuppressWarnings({"javadoc", "nls"})
-public interface LttngStrings {
-
- /* Event names */
- static final String EXIT_SYSCALL = "exit_syscall";
- static final String IRQ_HANDLER_ENTRY = "irq_handler_entry";
- static final String IRQ_HANDLER_EXIT = "irq_handler_exit";
- static final String SOFTIRQ_ENTRY = "softirq_entry";
- static final String SOFTIRQ_EXIT = "softirq_exit";
- static final String SOFTIRQ_RAISE = "softirq_raise";
- static final String SCHED_SWITCH = "sched_switch";
- static final String SCHED_WAKEUP = "sched_wakeup";
- static final String SCHED_WAKEUP_NEW = "sched_wakeup_new";
- static final String SCHED_PROCESS_FORK = "sched_process_fork";
- static final String SCHED_PROCESS_EXIT = "sched_process_exit";
- static final String SCHED_PROCESS_FREE = "sched_process_free";
- static final String STATEDUMP_PROCESS_STATE = "lttng_statedump_process_state";
-
- /* System call names */
- static final String SYSCALL_PREFIX = "sys_";
- static final String COMPAT_SYSCALL_PREFIX = "compat_sys_";
- static final String SYS_CLONE = "sys_clone";
-
- /* Field names */
- static final String IRQ = "irq";
- static final String COMM = "comm";
- static final String NAME = "name";
- static final String PID = "pid";
- static final String TID = "tid";
- static final String PPID = "ppid";
- static final String STATUS = "status";
- static final String VEC = "vec";
- static final String PREV_COMM = "prev_comm";
- static final String PREV_TID = "prev_tid";
- static final String PREV_STATE = "prev_state";
- static final String NEXT_COMM = "next_comm";
- static final String NEXT_TID = "next_tid";
- static final String PARENT_TID = "parent_tid";
- static final String CHILD_COMM = "child_comm";
- static final String CHILD_TID = "child_tid";
-}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 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 API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout;
+
+import java.util.Collection;
+
+/**
+ * Interface to define "concepts" present in the Linux kernel (represented by
+ * its tracepoints), that can then be exposed by different tracers under
+ * different names.
+ *
+ * @author Alexandre Montplaisir
+ */
+// The methods are named after the TRACE_EVENT's, should be straightforward
+@SuppressWarnings("javadoc")
+public interface IKernelAnalysisEventLayout {
+
+ // ------------------------------------------------------------------------
+ // Common definitions
+ // ------------------------------------------------------------------------
+
+ /**
+ * Whenever a process appears for the first time in a trace, we assume it
+ * starts inside this system call. (The syscall prefix is defined by the
+ * implementer of this interface.)
+ *
+ * TODO Change to a default method with Java 8?
+ */
+ String INITIAL_SYSCALL_NAME = "clone"; //$NON-NLS-1$
+
+ // ------------------------------------------------------------------------
+ // Event names
+ // ------------------------------------------------------------------------
+
+ String eventIrqHandlerEntry();
+ String eventIrqHandlerExit();
+ String eventSoftIrqEntry();
+ String eventSoftIrqExit();
+ String eventSoftIrqRaise();
+ String eventSchedSwitch();
+ Collection<String> eventsSchedWakeup();
+ String eventSchedProcessFork();
+ String eventSchedProcessExit();
+ String eventSchedProcessFree();
+ String eventStatedumpProcessState();
+ String eventSyscallEntryPrefix();
+ String eventCompatSyscallEntryPrefix();
+ String eventSyscallExit();
+
+ // ------------------------------------------------------------------------
+ // Event field names
+ // ------------------------------------------------------------------------
+
+ String fieldIrq();
+ String fieldVec();
+ String fieldTid();
+ String fieldPrevTid();
+ String fieldPrevState();
+ String fieldNextComm();
+ String fieldNextTid();
+ String fieldChildComm();
+ String fieldParentTid();
+ String fieldChildTid();
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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 API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout;
+
+import java.util.Collection;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * This file defines all the known event and field names for LTTng 2.0 kernel
+ * traces.
+ *
+ * These should not be externalized, since they need to match exactly what the
+ * tracer outputs. If you want to localize them in a view, you should do a
+ * mapping in the view itself.
+ *
+ * @author Alexandre Montplaisir
+ */
+@SuppressWarnings("nls")
+public class LttngEventLayout implements IKernelAnalysisEventLayout {
+
+ /* Event names */
+ private static final String EXIT_SYSCALL = "exit_syscall";
+ private static final String IRQ_HANDLER_ENTRY = "irq_handler_entry";
+ private static final String IRQ_HANDLER_EXIT = "irq_handler_exit";
+ private static final String SOFTIRQ_ENTRY = "softirq_entry";
+ private static final String SOFTIRQ_EXIT = "softirq_exit";
+ private static final String SOFTIRQ_RAISE = "softirq_raise";
+ private static final String SCHED_SWITCH = "sched_switch";
+
+ @SuppressWarnings("null")
+ private static final @NonNull Collection<String> SCHED_WAKEUP_EVENTS = ImmutableList.of("sched_wakeup", "sched_wakeup_new");
+
+ private static final String SCHED_PROCESS_FORK = "sched_process_fork";
+ private static final String SCHED_PROCESS_EXIT = "sched_process_exit";
+ private static final String SCHED_PROCESS_FREE = "sched_process_free";
+ private static final String STATEDUMP_PROCESS_STATE = "lttng_statedump_process_state";
+
+ private static final String SYSCALL_PREFIX = "sys_";
+ private static final String COMPAT_SYSCALL_PREFIX = "compat_sys_";
+
+ /* Field names */
+ private static final String IRQ = "irq";
+ private static final String TID = "tid";
+ private static final String VEC = "vec";
+ private static final String PREV_TID = "prev_tid";
+ private static final String PREV_STATE = "prev_state";
+ private static final String NEXT_COMM = "next_comm";
+ private static final String NEXT_TID = "next_tid";
+ private static final String PARENT_TID = "parent_tid";
+ private static final String CHILD_COMM = "child_comm";
+ private static final String CHILD_TID = "child_tid";
+
+ /** All instances are the same. Only provide a static instance getter */
+ private LttngEventLayout() {
+ }
+
+ private static final IKernelAnalysisEventLayout INSTANCE = new LttngEventLayout();
+
+ /**
+ * Get an instance of this event layout
+ *
+ * This object is completely immutable, so no need to create additional
+ * instances via the constructor.
+ *
+ * @return The instance
+ */
+ public static IKernelAnalysisEventLayout getInstance() {
+ return INSTANCE;
+ }
+
+ // ------------------------------------------------------------------------
+ // Event names
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String eventIrqHandlerEntry() {
+ return IRQ_HANDLER_ENTRY;
+ }
+
+ @Override
+ public String eventIrqHandlerExit() {
+ return IRQ_HANDLER_EXIT;
+ }
+
+ @Override
+ public String eventSoftIrqEntry() {
+ return SOFTIRQ_ENTRY;
+ }
+
+ @Override
+ public String eventSoftIrqExit() {
+ return SOFTIRQ_EXIT;
+ }
+
+ @Override
+ public String eventSoftIrqRaise() {
+ return SOFTIRQ_RAISE;
+ }
+
+ @Override
+ public String eventSchedSwitch() {
+ return SCHED_SWITCH;
+ }
+
+ @Override
+ public Collection<String> eventsSchedWakeup() {
+ return SCHED_WAKEUP_EVENTS;
+ }
+
+ @Override
+ public String eventSchedProcessFork() {
+ return SCHED_PROCESS_FORK;
+ }
+
+ @Override
+ public String eventSchedProcessExit() {
+ return SCHED_PROCESS_EXIT;
+ }
+
+ @Override
+ public String eventSchedProcessFree() {
+ return SCHED_PROCESS_FREE;
+ }
+
+ @Override
+ public String eventStatedumpProcessState() {
+ return STATEDUMP_PROCESS_STATE;
+ }
+ @Override
+ public String eventSyscallExit() {
+ return EXIT_SYSCALL;
+ }
+
+ @Override
+ public String eventSyscallEntryPrefix() {
+ return SYSCALL_PREFIX;
+ }
+
+ @Override
+ public String eventCompatSyscallEntryPrefix() {
+ return COMPAT_SYSCALL_PREFIX;
+ }
+
+ // ------------------------------------------------------------------------
+ // Event field names
+ // ------------------------------------------------------------------------
+
+ @Override
+ public String fieldIrq() {
+ return IRQ;
+ }
+
+ @Override
+ public String fieldVec() {
+ return VEC;
+ }
+
+ @Override
+ public String fieldTid() {
+ return TID;
+ }
+
+ @Override
+ public String fieldPrevTid() {
+ return PREV_TID;
+ }
+
+ @Override
+ public String fieldPrevState() {
+ return PREV_STATE;
+ }
+
+ @Override
+ public String fieldNextComm() {
+ return NEXT_COMM;
+ }
+
+ @Override
+ public String fieldNextTid() {
+ return NEXT_TID;
+ }
+
+ @Override
+ public String fieldChildComm() {
+ return CHILD_COMM;
+ }
+
+ @Override
+ public String fieldParentTid() {
+ return PARENT_TID;
+ }
+
+ @Override
+ public String fieldChildTid() {
+ return CHILD_TID;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 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:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.Activator;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel.LttngKernelAnalysis;
+import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
@Override
protected ITmfStateProvider createStateProvider() {
- return new LttngKernelCpuUsageStateProvider(getTrace());
+ ITmfTrace trace = getTrace();
+ IKernelAnalysisEventLayout layout;
+
+ if (trace instanceof LttngKernelTrace) {
+ layout = ((LttngKernelTrace) trace).getEventLayout();
+ } else {
+ /* Fall-back to the base LttngEventLayout */
+ layout = LttngEventLayout.getInstance();
+ }
+
+ return new LttngKernelCpuUsageStateProvider(trace, layout);
}
@Override
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.Activator;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
-import org.eclipse.tracecompass.internal.lttng2.kernel.core.LttngStrings;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
/* For each CPU, maps the last time a thread was scheduled in */
private final Map<String, Long> fLastStartTimes = new HashMap<>();
private final long fTraceStart;
+ private final @NonNull IKernelAnalysisEventLayout fLayout;
/**
* Constructor
*
* @param trace
* The trace from which to get the CPU usage
+ * @param layout
+ * The event layout to use for this state provider.
*/
- public LttngKernelCpuUsageStateProvider(ITmfTrace trace) {
+ public LttngKernelCpuUsageStateProvider(ITmfTrace trace, @NonNull IKernelAnalysisEventLayout layout) {
super(trace, ITmfEvent.class, "LTTng Kernel CPU usage"); //$NON-NLS-1$
fTraceStart = trace.getStartTime().getValue();
+ fLayout = layout;
}
// ------------------------------------------------------------------------
@Override
public LttngKernelCpuUsageStateProvider getNewInstance() {
- return new LttngKernelCpuUsageStateProvider(this.getTrace());
+ return new LttngKernelCpuUsageStateProvider(this.getTrace(), this.fLayout);
}
@Override
protected void eventHandle(ITmfEvent event) {
final String eventName = event.getType().getName();
- if (eventName.equals(LttngStrings.SCHED_SWITCH)) {
+ if (eventName.equals(fLayout.eventSchedSwitch())) {
/*
* Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64
* prev_state, string next_comm, int32 next_tid, int32 next_prio
long ts = event.getTimestamp().getValue();
String cpu = event.getSource();
- Long prevTid = (Long) content.getField(LttngStrings.PREV_TID).getValue();
+ Long prevTid = (Long) content.getField(fLayout.fieldPrevTid()).getValue();
try {
Integer currentCPUNode = ss.getQuarkRelativeAndAdd(getNodeCPUs(), cpu);
package org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.lttng2.kernel.core.LttngStrings;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
import org.eclipse.tracecompass.lttng2.control.core.session.SessionConfigStrings;
+import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement;
import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import com.google.common.collect.ImmutableSet;
private static final ImmutableSet<String> REQUIRED_EVENTS = ImmutableSet.of();
private static final ImmutableSet<String> OPTIONAL_EVENTS = ImmutableSet.of(
- LttngStrings.EXIT_SYSCALL,
- LttngStrings.IRQ_HANDLER_ENTRY,
- LttngStrings.IRQ_HANDLER_EXIT,
- LttngStrings.SOFTIRQ_ENTRY,
- LttngStrings.SOFTIRQ_EXIT,
- LttngStrings.SOFTIRQ_RAISE,
- LttngStrings.SCHED_PROCESS_FORK,
- LttngStrings.SCHED_PROCESS_EXIT,
- LttngStrings.SCHED_PROCESS_FREE,
- LttngStrings.SCHED_SWITCH,
- LttngStrings.STATEDUMP_PROCESS_STATE,
- LttngStrings.SCHED_WAKEUP,
- LttngStrings.SCHED_WAKEUP_NEW,
-
- /* FIXME Add the prefix for syscalls */
- LttngStrings.SYSCALL_PREFIX
+ // FIXME These cannot be declared statically anymore, they depend on
+ // the OriginTracer of the kernel trace.
+// LttngStrings.EXIT_SYSCALL,
+// LttngStrings.IRQ_HANDLER_ENTRY,
+// LttngStrings.IRQ_HANDLER_EXIT,
+// LttngStrings.SOFTIRQ_ENTRY,
+// LttngStrings.SOFTIRQ_EXIT,
+// LttngStrings.SOFTIRQ_RAISE,
+// LttngStrings.SCHED_PROCESS_FORK,
+// LttngStrings.SCHED_PROCESS_EXIT,
+// LttngStrings.SCHED_PROCESS_FREE,
+// LttngStrings.SCHED_SWITCH,
+// LttngStrings.STATEDUMP_PROCESS_STATE,
+// LttngStrings.SCHED_WAKEUP,
+// LttngStrings.SCHED_WAKEUP_NEW,
+//
+// /* FIXME Add the prefix for syscalls */
+// LttngStrings.SYSCALL_PREFIX
);
/** The requirements as an immutable set */
}
@Override
- @NonNull
- protected ITmfStateProvider createStateProvider() {
- return new LttngKernelStateProvider(getTrace());
+ protected @NonNull ITmfStateProvider createStateProvider() {
+ ITmfTrace trace = getTrace();
+ IKernelAnalysisEventLayout layout;
+
+ if (trace instanceof LttngKernelTrace) {
+ layout = ((LttngKernelTrace) trace).getEventLayout();
+ } else {
+ /* Fall-back to the base LttngEventLayout */
+ layout = LttngEventLayout.getInstance();
+ }
+
+ return new LttngKernelStateProvider(trace, layout);
}
@Override
package org.eclipse.tracecompass.lttng2.kernel.core.analysis.kernel;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes;
-import org.eclipse.tracecompass.internal.lttng2.kernel.core.LttngStrings;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.StateValues;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import com.google.common.collect.ImmutableMap;
+
/**
* This is the state change input plugin for TMF's state system which handles
* the LTTng 2.0 kernel traces in CTF format.
*/
public class LttngKernelStateProvider extends AbstractTmfStateProvider {
+ // ------------------------------------------------------------------------
+ // Static fields
+ // ------------------------------------------------------------------------
+
/**
* Version number of this state provider. Please bump this if you modify the
* contents of the generated state history in some way.
*/
private static final int VERSION = 4;
+ private static final int SYSCALL_EXIT_INDEX = 0;
+ private static final int IRQ_HANDLER_ENTRY_INDEX = 1;
+ private static final int IRQ_HANDLER_EXIT_INDEX = 2;
+ private static final int SOFT_IRQ_ENTRY_INDEX = 3;
+ private static final int SOFT_IRQ_EXIT_INDEX = 4;
+ private static final int SOFT_IRQ_RAISE_INDEX = 5;
+ private static final int SCHED_SWITCH_INDEX = 6;
+ private static final int SCHED_PROCESS_FORK_INDEX = 7;
+ private static final int SCHED_PROCESS_EXIT_INDEX = 8;
+ private static final int SCHED_PROCESS_FREE_INDEX = 9;
+ private static final int STATEDUMP_PROCESS_STATE_INDEX = 10;
+ private static final int SCHED_WAKEUP_INDEX = 11;
+
+
+ // ------------------------------------------------------------------------
+ // Fields
+ // ------------------------------------------------------------------------
+
+ private final Map<String, Integer> fEventNames;
+ private final @NonNull IKernelAnalysisEventLayout fLayout;
+
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
*
* @param trace
* The LTTng 2.0 kernel trace directory
+ * @param layout
+ * The event layout to use for this state provider. Usually
+ * depending on the tracer implementation.
*/
- public LttngKernelStateProvider(ITmfTrace trace) {
- super(trace, ITmfEvent.class, "LTTng Kernel"); //$NON-NLS-1$
+ public LttngKernelStateProvider(ITmfTrace trace, @NonNull IKernelAnalysisEventLayout layout) {
+ super(trace, ITmfEvent.class, "Kernel"); //$NON-NLS-1$
+ fLayout = layout;
+ fEventNames = buildEventNames(layout);
+ }
+
+ // ------------------------------------------------------------------------
+ // Event names management
+ // ------------------------------------------------------------------------
+
+ private static Map<String, Integer> buildEventNames(IKernelAnalysisEventLayout layout) {
+ ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
+
+ builder.put(layout.eventSyscallExit(), SYSCALL_EXIT_INDEX);
+ builder.put(layout.eventIrqHandlerEntry(), IRQ_HANDLER_ENTRY_INDEX);
+ builder.put(layout.eventIrqHandlerExit(), IRQ_HANDLER_EXIT_INDEX);
+ builder.put(layout.eventSoftIrqEntry(), SOFT_IRQ_ENTRY_INDEX);
+ builder.put(layout.eventSoftIrqExit(), SOFT_IRQ_EXIT_INDEX);
+ builder.put(layout.eventSoftIrqRaise(), SOFT_IRQ_RAISE_INDEX);
+ builder.put(layout.eventSchedSwitch(), SCHED_SWITCH_INDEX);
+ builder.put(layout.eventSchedProcessFork(), SCHED_PROCESS_FORK_INDEX);
+ builder.put(layout.eventSchedProcessExit(), SCHED_PROCESS_EXIT_INDEX);
+ builder.put(layout.eventSchedProcessFree(), SCHED_PROCESS_FREE_INDEX);
+ builder.put(layout.eventStatedumpProcessState(), STATEDUMP_PROCESS_STATE_INDEX);
+
+ for (String eventSchedWakeup : layout.eventsSchedWakeup()) {
+ builder.put(eventSchedWakeup, SCHED_WAKEUP_INDEX);
+ }
+
+ return builder.build();
}
// ------------------------------------------------------------------------
@Override
public LttngKernelStateProvider getNewInstance() {
- return new LttngKernelStateProvider(this.getTrace());
+ return new LttngKernelStateProvider(this.getTrace(), fLayout);
}
@Override
* Feed event to the history system if it's known to cause a state
* transition.
*/
- switch (eventName) {
+ Integer idx = fEventNames.get(eventName);
+ int intval = (idx == null ? -1 : idx.intValue());
+ switch (intval) {
- case LttngStrings.EXIT_SYSCALL:
- /* Fields: int64 ret */
+ case SYSCALL_EXIT_INDEX:
{
/* Clear the current system call on the process */
quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
}
break;
- case LttngStrings.IRQ_HANDLER_ENTRY:
- /* Fields: int32 irq, string name */
+ case IRQ_HANDLER_ENTRY_INDEX:
{
- Integer irqId = ((Long) event.getContent().getField(LttngStrings.IRQ).getValue()).intValue();
+ Integer irqId = ((Long) event.getContent().getField(fLayout.fieldIrq()).getValue()).intValue();
/* Mark this IRQ as active in the resource tree.
* The state value = the CPU on which this IRQ is sitting */
}
break;
- case LttngStrings.IRQ_HANDLER_EXIT:
- /* Fields: int32 irq, int32 ret */
+ case IRQ_HANDLER_EXIT_INDEX:
{
- Integer irqId = ((Long) event.getContent().getField(LttngStrings.IRQ).getValue()).intValue();
+ Integer irqId = ((Long) event.getContent().getField(fLayout.fieldIrq()).getValue()).intValue();
/* Put this IRQ back to inactive in the resource tree */
quark = ss.getQuarkRelativeAndAdd(getNodeIRQs(), irqId.toString());
}
break;
- case LttngStrings.SOFTIRQ_ENTRY:
- /* Fields: int32 vec */
+ case SOFT_IRQ_ENTRY_INDEX:
{
- Integer softIrqId = ((Long) event.getContent().getField(LttngStrings.VEC).getValue()).intValue();
+ Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
/* Mark this SoftIRQ as active in the resource tree.
* The state value = the CPU on which this SoftIRQ is processed */
}
break;
- case LttngStrings.SOFTIRQ_EXIT:
- /* Fields: int32 vec */
+ case SOFT_IRQ_EXIT_INDEX:
{
- Integer softIrqId = ((Long) event.getContent().getField(LttngStrings.VEC).getValue()).intValue();
+ Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
/* Put this SoftIRQ back to inactive (= -1) in the resource tree */
quark = ss.getQuarkRelativeAndAdd(getNodeSoftIRQs(), softIrqId.toString());
}
break;
- case LttngStrings.SOFTIRQ_RAISE:
+ case SOFT_IRQ_RAISE_INDEX:
/* Fields: int32 vec */
{
- Integer softIrqId = ((Long) event.getContent().getField(LttngStrings.VEC).getValue()).intValue();
+ Integer softIrqId = ((Long) event.getContent().getField(fLayout.fieldVec()).getValue()).intValue();
/* Mark this SoftIRQ as *raised* in the resource tree.
* State value = -2 */
}
break;
- case LttngStrings.SCHED_SWITCH:
- /*
- * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state,
- * string next_comm, int32 next_tid, int32 next_prio
- */
+ case SCHED_SWITCH_INDEX:
{
ITmfEventField content = event.getContent();
- Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue();
- Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue();
- String nextProcessName = (String) content.getField(LttngStrings.NEXT_COMM).getValue();
- Integer nextTid = ((Long) content.getField(LttngStrings.NEXT_TID).getValue()).intValue();
+ Integer prevTid = ((Long) content.getField(fLayout.fieldPrevTid()).getValue()).intValue();
+ Long prevState = (Long) content.getField(fLayout.fieldPrevState()).getValue();
+ String nextProcessName = (String) content.getField(fLayout.fieldNextComm()).getValue();
+ Integer nextTid = ((Long) content.getField(fLayout.fieldNextTid()).getValue()).intValue();
Integer formerThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), prevTid.toString());
Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), nextTid.toString());
}
break;
- case LttngStrings.SCHED_PROCESS_FORK:
- /* Fields: string parent_comm, int32 parent_tid,
- * string child_comm, int32 child_tid */
+ case SCHED_PROCESS_FORK_INDEX:
{
ITmfEventField content = event.getContent();
// String parentProcessName = (String) event.getFieldValue("parent_comm");
- String childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue();
+ String childProcessName = (String) content.getField(fLayout.fieldChildComm()).getValue();
// assert ( parentProcessName.equals(childProcessName) );
- Integer parentTid = ((Long) content.getField(LttngStrings.PARENT_TID).getValue()).intValue();
- Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue();
+ Integer parentTid = ((Long) content.getField(fLayout.fieldParentTid()).getValue()).intValue();
+ Integer childTid = ((Long) content.getField(fLayout.fieldChildTid()).getValue()).intValue();
Integer parentTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), parentTid.toString());
Integer childTidNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), childTid.toString());
* Maybe we were missing info about the parent? At least we
* will set the child right. Let's suppose "sys_clone".
*/
- value = TmfStateValue.newValueString(LttngStrings.SYS_CLONE);
+ value = TmfStateValue.newValueString(fLayout.eventSyscallEntryPrefix() + IKernelAnalysisEventLayout.INITIAL_SYSCALL_NAME);
}
quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL);
ss.modifyAttribute(ts, value, quark);
}
break;
- case LttngStrings.SCHED_PROCESS_EXIT:
- /* Fields: string comm, int32 tid, int32 prio */
+ case SCHED_PROCESS_EXIT_INDEX:
break;
- case LttngStrings.SCHED_PROCESS_FREE:
- /* Fields: string comm, int32 tid, int32 prio */
- /*
- * A sched_process_free will always happen after the sched_switch
- * that will remove the process from the cpu for the last time. So
- * this is when we should delete everything wrt to the process.
- */
+ case SCHED_PROCESS_FREE_INDEX:
{
- Integer tid = ((Long) event.getContent().getField(LttngStrings.TID).getValue()).intValue();
+ Integer tid = ((Long) event.getContent().getField(fLayout.fieldTid()).getValue()).intValue();
/*
* Remove the process and all its sub-attributes from the
* current state
}
break;
- case LttngStrings.STATEDUMP_PROCESS_STATE:
- /* Fields:
- * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid,
- * int32 ppid, int32 tid, string name, int32 status, int32 vtid */
+ case STATEDUMP_PROCESS_STATE_INDEX:
+ /* LTTng-specific */
{
ITmfEventField content = event.getContent();
- int tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue();
- int pid = ((Long) content.getField(LttngStrings.PID).getValue()).intValue();
- int ppid = ((Long) content.getField(LttngStrings.PPID).getValue()).intValue();
- int status = ((Long) content.getField(LttngStrings.STATUS).getValue()).intValue();
- String name = (String) content.getField(LttngStrings.NAME).getValue();
+ int tid = ((Long) content.getField("tid").getValue()).intValue(); //$NON-NLS-1$
+ int pid = ((Long) content.getField("pid").getValue()).intValue(); //$NON-NLS-1$
+ int ppid = ((Long) content.getField("ppid").getValue()).intValue(); //$NON-NLS-1$
+ int status = ((Long) content.getField("status").getValue()).intValue(); //$NON-NLS-1$
+ String name = (String) content.getField("name").getValue(); //$NON-NLS-1$
/*
* "mode" could be interesting too, but it doesn't seem to be
* populated with anything relevant for now.
}
break;
- case LttngStrings.SCHED_WAKEUP:
- case LttngStrings.SCHED_WAKEUP_NEW:
- /* Fields (same fields for both types):
- * string comm, int32 pid, int32 prio, int32 success,
- * int32 target_cpu */
+ case SCHED_WAKEUP_INDEX:
{
- final int tid = ((Long) event.getContent().getField(LttngStrings.TID).getValue()).intValue();
+ final int tid = ((Long) event.getContent().getField(fLayout.fieldTid()).getValue()).intValue();
final int threadNode = ss.getQuarkRelativeAndAdd(getNodeThreads(), String.valueOf(tid));
/*
default:
/* Other event types not covered by the main switch */
{
- if (eventName.startsWith(LttngStrings.SYSCALL_PREFIX)
- || eventName.startsWith(LttngStrings.COMPAT_SYSCALL_PREFIX)) {
+ if (eventName.startsWith(fLayout.eventSyscallEntryPrefix())
+ || eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix())) {
/*
* This is a replacement for the old sys_enter event. Now
* syscall names are listed into the event type
import java.nio.BufferOverflowException;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
import org.eclipse.tracecompass.ctf.core.trace.CTFTrace;
import org.eclipse.tracecompass.internal.lttng2.kernel.core.Activator;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout.LttngEventLayout;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
* traces.
*
* @author Alexandre Montplaisir
- * @since 2.0
*/
public class LttngKernelTrace extends CtfTmfTrace {
+ /**
+ * Supported Linux kernel tracers
+ */
+ private enum OriginTracer {
+ LTTNG(LttngEventLayout.getInstance());
+
+ private final @NonNull IKernelAnalysisEventLayout fLayout;
+
+ private OriginTracer(@NonNull IKernelAnalysisEventLayout layout) {
+ fLayout = layout;
+ }
+ }
+
+ /**
+ * CTF metadata identifies trace type and tracer version pretty well, we are
+ * quite confident in the inferred trace type.
+ */
private static final int CONFIDENCE = 100;
+ /** The tracer which originated this trace */
+ private OriginTracer fOriginTracer = null;
+
/**
* Default constructor
*/
super();
}
+ /**
+ * Return the kernel event layout (event and field names) used in this
+ * trace.
+ *
+ * @return The event layout
+ */
+ public @NonNull IKernelAnalysisEventLayout getEventLayout() {
+ OriginTracer tracer = fOriginTracer;
+ if (tracer == null) {
+ throw new IllegalStateException("Cannot get the layout of a non-initialized trace!"); //$NON-NLS-1$
+ }
+ return tracer.fLayout;
+ }
+
+ @Override
+ public void initTrace(IResource resource, String path,
+ Class<? extends ITmfEvent> eventType) throws TmfTraceException {
+ /*
+ * Set the 'fOriginTracer' in accordance to what is found in the
+ * metadata
+ */
+ fOriginTracer = OriginTracer.LTTNG;
+
+ super.initTrace(resource, path, eventType);
+ }
+
/**
* {@inheritDoc}
* <p>