analysis: introduce latency table view
authorFrance Lapointe Nguyen <francelap@gmail.com>
Fri, 21 Aug 2015 22:06:46 +0000 (18:06 -0400)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 26 Aug 2015 17:54:09 +0000 (13:54 -0400)
Change-Id: Icdad089daf432306146cd390bf5694a95dc0b5f8
Signed-off-by: France Lapointe Nguyen <francelap@gmail.com>
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-on: https://git.eclipse.org/r/52255
Reviewed-by: Hudson CI
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
17 files changed:
analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.core/plugin.properties
analysis/org.eclipse.tracecompass.analysis.os.linux.core/plugin.xml
analysis/org.eclipse.tracecompass.analysis.os.linux.core/pom.xml
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysis.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysisListener.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/SystemCall.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/package-info.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/META-INF/MANIFEST.MF
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/plugin.properties
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/plugin.xml
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyContentProvider.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyTableViewer.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyView.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/Messages.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/messages.properties [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/package-info.java [new file with mode: 0644]

index 0a76920665a3ae2579a41df5466d16a14b4fe5f7..caee9bdf25ad7bee7d4d86e0b5af8fab559b1a66 100644 (file)
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 1.1.0.qualifier
 Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.tracecompass.analysis.os.linux.core;singleton:=true
 Bundle-Activator: org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator
@@ -11,12 +11,15 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.core.resources,
  org.eclipse.tracecompass.common.core,
- org.eclipse.tracecompass.tmf.core
-Import-Package: com.google.common.collect,
- com.google.common.hash;version="15.0.0"
+ org.eclipse.tracecompass.tmf.core,
+ org.eclipse.tracecompass.segmentstore.core
+Import-Package: com.google.common.base,
+ com.google.common.collect,
+ com.google.common.hash
 Export-Package: org.eclipse.tracecompass.analysis.os.linux.core.cpuusage,
  org.eclipse.tracecompass.analysis.os.linux.core.event.aspect,
  org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis,
+ org.eclipse.tracecompass.analysis.os.linux.core.latency,
  org.eclipse.tracecompass.analysis.os.linux.core.model,
  org.eclipse.tracecompass.analysis.os.linux.core.trace,
  org.eclipse.tracecompass.internal.analysis.os.linux.core;x-internal:=true,
index 8d0a7f4b87604fdfae87158abbb4af3208ef10e9..8866c02db35af0af006d383c8c10908a00e9b76d 100644 (file)
@@ -17,4 +17,5 @@ tracetype.type.kernel = Linux Kernel Trace
 analysis.linuxkernel = Linux Kernel Analysis
 
 analysis.cpuusage = CPU usage
+analysis.latency = Latency Analysis
 
index 46b9a6355e2fa2eaeb3939cb15c499416016d2d2..e431977e9f67d3b529d103db8a9e85bdc1b8a67b 100644 (file)
                class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace">
          </tracetype>
       </module>
+      <module
+            analysis_module="org.eclipse.tracecompass.analysis.os.linux.core.latency.LatencyAnalysis"
+            automatic="false"
+            id="org.eclipse.tracecompass.analysis.os.linux.latency"
+            name="%analysis.latency">
+         <tracetype
+               applies="true"
+               class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace">
+         </tracetype>
+      </module>
    </extension>
 </plugin>
index b21aba5ed56720bf4b3eda564c562ffeba7c49e4..7de0b21c25717979e0ef4b4ad29ac6e91b405cf3 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-   Copyright (C) 2011, Red Hat, Inc.
+   Copyright (C) 2011, 2015 Red Hat, Inc. and others
 
    All rights reserved. This program and the accompanying materials
    are made available under the terms of the Eclipse Public License v1.0
@@ -19,7 +19,7 @@
 
   <artifactId>org.eclipse.tracecompass.analysis.os.linux.core</artifactId>
   <groupId>org.eclipse.tracecompass</groupId>
-  <version>1.0.0-SNAPSHOT</version>
+  <version>1.1.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <name>Trace Compass Linux Kernel Analysis Core Plug-in</name>
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysis.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysis.java
new file mode 100644 (file)
index 0000000..8b8d50f
--- /dev/null
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EfficiOS Inc., 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.os.linux.core.latency;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelTidAspect;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
+import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+
+/**
+ * @author Alexandre Montplaisir
+ * @since 1.1
+ */
+public class LatencyAnalysis extends TmfAbstractAnalysisModule {
+
+    /**
+     * The ID of this analysis
+     */
+    public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.latency"; //$NON-NLS-1$
+
+    private static final String DATA_FILENAME = "latency-analysis.dat"; //$NON-NLS-1$
+
+    private @Nullable ISegmentStore<ISegment> fSystemCalls;
+
+    private final Set<LatencyAnalysisListener> fListeners = new HashSet<>();
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    /**
+     * Listener for the viewers
+     *
+     * @param listener
+     *            listener for each type of viewer
+     */
+    public void addListener(LatencyAnalysisListener listener) {
+        fListeners.add(listener);
+    }
+
+    @Override
+    protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException {
+        IKernelTrace trace = checkNotNull((IKernelTrace) getTrace());
+        IKernelAnalysisEventLayout layout = trace.getKernelEventLayout();
+
+        /* See if the data file already exists on disk */
+        String dir = TmfTraceManager.getSupplementaryFileDir(trace);
+        final Path file = Paths.get(dir, DATA_FILENAME);
+
+        if (Files.exists(file)) {
+            /* Attempt to read the existing file */
+            try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file))) {
+                @SuppressWarnings("unchecked")
+                ISegmentStore<ISegment> syscalls = (ISegmentStore<ISegment>) ois.readObject();
+                fSystemCalls = syscalls;
+                return true;
+            } catch (IOException | ClassNotFoundException | ClassCastException e) {
+                /*
+                 * We did not manage to read the file successfully, we will just
+                 * fall-through to rebuild a new one.
+                 */
+                try {
+                    Files.delete(file);
+                } catch (IOException e1) {
+                }
+            }
+        }
+
+        ISegmentStore<ISegment> syscalls = new TreeMapStore<>();
+        ITmfEventRequest req = new LatencyAnalysisRequest(layout, syscalls);
+        trace.sendRequest(req);
+        try {
+            req.waitForCompletion();
+        } catch (InterruptedException e) {
+        }
+        /* The request will fill 'syscalls' */
+        fSystemCalls = syscalls;
+
+        /* Serialize the collections to disk for future usage */
+        try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(file))) {
+            oos.writeObject(syscalls);
+        } catch (IOException e) {
+            /* Didn't work, oh well. We will just re-read the trace next time */
+        }
+
+        for (LatencyAnalysisListener listener : fListeners) {
+            listener.onComplete(this, syscalls);
+        }
+
+        return true;
+    }
+
+    @Override
+    protected void canceling() {
+
+    }
+
+    /**
+     * @return Results from the analysis in a ISegmentStore
+     */
+    public @Nullable ISegmentStore<ISegment> getResults() {
+        return fSystemCalls;
+    }
+
+    private static class LatencyAnalysisRequest extends TmfEventRequest {
+
+        private final IKernelAnalysisEventLayout fLayout;
+        private final ISegmentStore<ISegment> fFullSyscalls;
+        private final Map<Integer, SystemCall.InitialInfo> fOngoingSystemCalls = new HashMap<>();
+
+        public LatencyAnalysisRequest(IKernelAnalysisEventLayout layout, ISegmentStore<ISegment> syscalls) {
+            super(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND);
+            fLayout = layout;
+            /*
+             * We do NOT make a copy here! We want to modify the list that was
+             * passed in parameter.
+             */
+            fFullSyscalls = syscalls;
+        }
+
+        @Override
+        public void handleData(final ITmfEvent event) {
+            super.handleData(event);
+            final String eventName = event.getType().getName();
+
+            if (eventName.startsWith(fLayout.eventSyscallEntryPrefix()) ||
+                    eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix())) {
+                /* This is a system call entry event */
+
+                Integer tid = KernelTidAspect.INSTANCE.resolve(event);
+                if (tid == null) {
+                    // no information on this event/trace ?
+                    return;
+                }
+
+                /* Record the event's data into the intial system call info */
+                // String syscallName = fLayout.getSyscallNameFromEvent(event);
+                long startTime = event.getTimestamp().getValue();
+                String syscallName = eventName.substring(fLayout.eventSyscallEntryPrefix().length());
+                FluentIterable<String> argNames = FluentIterable.from(event.getContent().getFieldNames());
+                Map<String, String> args = argNames.toMap(new Function<String, String>() {
+                    @Override
+                    public String apply(@Nullable String input) {
+                        return checkNotNull(event.getContent().getField(input).getValue().toString());
+                    }
+                });
+                SystemCall.InitialInfo newSysCall = new SystemCall.InitialInfo(startTime, NonNullUtils.checkNotNull(syscallName), NonNullUtils.checkNotNull(args));
+                fOngoingSystemCalls.put(tid, newSysCall);
+
+            } else if (eventName.startsWith(fLayout.eventSyscallExitPrefix())) {
+                /* This is a system call exit event */
+
+                Integer tid = KernelTidAspect.INSTANCE.resolve(event);
+                if (tid == null) {
+                    return;
+                }
+
+                SystemCall.InitialInfo info = fOngoingSystemCalls.remove(tid);
+                if (info == null) {
+                    /*
+                     * We have not seen the entry event corresponding to this
+                     * exit (lost event, or before start of trace).
+                     */
+                    return;
+                }
+
+                long endTime = event.getTimestamp().getValue();
+                int ret = ((Long) event.getContent().getField("ret").getValue()).intValue(); //$NON-NLS-1$
+                ISegment syscall = new SystemCall(info, endTime, ret);
+                fFullSyscalls.addElement(syscall);
+            }
+        }
+
+        @Override
+        public void handleCompleted() {
+            fOngoingSystemCalls.clear();
+        }
+    }
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysisListener.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/LatencyAnalysisListener.java
new file mode 100644 (file)
index 0000000..d6e1938
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.os.linux.core.latency;
+
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+
+/**
+ * End of latency analysis listener for latency viewers
+ *
+ * @author France Lapointe Nguyen
+ * @since 1.1
+ */
+public interface LatencyAnalysisListener {
+
+    /**
+     * Called at the end of the latency analysis
+     *
+     * @param activeAnalysis
+     *            latency analysis that is running
+     *
+     * @param data
+     *            results of the latency analysis
+     */
+    void onComplete(LatencyAnalysis activeAnalysis, ISegmentStore<ISegment> data);
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/SystemCall.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/SystemCall.java
new file mode 100644 (file)
index 0000000..1fbbbdd
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * 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.tracecompass.analysis.os.linux.core.latency;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Ordering;
+
+/**
+ * A linux kernel system call, represented as an {@link ISegment}.
+ *
+ * @author Alexandre Montplaisir
+ * @since 1.1
+ */
+public class SystemCall implements ISegment {
+
+    private static final long serialVersionUID = 1554494342105208730L;
+
+    private static final Comparator<ISegment> COMPARATOR = checkNotNull(Ordering
+            .from(SegmentComparators.INTERVAL_START_COMPARATOR)
+            .compound(SegmentComparators.INTERVAL_END_COMPARATOR)
+             /* Kind of lazy, but should work! */
+            .compound(Ordering.usingToString()));
+
+    /**
+     * The subset of information that is available from the syscall entry event.
+     */
+    public static class InitialInfo implements Serializable {
+
+        private static final long serialVersionUID = -5009710718804983721L;
+
+        private final long fStartTime;
+        private final String fName;
+        private final Map<String, String> fArgs;
+
+        /**
+         * @param startTime
+         *            Start time of the system call
+         * @param name
+         *            Name of the system call
+         * @param arguments
+         *            Arguments of the system call
+         */
+        public InitialInfo(
+                long startTime,
+                String name,
+                Map<String, String> arguments) {
+            fStartTime = startTime;
+            fName = name;
+            fArgs = NonNullUtils.checkNotNull(ImmutableMap.copyOf(arguments));
+        }
+    }
+
+    private final InitialInfo fInfo;
+    private final long fEndTime;
+    private final int fRet;
+    private final transient long fDuration;
+
+    /**
+     * @param info
+     *            Initial information of the system call
+     * @param endTime
+     *            End time of the system call
+     * @param ret
+     *            Return value of the system call
+     */
+    public SystemCall(
+            InitialInfo info,
+            long endTime,
+            int ret) {
+        fInfo = info;
+        fEndTime = endTime;
+        fRet = ret;
+        fDuration = fEndTime - fInfo.fStartTime;
+    }
+
+    @Override
+    public long getStart() {
+        return fInfo.fStartTime;
+    }
+
+    @Override
+    public long getEnd() {
+        return fEndTime;
+    }
+
+    @Override
+    public long getLength() {
+        return fDuration;
+    }
+
+    /**
+     * Get the name of the system call
+     *
+     * @return Name
+     */
+    public String getName() {
+        return fInfo.fName;
+    }
+
+    /**
+     * Get the arguments of the system call
+     *
+     * @return Map of the arguments
+     */
+    public Map<String, String> getArguments() {
+        return fInfo.fArgs;
+    }
+
+    /**
+     * Get the return value of the system call
+     *
+     * @return Return value
+     */
+    public int getReturnValue() {
+        return fRet;
+    }
+
+
+    @Override
+    public int compareTo(@Nullable ISegment o) {
+        if (o == null) {
+            throw new IllegalArgumentException();
+        }
+        return COMPARATOR.compare(this, o);
+    }
+
+    @Override
+    public String toString() {
+        return "Start Time = " + getStart() + //$NON-NLS-1$
+                "; End Time = " + getEnd() + //$NON-NLS-1$
+                "; Duration = " + getLength() + //$NON-NLS-1$
+                "; Name = " + getName() + //$NON-NLS-1$
+                "; Args = " + getArguments().toString() + //$NON-NLS-1$
+                "; Return = " + getReturnValue(); //$NON-NLS-1$
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/package-info.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/latency/package-info.java
new file mode 100644 (file)
index 0000000..2ad2c43
--- /dev/null
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompass.analysis.os.linux.core.latency;
index dc16a280e9a6702736a487298b6d220062ef97ca..0b864fef5c7900963b15ee94edd8e9d816ef6520 100644 (file)
@@ -16,9 +16,11 @@ Require-Bundle: org.eclipse.ui,
  org.eclipse.tracecompass.analysis.os.linux.core,
  org.eclipse.tracecompass.tmf.core,
  org.eclipse.tracecompass.tmf.ui,
- org.eclipse.tracecompass.tmf.ctf.core
+ org.eclipse.tracecompass.tmf.ctf.core,
+ org.eclipse.tracecompass.segmentstore.core
 Import-Package: com.google.common.collect
 Export-Package: org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow,
  org.eclipse.tracecompass.analysis.os.linux.ui.views.cpuusage,
  org.eclipse.tracecompass.analysis.os.linux.ui.views.resources,
- org.eclipse.tracecompass.internal.analysis.os.linux.ui;x-internal:=true
+ org.eclipse.tracecompass.internal.analysis.os.linux.ui;x-internal:=true,
+ org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;x-internal:=true
index 724b0f21051d37a28825df6d793f1a36438f8197..90dd15b4b12c32c58cb5618712fb2ab7c17161aa 100644 (file)
@@ -18,3 +18,4 @@ kernel.perspective.name = LTTng Kernel
 controlflow.view.name = Control Flow
 resources.view.name = Resources
 cpuusage.view.name = CPU Usage
+latency.view.name = Latency Analysis
\ No newline at end of file
index 626f274e28a50c2b239501de21622a0d51782c39..944c0fa95612cb129a535ce9da8fdc54cf96976e 100644 (file)
             name="%cpuusage.view.name"
             restorable="true">
       </view>
+      <view
+            allowMultiple="false"
+            category="org.eclipse.linuxtools.lttng2.ui.views.category"
+            class="org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.LatencyView"
+            id="org.eclipse.tracecompass.analysis.os.linux.views.latency"
+            name="%latency.view.name"
+            restorable="true">
+      </view>
    </extension>
    <extension
          point="org.eclipse.linuxtools.tmf.core.analysis">
                class="org.eclipse.tracecompass.analysis.os.linux.core.cpuusage.KernelCpuUsageAnalysis">
          </analysisModuleClass>
       </output>
+      <output
+            class="org.eclipse.tracecompass.tmf.ui.analysis.TmfAnalysisViewOutput"
+            id="org.eclipse.tracecompass.analysis.os.linux.views.latency">
+         <analysisModuleClass
+               class="org.eclipse.tracecompass.analysis.os.linux.core.latency.LatencyAnalysis">
+         </analysisModuleClass>
+      </output>
    </extension>
 </plugin>
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyContentProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyContentProvider.java
new file mode 100644 (file)
index 0000000..ec15245
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ *   France Lapointe Nguyen - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.tmf.ui.viewers.table.ISortingLazyContentProvider;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * Content provider for the latency table viewers.
+ *
+ * @author France Lapointe Nguyen
+ */
+public class LatencyContentProvider implements ISortingLazyContentProvider {
+
+    /**
+     * Array of all the segments in the segment store of the current trace
+     */
+    private @Nullable ISegment[] fSegmentArray = null;
+
+    /**
+     * Table viewer of the latency table viewer
+     */
+    private @Nullable TableViewer fTableViewer = null;
+
+    /**
+     * Segment comparator
+     */
+    private @Nullable Comparator<ISegment> fComparator = null;
+
+    @Override
+    public void updateElement(int index) {
+        final TableViewer tableViewer = fTableViewer;
+        final ISegment[] segmentArray = fSegmentArray;
+        if (tableViewer != null && segmentArray != null) {
+            tableViewer.replace(segmentArray[index], index);
+        }
+    }
+
+    @Override
+    public void dispose() {
+        fSegmentArray = null;
+        fTableViewer = null;
+        fComparator = null;
+    }
+
+    @Override
+    public void inputChanged(@Nullable Viewer viewer, @Nullable Object oldInput, @Nullable Object newInput) {
+        fTableViewer = (TableViewer) viewer;
+        if (newInput instanceof ISegmentStore<?>) {
+            ISegmentStore<?> segmentStore = (ISegmentStore<?>) newInput;
+            fSegmentArray = Iterables.toArray(segmentStore, ISegment.class);
+            if (fComparator != null) {
+                Arrays.sort(fSegmentArray, fComparator);
+            }
+        } else {
+            fSegmentArray = null;
+        }
+    }
+
+    @Override
+    public void setSortOrder(@Nullable Comparator<?> comparator) {
+        if (comparator == null) {
+            return;
+        }
+        if (fSegmentArray == null) {
+            return;
+        }
+        final TableViewer tableViewer = fTableViewer;
+        if (tableViewer == null) {
+            return;
+        }
+        fComparator = (Comparator<ISegment>) comparator;
+        Arrays.sort(fSegmentArray, fComparator);
+        tableViewer.refresh();
+    }
+
+    /**
+     * Get the segment count
+     *
+     * @return the segment count
+     */
+    public int getSegmentCount() {
+        ISegment[] segmentArray = fSegmentArray;
+        return (segmentArray == null ? 0 : segmentArray.length);
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyTableViewer.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyTableViewer.java
new file mode 100644 (file)
index 0000000..7f68c6f
--- /dev/null
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ *   France Lapointe Nguyen - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tracecompass.analysis.os.linux.core.latency.LatencyAnalysis;
+import org.eclipse.tracecompass.analysis.os.linux.core.latency.LatencyAnalysisListener;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
+import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.eclipse.tracecompass.tmf.ui.viewers.table.TmfSimpleTableViewer;
+
+/**
+ * Displays the latency analysis data in a column table
+ *
+ * @author France Lapointe Nguyen
+ */
+public class LatencyTableViewer extends TmfSimpleTableViewer {
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    /**
+     * Abstract class for the column label provider for the latency analysis
+     * table viewer
+     */
+    private abstract class LatencyTableColumnLabelProvider extends ColumnLabelProvider {
+
+        @Override
+        public String getText(@Nullable Object input) {
+            if (!(input instanceof ISegment)) {
+                /* Doubles as a null check */
+                return ""; //$NON-NLS-1$
+            }
+            return getTextFoITimeRange((ISegment) input);
+        }
+
+        public abstract String getTextFoITimeRange(ISegment input);
+    }
+
+    /**
+     * Listener to update the model with the latency analysis results once the
+     * latency analysis is fully completed
+     */
+    private final class LatencyListener implements LatencyAnalysisListener {
+        @Override
+        public void onComplete(LatencyAnalysis activeAnalysis, ISegmentStore<ISegment> data) {
+            // Check if the active trace was changed while the analysis was
+            // running
+            if (activeAnalysis.equals(fAnalysisModule)) {
+                updateModel(data);
+            }
+        }
+    }
+
+    /**
+     * Listener to select a range in other viewers when a cell of the latency
+     * table view is selected
+     */
+    private class LatencyTableSelectionListener extends SelectionAdapter {
+        @Override
+        public void widgetSelected(@Nullable SelectionEvent e) {
+            ISegment selectedSegment = ((ISegment) NonNullUtils.checkNotNull(e).item.getData());
+            ITmfTimestamp start = new TmfNanoTimestamp(selectedSegment.getStart());
+            ITmfTimestamp end = new TmfNanoTimestamp(selectedSegment.getEnd());
+            TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(LatencyTableViewer.this, start, end));
+        }
+    }
+
+    /**
+     * Current latency analysis module
+     */
+    private @Nullable LatencyAnalysis fAnalysisModule = null;
+
+    /**
+     * Latency analysis completion listener
+     */
+    private LatencyListener fListener;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor
+     *
+     * @param tableViewer
+     *            Table viewer of the view
+     */
+    public LatencyTableViewer(TableViewer tableViewer) {
+        super(tableViewer);
+        // Sort order of the content provider is by start time by default
+        getTableViewer().setContentProvider(new LatencyContentProvider());
+        ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
+        if (trace != null) {
+            fAnalysisModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, LatencyAnalysis.class, LatencyAnalysis.ID);
+        }
+        createColumns();
+        getTableViewer().getTable().addSelectionListener(new LatencyTableSelectionListener());
+        fListener = new LatencyListener();
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    /**
+     * Create columns for start time, end time and duration
+     */
+    private void createColumns() {
+        createColumn(Messages.LatencyTableViewer_startTime, new LatencyTableColumnLabelProvider() {
+            @Override
+            public String getTextFoITimeRange(ISegment input) {
+                return NonNullUtils.nullToEmptyString(TmfTimestampFormat.getDefaulTimeFormat().format(input.getStart()));
+            }
+        }, SegmentComparators.INTERVAL_START_COMPARATOR);
+
+        createColumn(Messages.LatencyTableViewer_endTime, new LatencyTableColumnLabelProvider() {
+            @Override
+            public String getTextFoITimeRange(ISegment input) {
+                return NonNullUtils.nullToEmptyString(TmfTimestampFormat.getDefaulTimeFormat().format(input.getEnd()));
+            }
+        }, SegmentComparators.INTERVAL_END_COMPARATOR);
+
+        createColumn(Messages.LatencyTableViewer_duration, new LatencyTableColumnLabelProvider() {
+            @Override
+            public String getTextFoITimeRange(ISegment input) {
+                return NonNullUtils.nullToEmptyString(Long.toString(input.getLength()));
+            }
+        }, SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
+    }
+
+    /**
+     * Update the data in the table viewer
+     *
+     * @param dataInput
+     *            New data input
+     */
+    public void updateModel(final @Nullable ISegmentStore<ISegment> dataInput) {
+        final TableViewer tableViewer = getTableViewer();
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                if (!tableViewer.getTable().isDisposed()) {
+                    // Go to the top of the table
+                    tableViewer.getTable().setTopIndex(0);
+                    // Reset selected row
+                    tableViewer.setSelection(StructuredSelection.EMPTY);
+                    if (dataInput == null) {
+                        tableViewer.setInput(null);
+                        tableViewer.setItemCount(0);
+                        return;
+                    }
+                    tableViewer.setInput(dataInput);
+                    LatencyContentProvider latencyContentProvider = (LatencyContentProvider) getTableViewer().getContentProvider();
+                    tableViewer.setItemCount(latencyContentProvider.getSegmentCount());
+                }
+            }
+        });
+    }
+
+    /**
+     * Set the data into the viewer. Will update model is analysis is completed
+     * or run analysis if not completed
+     *
+     * @param analysis
+     *            Latency analysis module
+     */
+    public void setData(@Nullable LatencyAnalysis analysis) {
+        // Set the current latency analysis module
+        fAnalysisModule = analysis;
+        if (analysis == null) {
+            updateModel(null);
+            return;
+        }
+        ISegmentStore<ISegment> results = analysis.getResults();
+        // If results are not null, then analysis is completed and model can be
+        // updated
+        if (results != null) {
+            updateModel(results);
+            return;
+        }
+        // If results are null, then add completion listener and run analysis
+        updateModel(null);
+        analysis.addListener(fListener);
+        analysis.schedule();
+    }
+
+    // ------------------------------------------------------------------------
+    // Getters
+    // ------------------------------------------------------------------------
+
+    /**
+     * Get current latency analysis module
+     *
+     * @return current latency analysis module
+     */
+    public @Nullable LatencyAnalysis getAnalysisModule() {
+        return fAnalysisModule;
+    }
+
+    // ------------------------------------------------------------------------
+    // Signal handlers
+    // ------------------------------------------------------------------------
+
+    /**
+     * Trace selected handler
+     *
+     * @param signal
+     *            Different opened trace (on which latency analysis as already
+     *            been performed) has been selected
+     */
+    @TmfSignalHandler
+    public void traceSelected(TmfTraceSelectedSignal signal) {
+        ITmfTrace trace = signal.getTrace();
+        if (trace != null) {
+            setData(TmfTraceUtils.getAnalysisModuleOfClass(trace, LatencyAnalysis.class, LatencyAnalysis.ID));
+        }
+    }
+
+    /**
+     * Trace opened handler
+     *
+     * @param signal
+     *            New trace (on which latency analysis has not been performed)
+     *            is opened
+     */
+    @TmfSignalHandler
+    public void traceOpened(TmfTraceOpenedSignal signal) {
+        ITmfTrace trace = signal.getTrace();
+        if (trace != null) {
+            setData(TmfTraceUtils.getAnalysisModuleOfClass(trace, LatencyAnalysis.class, LatencyAnalysis.ID));
+        }
+    }
+
+    /**
+     * Trace closed handler
+     *
+     * @param signal
+     *            Last opened trace was closed
+     */
+    @TmfSignalHandler
+    public void traceClosed(TmfTraceClosedSignal signal) {
+        // Check if there is no more opened trace
+        if (TmfTraceManager.getInstance().getActiveTrace() == null) {
+            if (!getTableViewer().getTable().isDisposed()) {
+                getTableViewer().setInput(null);
+                refresh();
+            }
+        }
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyView.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/LatencyView.java
new file mode 100644 (file)
index 0000000..b0fd96a
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ *   France Lapointe Nguyen - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tracecompass.tmf.ui.views.TmfView;
+
+/**
+ * View for the latency analysis
+ *
+ * @author France Lapointe Nguyen
+ */
+public class LatencyView extends TmfView {
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    /** The view's ID */
+    public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.latency"; //$NON-NLS-1$
+
+    private @Nullable LatencyTableViewer fTableViewer;
+
+    // ------------------------------------------------------------------------
+    // Constructor
+    // ------------------------------------------------------------------------
+
+    /**
+     * Constructor
+     */
+    public LatencyView() {
+        super(ID);
+    }
+
+    // ------------------------------------------------------------------------
+    // ViewPart
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void createPartControl(@Nullable Composite parent) {
+        SashForm sf = new SashForm(parent, SWT.NONE);
+        TableViewer tableViewer = new TableViewer(sf, SWT.FULL_SELECTION | SWT.VIRTUAL);
+        fTableViewer = new LatencyTableViewer(tableViewer);
+        setInitialData();
+    }
+
+    // ------------------------------------------------------------------------
+    // Operations
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void setFocus() {
+        if (fTableViewer != null) {
+            fTableViewer.getTableViewer().getControl().setFocus();
+        }
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        if (fTableViewer != null) {
+            fTableViewer.dispose();
+        }
+    }
+
+    /**
+     * Set initial data into the viewer
+     */
+    private void setInitialData() {
+        if (fTableViewer != null) {
+            fTableViewer.setData(fTableViewer.getAnalysisModule());
+        }
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/Messages.java
new file mode 100644 (file)
index 0000000..52f8046
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ *   France Lapointe Nguyen - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author France Lapointe Nguyen
+ */
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.messages"; //$NON-NLS-1$
+
+    /**
+     * Name of the duration column
+     */
+    public static @Nullable String LatencyTableViewer_duration;
+
+    /**
+     * Name of the end time column
+     */
+    public static @Nullable String LatencyTableViewer_endTime;
+
+    /**
+     * Name of the start time column
+     */
+    public static @Nullable String LatencyTableViewer_startTime;
+
+    /**
+     * Title of the scatter graph
+     */
+    public static @Nullable String LatencyView_title;
+
+    /**
+     * Title of the x axis of the scatter graph
+     */
+    public static @Nullable String LatencyView_xAxis;
+
+    /**
+     * Title of the y axis of the scatter graph
+     */
+    public static @Nullable String LatencyView_yAxis;
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/messages.properties
new file mode 100644 (file)
index 0000000..df5ebac
--- /dev/null
@@ -0,0 +1,6 @@
+LatencyTableViewer_duration=Duration
+LatencyTableViewer_endTime=End Time
+LatencyTableViewer_startTime=Start Time
+LatencyView_title=Latency vs Time
+LatencyView_xAxis=Time
+LatencyView_yAxis=Latency
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/package-info.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/package-info.java
new file mode 100644 (file)
index 0000000..036cab9
--- /dev/null
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;
This page took 0.049043 seconds and 5 git commands to generate.