import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.AggregateEventIterator;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.AggregateEventIterator;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
com.google.common.collect,
org.swtchart
Export-Package: org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow,
- org.eclipse.tracecompass.analysis.os.linux.ui.views.resources,
org.eclipse.tracecompass.internal.analysis.os.linux.ui;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions;x-internal:=true,
org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests,org.eclipse.tracecompass.analysis.os.linux.ui.tests",
org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage;x-internal:=true,
org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.statistics;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests",
- org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests"
+ org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;
+ x-friends:="org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests,
+ org.eclipse.tracecompass.analysis.os.linux.ui.tests,
+ org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests,
+ org.eclipse.tracecompass.lttng2.kernel.ui"
<view
allowMultiple="false"
category="org.eclipse.linuxtools.lttng2.ui.views.category"
- class="org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesView"
+ class="org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesView"
icon="icons/eview16/resources_view.gif"
id="org.eclipse.tracecompass.analysis.os.linux.views.resources"
name="%resources.view.name"
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2016 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.ui.views.resources;
-
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
-
-/**
- * Aggregate TimeEvent iterator, this takes multiple streams of events and
- * merges them into one single time event stream
- *
- * @author Matthew Khouzam
- * @since 2.0
- */
-public class AggregateEventIterator implements Iterator<@NonNull ITimeEvent> {
-
- private final List<@NonNull CachingIterator> fIterators = new ArrayList<>();
-
- private final Comparator<ITimeEvent> fComparator;
-
- /**
- * Constructor
- *
- * @param contributors
- * the entries to aggregate
- * @param comparator
- * The comparator to sort time events
- */
- public AggregateEventIterator(@NonNull List<ITimeGraphEntry> contributors, Comparator<ITimeEvent> comparator) {
- this(contributors, Long.MIN_VALUE, Long.MAX_VALUE, 1, comparator);
- }
-
- /**
- * Constructor with a time range
- *
- * @param contributors
- * the entries to aggregate
- * @param startTime
- * start time in nanoseconds
- * @param endTime
- * stop time in nanoseconds
- * @param duration
- * duration of one pixel in nanoseconds
- * @param comparator
- * The comparator to sort time events
- */
- public AggregateEventIterator(@NonNull List<ITimeGraphEntry> contributors, long startTime, long endTime, long duration, Comparator<ITimeEvent> comparator) {
- fComparator = comparator;
- contributors.forEach(timeGraphEntry -> {
- final Iterator<@NonNull ITimeEvent> timeEventsIterator = timeGraphEntry.getTimeEventsIterator(startTime, endTime, duration);
- if (timeEventsIterator != null) {
- CachingIterator iterator = new CachingIterator(timeEventsIterator, comparator);
- if (iterator.hasNext()) {
- fIterators.add(iterator);
- }
- }
- });
- }
-
- @Override
- public boolean hasNext() {
- return !fIterators.isEmpty();
- }
-
- @Override
- public @NonNull ITimeEvent next() {
-
- final List<@NonNull CachingIterator> iterators = fIterators;
- if (iterators.isEmpty()) {
- throw new NoSuchElementException("Aggregate iterator is empty"); //$NON-NLS-1$
- }
-
- ITimeEvent winner = iterators.get(0).peek();
- long trimTime = winner.getTime() + winner.getDuration();
- for (int i = 1; i < iterators.size(); i++) {
- CachingIterator iterator = iterators.get(i);
- ITimeEvent candidate = iterator.peek();
- if (candidate.getTime() < winner.getTime()) {
- trimTime = Math.min(winner.getTime(), candidate.getTime() + candidate.getDuration());
- winner = candidate;
- } else if (candidate.getTime() == winner.getTime()) {
- trimTime = Math.min(trimTime, candidate.getTime() + candidate.getDuration());
- if (fComparator.compare(candidate, winner) < 0) {
- winner = candidate;
- }
- } else {
- trimTime = Math.min(trimTime, candidate.getTime());
- }
- }
-
- /* Trim the next event before the trim time, if necessary. */
- final ITimeEvent next = (trimTime < (winner.getDuration() + winner.getTime())) ? winner.splitBefore(trimTime) : winner;
-
- /* Trim all remaining events after the trim time, if necessary. */
- Iterator<CachingIterator> iteratorIterator = iterators.iterator();
- while (iteratorIterator.hasNext()) {
- CachingIterator iterator = iteratorIterator.next();
- iterator.trim(trimTime);
- /* Remove empty iterators from the list */
- if (!iterator.hasNext()) {
- iteratorIterator.remove();
- }
- }
-
- return checkNotNull(next);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2016 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.ui.views.resources;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
-
-/**
- * Internal entry of the aggregate kind, it is one without a state system value,
- * it uses other entries and aggregates their values.
- *
- * @author Matthew Khouzam
- */
-class AggregateResourcesEntry extends ResourcesEntry {
-
- private final @NonNull List<ITimeGraphEntry> fContributors = new ArrayList<>();
-
- private static final Comparator<ITimeEvent> COMPARATOR = new Comparator<ITimeEvent>() {
- @Override
- public int compare(ITimeEvent o1, ITimeEvent o2) {
- // largest value
- return Integer.compare(getValue(o2), getValue(o1));
- }
-
- private int getValue(ITimeEvent element) {
- return (element instanceof TimeEvent) ? ((TimeEvent) element).getValue() : Integer.MIN_VALUE;
- }
- };
-
- /**
- * AggregateResourcesEntry Constructor
- *
- * @param trace
- * the parent trace
- * @param startTime
- * the start time
- * @param endTime
- * the end time
- * @param type
- * the type
- * @param id
- * the id
- */
- public AggregateResourcesEntry(@NonNull ITmfTrace trace,
- long startTime, long endTime, Type type, int id) {
- super(ITmfStateSystem.INVALID_ATTRIBUTE, trace, startTime, endTime, type, id);
- }
-
- /**
- * Constructor
- *
- * @param trace
- * The trace on which we are working
- * @param name
- * The exec_name of this entry
- * @param startTime
- * The start time of this entry lifetime
- * @param endTime
- * The end time of this entry
- * @param type
- * The type of this entry
- * @param id
- * The id of this entry
- */
- public AggregateResourcesEntry(@NonNull ITmfTrace trace, String name, long startTime, long endTime, Type type, int id) {
- super(ITmfStateSystem.INVALID_ATTRIBUTE, trace, name, startTime, endTime, type, id);
- }
-
- @Override
- public void addEvent(ITimeEvent event) {
- }
-
- @Override
- public void addZoomedEvent(ITimeEvent event) {
- }
-
- @Override
- public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
- return new AggregateEventIterator(fContributors, COMPARATOR);
- }
-
- @Override
- public Iterator<@NonNull ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
- return new AggregateEventIterator(fContributors, startTime, stopTime, visibleDuration, COMPARATOR);
- }
-
- public void addContributor(ITimeGraphEntry entry) {
- fContributors.add(entry);
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2016 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.ui.views.resources;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
-
-/**
- * Caching iterator of time events with a couple extras.
- * <ul>
- * <li>peek() allows reading the head without removing it</li>
- * <li>trim() allows removing a bit of the first event</li>
- * </ul>
- *
- * @author Matthew Khouzam
- */
-class CachingIterator implements Iterator<@NonNull ITimeEvent>, Comparable<CachingIterator> {
- private ITimeEvent fEvent;
- private @NonNull Iterator<@NonNull ? extends ITimeEvent> fIterator;
- private final Comparator<ITimeEvent> fComparator;
-
- public CachingIterator(@NonNull Iterator<@NonNull ? extends ITimeEvent> iterator, Comparator<ITimeEvent> comparator) {
- fIterator = iterator;
- fComparator = comparator;
- fEvent = iterator.hasNext() ? iterator.next() : null;
- }
-
- @Override
- public ITimeEvent next() {
- ITimeEvent retVal = fEvent;
- fEvent = fIterator.hasNext() ? fIterator.next() : null;
- if (retVal == null) {
- throw new NoSuchElementException("Iterator is empty"); //$NON-NLS-1$
- }
- return retVal;
- }
-
- @Override
- public boolean hasNext() {
- return fEvent != null;
- }
-
- /**
- * Retrieves, but does not remove, the next element of this iterator, or
- * returns {@code null} if this iterator does not have a next.
- *
- * @return the next element of the iterator
- */
- public ITimeEvent peek() {
- return fEvent;
- }
-
- @Override
- public int compareTo(CachingIterator o) {
- final ITimeEvent myEvent = peek();
- final ITimeEvent otherEvent = o.peek();
- return fComparator.compare(myEvent, otherEvent);
- }
-
- /**
- * Trims the next element in the iterator to be after a cut-off time.
- *
- * @param time
- * the cut-off time
- * @return true if there was a trim
- */
- public boolean trim(long time) {
- if (time <= fEvent.getTime()) {
- return false;
- }
- if (time < fEvent.getTime() + fEvent.getDuration()) {
- fEvent = fEvent.splitAfter(time);
- return true;
- }
- fEvent = fIterator.hasNext() ? fIterator.next() : null;
- return true;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Patrick Tasse - Initial API and implementation
- * Geneviève Bastien - Move code to provide base classes for time graph view
- *******************************************************************************/
-
-package org.eclipse.tracecompass.analysis.os.linux.ui.views.resources;
-
-import java.util.Iterator;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.SoftIrqLabelProvider;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
-
-/**
- * An entry, or row, in the resource view
- *
- * @author Patrick Tasse
- */
-public class ResourcesEntry extends TimeGraphEntry implements Comparable<ITimeGraphEntry> {
-
- /** Type of resource */
- public static enum Type {
- /** Null resources (filler rows, etc.) */
- NULL,
- /** Entries for CPUs */
- CPU,
- /** Entries for IRQs */
- IRQ,
- /** Entries for Soft IRQ */
- SOFT_IRQ
- }
-
- private final int fId;
- private final @NonNull ITmfTrace fTrace;
- private final Type fType;
- private final int fQuark;
-
- /**
- * Constructor
- *
- * @param quark
- * The attribute quark matching the entry
- * @param trace
- * The trace on which we are working
- * @param name
- * The exec_name of this entry
- * @param startTime
- * The start time of this entry lifetime
- * @param endTime
- * The end time of this entry
- * @param type
- * The type of this entry
- * @param id
- * The id of this entry
- */
- public ResourcesEntry(int quark, @NonNull ITmfTrace trace, String name,
- long startTime, long endTime, Type type, int id) {
- super(name, startTime, endTime);
- fId = id;
- fTrace = trace;
- fType = type;
- fQuark = quark;
- }
-
- /**
- * Constructor
- *
- * @param trace
- * The trace on which we are working
- * @param name
- * The exec_name of this entry
- * @param startTime
- * The start time of this entry lifetime
- * @param endTime
- * The end time of this entry
- * @param id
- * The id of this entry
- */
- public ResourcesEntry(@NonNull ITmfTrace trace, String name,
- long startTime, long endTime, int id) {
- this(-1, trace, name, startTime, endTime, Type.NULL, id);
- }
-
- /**
- * Constructor
- *
- * @param quark
- * The attribute quark matching the entry
- * @param trace
- * The trace on which we are working
- * @param startTime
- * The start time of this entry lifetime
- * @param endTime
- * The end time of this entry
- * @param type
- * The type of this entry
- * @param id
- * The id of this entry
- */
- public ResourcesEntry(int quark, @NonNull ITmfTrace trace,
- long startTime, long endTime, Type type, int id) {
- this(quark, trace, computeEntryName(type, id), startTime, endTime, type, id);
- }
-
- private static String computeEntryName(Type type, int id) {
- if (Type.SOFT_IRQ.equals(type)) {
- return type.toString() + ' ' + id + ' ' + SoftIrqLabelProvider.getSoftIrq(id);
- }
- return type.toString() + ' ' + id;
- }
-
- /**
- * Get the entry's id
- *
- * @return the entry's id
- */
- public int getId() {
- return fId;
- }
-
- /**
- * Get the entry's trace
- *
- * @return the entry's trace
- */
- public @NonNull ITmfTrace getTrace() {
- return fTrace;
- }
-
- /**
- * Get the entry Type of this entry. Uses the inner Type enum.
- *
- * @return The entry type
- */
- public Type getType() {
- return fType;
- }
-
- /**
- * Retrieve the attribute quark that's represented by this entry.
- *
- * @return The integer quark The attribute quark matching the entry
- */
- public int getQuark() {
- return fQuark;
- }
-
- @Override
- public boolean hasTimeEvents() {
- if (fType == Type.NULL) {
- return false;
- }
- return true;
- }
-
- @Override
- public int compareTo(ITimeGraphEntry other) {
- if (!(other instanceof ResourcesEntry)) {
- /*
- * Should not happen, but if it does, put those entries at the end
- */
- return -1;
- }
- ResourcesEntry o = (ResourcesEntry) other;
-
- /*
- * Resources entry names should all be of type "ABC 123"
- *
- * We want to filter on the Type first (the "ABC" part), then on the ID
- * ("123") in numerical order (so we get 1,2,10 and not 1,10,2).
- */
- int ret = this.getType().compareTo(o.getType());
- if (ret != 0) {
- return ret;
- }
- return Integer.compare(this.getId(), o.getId());
- }
-
- @Override
- public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
- return super.getTimeEventsIterator();
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Patrick Tasse - Initial API and implementation
- * Geneviève Bastien - Move code to provide base classes for time graph view
- *******************************************************************************/
-
-package org.eclipse.tracecompass.analysis.os.linux.ui.views.resources;
-
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
-import org.eclipse.tracecompass.analysis.os.linux.core.kernel.StateValues;
-import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
-import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
-import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesEntry.Type;
-import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
-import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
-import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
-import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
-
-/**
- * Presentation provider for the Resource view, based on the generic TMF
- * presentation provider.
- *
- * @author Patrick Tasse
- */
-public class ResourcesPresentationProvider extends TimeGraphPresentationProvider {
-
- private long fLastThreadId = -1;
- private Color fColorWhite;
- private Color fColorGray;
- private Integer fAverageCharWidth;
-
- private enum State {
- IDLE (new RGB(200, 200, 200)),
- USERMODE (new RGB( 0, 200, 0)),
- SYSCALL (new RGB( 0, 0, 200)),
- IRQ (new RGB(200, 0, 100)),
- SOFT_IRQ (new RGB(200, 150, 100)),
- IRQ_ACTIVE (new RGB(200, 0, 100)),
- SOFT_IRQ_RAISED (new RGB(200, 200, 0)),
- SOFT_IRQ_ACTIVE (new RGB(200, 150, 100));
-
- public final RGB rgb;
-
- private State(RGB rgb) {
- this.rgb = rgb;
- }
- }
-
- /**
- * Default constructor
- */
- public ResourcesPresentationProvider() {
- super();
- }
-
- private static State[] getStateValues() {
- return State.values();
- }
-
- private static State getEventState(TimeEvent event) {
- if (event.hasValue()) {
- ResourcesEntry entry = (ResourcesEntry) event.getEntry();
- int value = event.getValue();
-
- if (entry.getType() == Type.CPU) {
- if (value == StateValues.CPU_STATUS_IDLE) {
- return State.IDLE;
- } else if (value == StateValues.CPU_STATUS_RUN_USERMODE) {
- return State.USERMODE;
- } else if (value == StateValues.CPU_STATUS_RUN_SYSCALL) {
- return State.SYSCALL;
- } else if (value == StateValues.CPU_STATUS_IRQ) {
- return State.IRQ;
- } else if (value == StateValues.CPU_STATUS_SOFTIRQ) {
- return State.SOFT_IRQ;
- }
- } else if (entry.getType() == Type.IRQ) {
- return State.IRQ_ACTIVE;
- } else if (entry.getType() == Type.SOFT_IRQ) {
- if (value == StateValues.CPU_STATUS_SOFT_IRQ_RAISED) {
- return State.SOFT_IRQ_RAISED;
- }
- return State.SOFT_IRQ_ACTIVE;
- }
- }
- return null;
- }
-
- @Override
- public int getStateTableIndex(ITimeEvent event) {
- State state = getEventState((TimeEvent) event);
- if (state != null) {
- return state.ordinal();
- }
- if (event instanceof NullTimeEvent) {
- return INVISIBLE;
- }
- return TRANSPARENT;
- }
-
- @Override
- public StateItem[] getStateTable() {
- State[] states = getStateValues();
- StateItem[] stateTable = new StateItem[states.length];
- for (int i = 0; i < stateTable.length; i++) {
- State state = states[i];
- stateTable[i] = new StateItem(state.rgb, state.toString());
- }
- return stateTable;
- }
-
- @Override
- public String getEventName(ITimeEvent event) {
- State state = getEventState((TimeEvent) event);
- if (state != null) {
- return state.toString();
- }
- if (event instanceof NullTimeEvent) {
- return null;
- }
- return Messages.ResourcesView_multipleStates;
- }
-
- @Override
- public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) {
-
- Map<String, String> retMap = new LinkedHashMap<>();
- if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
-
- TimeEvent tcEvent = (TimeEvent) event;
- ResourcesEntry entry = (ResourcesEntry) event.getEntry();
-
- if (tcEvent.hasValue()) {
- ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
- if (ss == null) {
- return retMap;
- }
- // Check for IRQ or Soft_IRQ type
- if (entry.getType().equals(Type.IRQ) || entry.getType().equals(Type.SOFT_IRQ)) {
-
- // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
- int cpu = tcEvent.getValue();
- if (cpu >= 0) {
- retMap.put(Messages.ResourcesView_attributeCpuName, String.valueOf(cpu));
- }
- }
-
- // Check for type CPU
- else if (entry.getType().equals(Type.CPU)) {
- int status = tcEvent.getValue();
-
- if (status == StateValues.CPU_STATUS_IRQ) {
- // In IRQ state get the IRQ that caused the interruption
- int cpu = entry.getId();
-
- try {
- List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
- List<Integer> irqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.IRQS, "*"); //$NON-NLS-1$
-
- for (int irqQuark : irqQuarks) {
- if (fullState.get(irqQuark).getStateValue().unboxInt() == cpu) {
- ITmfStateInterval value = ss.querySingleState(event.getTime(), irqQuark);
- if (!value.getStateValue().isNull()) {
- int irq = Integer.parseInt(ss.getAttributeName(irqQuark));
- retMap.put(Messages.ResourcesView_attributeIrqName, String.valueOf(irq));
- }
- break;
- }
- }
- } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
- Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
- }
- } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
- // In SOFT_IRQ state get the SOFT_IRQ that caused the interruption
- int cpu = entry.getId();
-
- try {
- List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
- List<Integer> softIrqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
-
- for (int softIrqQuark : softIrqQuarks) {
- if (fullState.get(softIrqQuark).getStateValue().unboxInt() == cpu) {
- ITmfStateInterval value = ss.querySingleState(event.getTime(), softIrqQuark);
- if (!value.getStateValue().isNull()) {
- int softIrq = Integer.parseInt(ss.getAttributeName(softIrqQuark));
- retMap.put(Messages.ResourcesView_attributeSoftIrqName, String.valueOf(softIrq));
- }
- break;
- }
- }
- } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
- Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
- }
- } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL) {
- // In running state get the current tid
-
- try {
- retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
- int cpuQuark = entry.getQuark();
- int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
- ITmfStateInterval interval = ss.querySingleState(hoverTime, currentThreadQuark);
- if (!interval.getStateValue().isNull()) {
- ITmfStateValue value = interval.getStateValue();
- int currentThreadId = value.unboxInt();
- retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
- int execNameQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
- interval = ss.querySingleState(hoverTime, execNameQuark);
- if (!interval.getStateValue().isNull()) {
- value = interval.getStateValue();
- retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
- }
- if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
- int syscallQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
- interval = ss.querySingleState(hoverTime, syscallQuark);
- if (!interval.getStateValue().isNull()) {
- value = interval.getStateValue();
- retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
- }
- }
- }
- } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
- Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
- }
- }
- }
- }
- }
-
- return retMap;
- }
-
- @Override
- public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
- if (fColorGray == null) {
- fColorGray = gc.getDevice().getSystemColor(SWT.COLOR_GRAY);
- }
- if (fColorWhite == null) {
- fColorWhite = gc.getDevice().getSystemColor(SWT.COLOR_WHITE);
- }
- if (fAverageCharWidth == null) {
- fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth();
- }
-
- ITmfTimeGraphDrawingHelper drawingHelper = getDrawingHelper();
- if (bounds.width <= fAverageCharWidth) {
- return;
- }
-
- if (!(event instanceof TimeEvent)) {
- return;
- }
- TimeEvent tcEvent = (TimeEvent) event;
- if (!tcEvent.hasValue()) {
- return;
- }
-
- ResourcesEntry entry = (ResourcesEntry) event.getEntry();
- if (!entry.getType().equals(Type.CPU)) {
- return;
- }
-
- int status = tcEvent.getValue();
- if (status != StateValues.CPU_STATUS_RUN_USERMODE && status != StateValues.CPU_STATUS_RUN_SYSCALL) {
- return;
- }
-
- ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
- if (ss == null) {
- return;
- }
- long time = event.getTime();
- try {
- while (time < event.getTime() + event.getDuration()) {
- int cpuQuark = entry.getQuark();
- int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
- ITmfStateInterval tidInterval = ss.querySingleState(time, currentThreadQuark);
- long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
- int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
- if (x >= bounds.x + bounds.width) {
- break;
- }
- if (!tidInterval.getStateValue().isNull()) {
- ITmfStateValue value = tidInterval.getStateValue();
- int currentThreadId = value.unboxInt();
- long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
- int xForEndTime = drawingHelper.getXForTime(endTime);
- if (xForEndTime > bounds.x) {
- int width = Math.min(xForEndTime, bounds.x + bounds.width) - x - 1;
- if (width > 0) {
- String attribute = null;
- int beginIndex = 0;
- if (status == StateValues.CPU_STATUS_RUN_USERMODE && currentThreadId != fLastThreadId) {
- attribute = Attributes.EXEC_NAME;
- } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
- attribute = Attributes.SYSTEM_CALL;
- /*
- * Remove the "sys_" or "syscall_entry_" or similar from what we
- * draw in the rectangle. This depends on the trace's event layout.
- */
- ITmfTrace trace = entry.getTrace();
- if (trace instanceof IKernelTrace) {
- IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout();
- beginIndex = layout.eventSyscallEntryPrefix().length();
- }
- }
- if (attribute != null) {
- int quark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), attribute);
- ITmfStateInterval interval = ss.querySingleState(time, quark);
- if (!interval.getStateValue().isNull()) {
- value = interval.getStateValue();
- gc.setForeground(fColorWhite);
- int drawn = Utils.drawText(gc, value.unboxStr().substring(beginIndex), x + 1, bounds.y, width, bounds.height, true, true);
- if (drawn > 0 && status == StateValues.CPU_STATUS_RUN_USERMODE) {
- fLastThreadId = currentThreadId;
- }
- }
- }
- if (xForEndTime < bounds.x + bounds.width) {
- gc.setForeground(fColorGray);
- gc.drawLine(xForEndTime, bounds.y + 1, xForEndTime, bounds.y + bounds.height - 2);
- }
- }
- }
- }
- // make sure next time is at least at the next pixel
- time = Math.max(tidInterval.getEndTime() + 1, drawingHelper.getTimeAtX(x + 1));
- }
- } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
- Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
- }
- }
-
- @Override
- public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) {
- fLastThreadId = -1;
- }
-}
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2012, 2016 Ericsson, École Polytechnique de Montréal
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Patrick Tasse - Initial API and implementation
- * Geneviève Bastien - Move code to provide base classes for time graph views
- *******************************************************************************/
-
-package org.eclipse.tracecompass.analysis.os.linux.ui.views.resources;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
-import org.eclipse.tracecompass.analysis.os.linux.core.signals.TmfCpuSelectedSignal;
-import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesEntry.Type;
-import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
-import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
-import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.FollowCpuAction;
-import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.UnfollowCpuAction;
-import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
-import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
-import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
-import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractStateSystemTimeGraphView;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
-
-/**
- * Main implementation for the LTTng 2.0 kernel Resource view
- *
- * @author Patrick Tasse
- */
-public class ResourcesView extends AbstractStateSystemTimeGraphView {
-
- /** View ID. */
- public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.resources"; //$NON-NLS-1$
-
- private static final String[] FILTER_COLUMN_NAMES = new String[] {
- Messages.ResourcesView_stateTypeName
- };
-
- private int fCurrentCpu = -1;
-
- // Timeout between updates in the build thread in ms
- private static final long BUILD_UPDATE_TIMEOUT = 500;
-
- // ------------------------------------------------------------------------
- // Constructors
- // ------------------------------------------------------------------------
-
- /**
- * Default constructor
- */
- public ResourcesView() {
- super(ID, new ResourcesPresentationProvider());
- setFilterColumns(FILTER_COLUMN_NAMES);
- setFilterLabelProvider(new ResourcesFilterLabelProvider());
- setEntryComparator(new ResourcesEntryComparator());
- setAutoExpandLevel(1);
- }
-
- private static class ResourcesEntryComparator implements Comparator<ITimeGraphEntry> {
- @Override
- public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
- ResourcesEntry entry1 = (ResourcesEntry) o1;
- ResourcesEntry entry2 = (ResourcesEntry) o2;
- if (entry1.getType() == Type.NULL && entry2.getType() == Type.NULL) {
- /* sort trace entries alphabetically */
- return entry1.getName().compareTo(entry2.getName());
- }
- /* sort resource entries by their defined order */
- return entry1.compareTo(entry2);
- }
- }
-
-
- /**
- * @since 2.0
- */
- @Override
- protected void fillTimeGraphEntryContextMenu(@NonNull IMenuManager menuManager) {
- ISelection selection = getSite().getSelectionProvider().getSelection();
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection sSel = (IStructuredSelection) selection;
- if (sSel.getFirstElement() instanceof ResourcesEntry) {
- ResourcesEntry resourcesEntry = (ResourcesEntry) sSel.getFirstElement();
- if (resourcesEntry.getType().equals(ResourcesEntry.Type.CPU)) {
- if (fCurrentCpu >= 0) {
- menuManager.add(new UnfollowCpuAction(ResourcesView.this, resourcesEntry.getId(), resourcesEntry.getTrace()));
- } else {
- menuManager.add(new FollowCpuAction(ResourcesView.this, resourcesEntry.getId(), resourcesEntry.getTrace()));
- }
- }
- }
- }
- }
-
- private static class ResourcesFilterLabelProvider extends TreeLabelProvider {
- @Override
- public String getColumnText(Object element, int columnIndex) {
- ResourcesEntry entry = (ResourcesEntry) element;
- if (columnIndex == 0) {
- return entry.getName();
- }
- return ""; //$NON-NLS-1$
- }
-
- }
-
- // ------------------------------------------------------------------------
- // Internal
- // ------------------------------------------------------------------------
-
- @Override
- protected String getNextText() {
- return Messages.ResourcesView_nextResourceActionNameText;
- }
-
- @Override
- protected String getNextTooltip() {
- return Messages.ResourcesView_nextResourceActionToolTipText;
- }
-
- @Override
- protected String getPrevText() {
- return Messages.ResourcesView_previousResourceActionNameText;
- }
-
- @Override
- protected String getPrevTooltip() {
- return Messages.ResourcesView_previousResourceActionToolTipText;
- }
-
- @Override
- protected void buildEntryList(ITmfTrace trace, ITmfTrace parentTrace, final IProgressMonitor monitor) {
- final ITmfStateSystem ssq = TmfStateSystemAnalysisModule.getStateSystem(trace, KernelAnalysisModule.ID);
- if (ssq == null) {
- return;
- }
-
- Map<Integer, ResourcesEntry> entryMap = new HashMap<>();
- TimeGraphEntry traceEntry = null;
-
- long startTime = ssq.getStartTime();
- long start = startTime;
- setStartTime(Math.min(getStartTime(), startTime));
- boolean complete = false;
- while (!complete) {
- if (monitor.isCanceled()) {
- return;
- }
- complete = ssq.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
- if (ssq.isCancelled()) {
- return;
- }
- long end = ssq.getCurrentEndTime();
- if (start == end && !complete) {
- // when complete execute one last time regardless of end time
- continue;
- }
- long endTime = end + 1;
- setEndTime(Math.max(getEndTime(), endTime));
-
- if (traceEntry == null) {
- traceEntry = new ResourcesEntry(trace, trace.getName(), startTime, endTime, 0);
- List<TimeGraphEntry> entryList = Collections.singletonList(traceEntry);
- addToEntryList(parentTrace, ssq, entryList);
- } else {
- traceEntry.updateEndTime(endTime);
- }
- List<Integer> cpuQuarks = ssq.getQuarks(Attributes.CPUS, "*"); //$NON-NLS-1$
- createCpuEntriesWithQuark(trace, ssq, entryMap, traceEntry, startTime, endTime, cpuQuarks);
- if (parentTrace.equals(getTrace())) {
- refresh();
- }
- final List<@NonNull TimeGraphEntry> traceEntryChildren = traceEntry.getChildren();
- final long resolution = Math.max(1, (endTime - ssq.getStartTime()) / getDisplayWidth());
- queryFullStates(ssq, ssq.getStartTime(), end, resolution, monitor, new IQueryHandler() {
- @Override
- public void handle(List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState) {
- for (TimeGraphEntry child : traceEntryChildren) {
- if (!populateEventsRecursively(fullStates, prevFullState, child).isOK()) {
- return;
- }
- }
- }
-
- private IStatus populateEventsRecursively(@NonNull List<List<ITmfStateInterval>> fullStates, @Nullable List<ITmfStateInterval> prevFullState, @NonNull TimeGraphEntry entry) {
- if (monitor.isCanceled()) {
- return Status.CANCEL_STATUS;
- }
- List<ITimeEvent> eventList = getEventList(entry, ssq, fullStates, prevFullState, monitor);
- if (eventList != null) {
- /* Start a new event list on first iteration, then append to it */
- if (prevFullState == null) {
- entry.setEventList(eventList);
- } else {
- for (ITimeEvent event : eventList) {
- entry.addEvent(event);
- }
- }
- }
- for (TimeGraphEntry child : entry.getChildren()) {
- IStatus status = populateEventsRecursively(fullStates, prevFullState, child);
- if (!status.isOK()) {
- return status;
- }
- }
- return Status.OK_STATUS;
- }
- });
-
- start = end;
- }
-
- }
-
- private static void createCpuEntriesWithQuark(@NonNull ITmfTrace trace, final ITmfStateSystem ssq, Map<Integer, ResourcesEntry> entryMap, TimeGraphEntry traceEntry, long startTime, long endTime, List<Integer> cpuQuarks) {
- for (Integer cpuQuark : cpuQuarks) {
- final @NonNull String cpuName = ssq.getAttributeName(cpuQuark);
- int cpu = Integer.parseInt(cpuName);
- ResourcesEntry cpuEntry = entryMap.get(cpuQuark);
- if (cpuEntry == null) {
- cpuEntry = new ResourcesEntry(cpuQuark, trace, startTime, endTime, Type.CPU, cpu);
- entryMap.put(cpuQuark, cpuEntry);
- traceEntry.addChild(cpuEntry);
- } else {
- cpuEntry.updateEndTime(endTime);
- }
- List<Integer> irqQuarks = ssq.getQuarks(Attributes.CPUS, cpuName, Attributes.IRQS, "*"); //$NON-NLS-1$
- createCpuInterruptEntryWithQuark(trace, ssq, entryMap, startTime, endTime, traceEntry, cpuEntry, irqQuarks, Type.IRQ);
- List<Integer> softIrqQuarks = ssq.getQuarks(Attributes.CPUS, cpuName, Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
- createCpuInterruptEntryWithQuark(trace, ssq, entryMap, startTime, endTime, traceEntry, cpuEntry, softIrqQuarks, Type.SOFT_IRQ);
- }
- }
-
- /**
- * Create and add execution contexts to a cpu entry. Also creates an
- * aggregate entry in the root trace entry. The execution context is
- * basically what the cpu is doing in its execution stack. It can be in an
- * IRQ, Soft IRQ. MCEs, NMIs, Userland and Kernel execution is not yet
- * supported.
- *
- * @param trace
- * the trace
- * @param ssq
- * the state system
- * @param entryMap
- * the entry map
- * @param startTime
- * the start time in nanoseconds
- * @param endTime
- * the end time in nanoseconds
- * @param traceEntry
- * the trace timegraph entry
- * @param cpuEntry
- * the cpu timegraph entry (the entry under the trace entry
- * @param childrenQuarks
- * the quarks to add to cpu entry
- * @param type
- * the type of entry being added
- */
- private static void createCpuInterruptEntryWithQuark(@NonNull ITmfTrace trace,
- final ITmfStateSystem ssq, Map<Integer, ResourcesEntry> entryMap,
- long startTime, long endTime,
- TimeGraphEntry traceEntry, ResourcesEntry cpuEntry,
- List<Integer> childrenQuarks, Type type) {
- for (Integer quark : childrenQuarks) {
- final @NonNull String resourceName = ssq.getAttributeName(quark);
- int resourceId = Integer.parseInt(resourceName);
- ResourcesEntry interruptEntry = entryMap.get(quark);
- if (interruptEntry == null) {
- interruptEntry = new ResourcesEntry(quark, trace, startTime, endTime, type, resourceId);
- entryMap.put(quark, interruptEntry);
- cpuEntry.addChild(interruptEntry);
- boolean found = false;
- for (ITimeGraphEntry rootElem : traceEntry.getChildren()) {
- if (rootElem instanceof AggregateResourcesEntry) {
- AggregateResourcesEntry aggregateInterruptEntry = (AggregateResourcesEntry) rootElem;
- if (aggregateInterruptEntry.getId() == resourceId && aggregateInterruptEntry.getType().equals(type)) {
- found = true;
- aggregateInterruptEntry.addContributor(interruptEntry);
- final AggregateResourcesEntry irqCpuEntry = new AggregateResourcesEntry(trace, cpuEntry.getName(), startTime, endTime, type, cpuEntry.getId());
- irqCpuEntry.addContributor(interruptEntry);
- aggregateInterruptEntry.addChild(irqCpuEntry);
- break;
- }
- }
- }
- if (!found) {
- AggregateResourcesEntry aggregateInterruptEntry = new AggregateResourcesEntry(trace, startTime, endTime, type, resourceId);
- aggregateInterruptEntry.addContributor(interruptEntry);
- final AggregateResourcesEntry irqCpuEntry = new AggregateResourcesEntry(trace, cpuEntry.getName(), startTime, endTime, type, cpuEntry.getId());
- irqCpuEntry.addContributor(interruptEntry);
- aggregateInterruptEntry.addChild(irqCpuEntry);
- traceEntry.addChild(aggregateInterruptEntry);
- }
- } else {
- interruptEntry.updateEndTime(endTime);
- }
- }
- }
-
- @Override
- protected @Nullable List<ITimeEvent> getEventList(@NonNull TimeGraphEntry entry, ITmfStateSystem ssq,
- @NonNull List<List<ITmfStateInterval>> fullStates, @Nullable List<ITmfStateInterval> prevFullState, @NonNull IProgressMonitor monitor) {
- ResourcesEntry resourcesEntry = (ResourcesEntry) entry;
- int quark = resourcesEntry.getQuark();
-
- if (resourcesEntry.getType().equals(Type.CPU)) {
- return createCpuEventsList(entry, ssq, fullStates, prevFullState, monitor, quark);
- } else if ((resourcesEntry.getType().equals(Type.IRQ) || resourcesEntry.getType().equals(Type.SOFT_IRQ)) && (quark >= 0)) {
- return createIrqEventsList(entry, fullStates, prevFullState, monitor, quark);
- }
-
- return null;
- }
-
- private static List<ITimeEvent> createCpuEventsList(ITimeGraphEntry entry, ITmfStateSystem ssq, List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState, IProgressMonitor monitor, int quark) {
- List<ITimeEvent> eventList;
- int statusQuark;
- try {
- statusQuark = ssq.getQuarkRelative(quark, Attributes.STATUS);
- } catch (AttributeNotFoundException e) {
- /*
- * The sub-attribute "status" is not available. May happen if the
- * trace does not have sched_switch events enabled.
- */
- return null;
- }
- boolean isZoomThread = Thread.currentThread() instanceof ZoomThread;
- eventList = new ArrayList<>(fullStates.size());
- ITmfStateInterval lastInterval = prevFullState == null || statusQuark >= prevFullState.size() ? null : prevFullState.get(statusQuark);
- long lastStartTime = lastInterval == null ? -1 : lastInterval.getStartTime();
- long lastEndTime = lastInterval == null ? -1 : lastInterval.getEndTime() + 1;
- for (List<ITmfStateInterval> fullState : fullStates) {
- if (monitor.isCanceled()) {
- return null;
- }
- if (statusQuark >= fullState.size()) {
- /* No information on this CPU (yet?), skip it for now */
- continue;
- }
- ITmfStateInterval statusInterval = fullState.get(statusQuark);
- int status = statusInterval.getStateValue().unboxInt();
- long time = statusInterval.getStartTime();
- long duration = statusInterval.getEndTime() - time + 1;
- if (time == lastStartTime) {
- continue;
- }
- if (!statusInterval.getStateValue().isNull()) {
- if (lastEndTime != time && lastEndTime != -1) {
- eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
- }
- eventList.add(new TimeEvent(entry, time, duration, status));
- } else if (isZoomThread) {
- eventList.add(new NullTimeEvent(entry, time, duration));
- }
- lastStartTime = time;
- lastEndTime = time + duration;
- }
- return eventList;
- }
-
- private static List<ITimeEvent> createIrqEventsList(ITimeGraphEntry entry, List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState, IProgressMonitor monitor, int quark) {
- List<ITimeEvent> eventList;
- boolean isZoomThread = Thread.currentThread() instanceof ZoomThread;
- eventList = new ArrayList<>(fullStates.size());
- ITmfStateInterval lastInterval = prevFullState == null || quark >= prevFullState.size() ? null : prevFullState.get(quark);
- long lastStartTime = lastInterval == null ? -1 : lastInterval.getStartTime();
- long lastEndTime = lastInterval == null ? -1 : lastInterval.getEndTime() + 1;
- boolean lastIsNull = lastInterval == null ? false : lastInterval.getStateValue().isNull();
- for (List<ITmfStateInterval> fullState : fullStates) {
- if (monitor.isCanceled()) {
- return null;
- }
- if (quark >= fullState.size()) {
- /* No information on this IRQ (yet?), skip it for now */
- continue;
- }
- ITmfStateInterval irqInterval = fullState.get(quark);
- long time = irqInterval.getStartTime();
- long duration = irqInterval.getEndTime() - time + 1;
- if (time == lastStartTime) {
- continue;
- }
- if (!irqInterval.getStateValue().isNull()) {
- int cpu = irqInterval.getStateValue().unboxInt();
- eventList.add(new TimeEvent(entry, time, duration, cpu));
- lastIsNull = false;
- } else {
- if (lastEndTime != time && lastIsNull) {
- /*
- * This is a special case where we want to show IRQ_ACTIVE
- * state but we don't know the CPU (it is between two null
- * samples)
- */
- eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1));
- }
- if (isZoomThread) {
- eventList.add(new NullTimeEvent(entry, time, duration));
- }
- lastIsNull = true;
- }
- lastStartTime = time;
- lastEndTime = time + duration;
- }
- return eventList;
- }
-
- /**
- * Signal handler for a cpu selected signal.
- *
- * @param signal
- * the cpu selected signal
- * @since 2.0
- */
- @TmfSignalHandler
- public void listenToCpu(TmfCpuSelectedSignal signal) {
- if (signal.getCore() >= 0) {
- fCurrentCpu = signal.getCore();
- } else {
- fCurrentCpu = -1;
- }
- }
-
-}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 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.internal.analysis.os.linux.ui.views.resources;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+
+/**
+ * Aggregate TimeEvent iterator, this takes multiple streams of events and
+ * merges them into one single time event stream
+ *
+ * @author Matthew Khouzam
+ * @since 2.0
+ */
+public class AggregateEventIterator implements Iterator<@NonNull ITimeEvent> {
+
+ private final List<org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.CachingIterator> fIterators = new ArrayList<>();
+
+ private final Comparator<ITimeEvent> fComparator;
+
+ /**
+ * Constructor
+ *
+ * @param contributors
+ * the entries to aggregate
+ * @param comparator
+ * The comparator to sort time events
+ */
+ public AggregateEventIterator(@NonNull List<ITimeGraphEntry> contributors, Comparator<ITimeEvent> comparator) {
+ this(contributors, Long.MIN_VALUE, Long.MAX_VALUE, 1, comparator);
+ }
+
+ /**
+ * Constructor with a time range
+ *
+ * @param contributors
+ * the entries to aggregate
+ * @param startTime
+ * start time in nanoseconds
+ * @param endTime
+ * stop time in nanoseconds
+ * @param duration
+ * duration of one pixel in nanoseconds
+ * @param comparator
+ * The comparator to sort time events
+ */
+ public AggregateEventIterator(@NonNull List<ITimeGraphEntry> contributors, long startTime, long endTime, long duration, Comparator<ITimeEvent> comparator) {
+ fComparator = comparator;
+ contributors.forEach(timeGraphEntry -> {
+ final Iterator<@NonNull ITimeEvent> timeEventsIterator = timeGraphEntry.getTimeEventsIterator(startTime, endTime, duration);
+ if (timeEventsIterator != null) {
+ CachingIterator iterator = new CachingIterator(timeEventsIterator, comparator);
+ if (iterator.hasNext()) {
+ fIterators.add(iterator);
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !fIterators.isEmpty();
+ }
+
+ @Override
+ public @NonNull ITimeEvent next() {
+
+ final List<org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.CachingIterator> iterators = fIterators;
+ if (iterators.isEmpty()) {
+ throw new NoSuchElementException("Aggregate iterator is empty"); //$NON-NLS-1$
+ }
+
+ ITimeEvent winner = iterators.get(0).peek();
+ long trimTime = winner.getTime() + winner.getDuration();
+ for (int i = 1; i < iterators.size(); i++) {
+ CachingIterator iterator = iterators.get(i);
+ ITimeEvent candidate = iterator.peek();
+ if (candidate.getTime() < winner.getTime()) {
+ trimTime = Math.min(winner.getTime(), candidate.getTime() + candidate.getDuration());
+ winner = candidate;
+ } else if (candidate.getTime() == winner.getTime()) {
+ trimTime = Math.min(trimTime, candidate.getTime() + candidate.getDuration());
+ if (fComparator.compare(candidate, winner) < 0) {
+ winner = candidate;
+ }
+ } else {
+ trimTime = Math.min(trimTime, candidate.getTime());
+ }
+ }
+
+ /* Trim the next event before the trim time, if necessary. */
+ final ITimeEvent next = (trimTime < (winner.getDuration() + winner.getTime())) ? winner.splitBefore(trimTime) : winner;
+
+ /* Trim all remaining events after the trim time, if necessary. */
+ Iterator<CachingIterator> iteratorIterator = iterators.iterator();
+ while (iteratorIterator.hasNext()) {
+ CachingIterator iterator = iteratorIterator.next();
+ iterator.trim(trimTime);
+ /* Remove empty iterators from the list */
+ if (!iterator.hasNext()) {
+ iteratorIterator.remove();
+ }
+ }
+
+ return checkNotNull(next);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 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.internal.analysis.os.linux.ui.views.resources;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
+
+/**
+ * Internal entry of the aggregate kind, it is one without a state system value,
+ * it uses other entries and aggregates their values.
+ *
+ * @author Matthew Khouzam
+ */
+class AggregateResourcesEntry extends ResourcesEntry {
+
+ private final @NonNull List<ITimeGraphEntry> fContributors = new ArrayList<>();
+
+ private static final Comparator<ITimeEvent> COMPARATOR = new Comparator<ITimeEvent>() {
+ @Override
+ public int compare(ITimeEvent o1, ITimeEvent o2) {
+ // largest value
+ return Integer.compare(getValue(o2), getValue(o1));
+ }
+
+ private int getValue(ITimeEvent element) {
+ return (element instanceof TimeEvent) ? ((TimeEvent) element).getValue() : Integer.MIN_VALUE;
+ }
+ };
+
+ /**
+ * AggregateResourcesEntry Constructor
+ *
+ * @param trace
+ * the parent trace
+ * @param startTime
+ * the start time
+ * @param endTime
+ * the end time
+ * @param type
+ * the type
+ * @param id
+ * the id
+ */
+ public AggregateResourcesEntry(@NonNull ITmfTrace trace,
+ long startTime, long endTime, Type type, int id) {
+ super(ITmfStateSystem.INVALID_ATTRIBUTE, trace, startTime, endTime, type, id);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param trace
+ * The trace on which we are working
+ * @param name
+ * The exec_name of this entry
+ * @param startTime
+ * The start time of this entry lifetime
+ * @param endTime
+ * The end time of this entry
+ * @param type
+ * The type of this entry
+ * @param id
+ * The id of this entry
+ */
+ public AggregateResourcesEntry(@NonNull ITmfTrace trace, String name, long startTime, long endTime, Type type, int id) {
+ super(ITmfStateSystem.INVALID_ATTRIBUTE, trace, name, startTime, endTime, type, id);
+ }
+
+ @Override
+ public void addEvent(ITimeEvent event) {
+ }
+
+ @Override
+ public void addZoomedEvent(ITimeEvent event) {
+ }
+
+ @Override
+ public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
+ return new AggregateEventIterator(fContributors, COMPARATOR);
+ }
+
+ @Override
+ public Iterator<@NonNull ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
+ return new AggregateEventIterator(fContributors, startTime, stopTime, visibleDuration, COMPARATOR);
+ }
+
+ public void addContributor(ITimeGraphEntry entry) {
+ fContributors.add(entry);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 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.internal.analysis.os.linux.ui.views.resources;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
+
+/**
+ * Caching iterator of time events with a couple extras.
+ * <ul>
+ * <li>peek() allows reading the head without removing it</li>
+ * <li>trim() allows removing a bit of the first event</li>
+ * </ul>
+ *
+ * @author Matthew Khouzam
+ */
+class CachingIterator implements Iterator<@NonNull ITimeEvent>, Comparable<CachingIterator> {
+ private ITimeEvent fEvent;
+ private @NonNull Iterator<@NonNull ? extends ITimeEvent> fIterator;
+ private final Comparator<ITimeEvent> fComparator;
+
+ public CachingIterator(@NonNull Iterator<@NonNull ? extends ITimeEvent> iterator, Comparator<ITimeEvent> comparator) {
+ fIterator = iterator;
+ fComparator = comparator;
+ fEvent = iterator.hasNext() ? iterator.next() : null;
+ }
+
+ @Override
+ public ITimeEvent next() {
+ ITimeEvent retVal = fEvent;
+ fEvent = fIterator.hasNext() ? fIterator.next() : null;
+ if (retVal == null) {
+ throw new NoSuchElementException("Iterator is empty"); //$NON-NLS-1$
+ }
+ return retVal;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return fEvent != null;
+ }
+
+ /**
+ * Retrieves, but does not remove, the next element of this iterator, or
+ * returns {@code null} if this iterator does not have a next.
+ *
+ * @return the next element of the iterator
+ */
+ public ITimeEvent peek() {
+ return fEvent;
+ }
+
+ @Override
+ public int compareTo(CachingIterator o) {
+ final ITimeEvent myEvent = peek();
+ final ITimeEvent otherEvent = o.peek();
+ return fComparator.compare(myEvent, otherEvent);
+ }
+
+ /**
+ * Trims the next element in the iterator to be after a cut-off time.
+ *
+ * @param time
+ * the cut-off time
+ * @return true if there was a trim
+ */
+ public boolean trim(long time) {
+ if (time <= fEvent.getTime()) {
+ return false;
+ }
+ if (time < fEvent.getTime() + fEvent.getDuration()) {
+ fEvent = fEvent.splitAfter(time);
+ return true;
+ }
+ fEvent = fIterator.hasNext() ? fIterator.next() : null;
+ return true;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ * Geneviève Bastien - Move code to provide base classes for time graph view
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;
+
+import java.util.Iterator;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
+
+/**
+ * An entry, or row, in the resource view
+ *
+ * @author Patrick Tasse
+ */
+public class ResourcesEntry extends TimeGraphEntry implements Comparable<ITimeGraphEntry> {
+
+ /** Type of resource */
+ public static enum Type {
+ /** Null resources (filler rows, etc.) */
+ NULL,
+ /** Entries for CPUs */
+ CPU,
+ /** Entries for IRQs */
+ IRQ,
+ /** Entries for Soft IRQ */
+ SOFT_IRQ
+ }
+
+ private final int fId;
+ private final @NonNull ITmfTrace fTrace;
+ private final Type fType;
+ private final int fQuark;
+
+ /**
+ * Constructor
+ *
+ * @param quark
+ * The attribute quark matching the entry
+ * @param trace
+ * The trace on which we are working
+ * @param name
+ * The exec_name of this entry
+ * @param startTime
+ * The start time of this entry lifetime
+ * @param endTime
+ * The end time of this entry
+ * @param type
+ * The type of this entry
+ * @param id
+ * The id of this entry
+ */
+ public ResourcesEntry(int quark, @NonNull ITmfTrace trace, String name,
+ long startTime, long endTime, Type type, int id) {
+ super(name, startTime, endTime);
+ fId = id;
+ fTrace = trace;
+ fType = type;
+ fQuark = quark;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param trace
+ * The trace on which we are working
+ * @param name
+ * The exec_name of this entry
+ * @param startTime
+ * The start time of this entry lifetime
+ * @param endTime
+ * The end time of this entry
+ * @param id
+ * The id of this entry
+ */
+ public ResourcesEntry(@NonNull ITmfTrace trace, String name,
+ long startTime, long endTime, int id) {
+ this(-1, trace, name, startTime, endTime, Type.NULL, id);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param quark
+ * The attribute quark matching the entry
+ * @param trace
+ * The trace on which we are working
+ * @param startTime
+ * The start time of this entry lifetime
+ * @param endTime
+ * The end time of this entry
+ * @param type
+ * The type of this entry
+ * @param id
+ * The id of this entry
+ */
+ public ResourcesEntry(int quark, @NonNull ITmfTrace trace,
+ long startTime, long endTime, Type type, int id) {
+ this(quark, trace, computeEntryName(type, id), startTime, endTime, type, id);
+ }
+
+ private static String computeEntryName(Type type, int id) {
+ if (Type.SOFT_IRQ.equals(type)) {
+ return type.toString() + ' ' + id + ' ' + SoftIrqLabelProvider.getSoftIrq(id);
+ }
+ return type.toString() + ' ' + id;
+ }
+
+ /**
+ * Get the entry's id
+ *
+ * @return the entry's id
+ */
+ public int getId() {
+ return fId;
+ }
+
+ /**
+ * Get the entry's trace
+ *
+ * @return the entry's trace
+ */
+ public @NonNull ITmfTrace getTrace() {
+ return fTrace;
+ }
+
+ /**
+ * Get the entry Type of this entry. Uses the inner Type enum.
+ *
+ * @return The entry type
+ */
+ public Type getType() {
+ return fType;
+ }
+
+ /**
+ * Retrieve the attribute quark that's represented by this entry.
+ *
+ * @return The integer quark The attribute quark matching the entry
+ */
+ public int getQuark() {
+ return fQuark;
+ }
+
+ @Override
+ public boolean hasTimeEvents() {
+ if (fType == Type.NULL) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int compareTo(ITimeGraphEntry other) {
+ if (!(other instanceof ResourcesEntry)) {
+ /*
+ * Should not happen, but if it does, put those entries at the end
+ */
+ return -1;
+ }
+ ResourcesEntry o = (ResourcesEntry) other;
+
+ /*
+ * Resources entry names should all be of type "ABC 123"
+ *
+ * We want to filter on the Type first (the "ABC" part), then on the ID
+ * ("123") in numerical order (so we get 1,2,10 and not 1,10,2).
+ */
+ int ret = this.getType().compareTo(o.getType());
+ if (ret != 0) {
+ return ret;
+ }
+ return Integer.compare(this.getId(), o.getId());
+ }
+
+ @Override
+ public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
+ return super.getTimeEventsIterator();
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ * Geneviève Bastien - Move code to provide base classes for time graph view
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.StateValues;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
+import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesEntry.Type;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
+
+/**
+ * Presentation provider for the Resource view, based on the generic TMF
+ * presentation provider.
+ *
+ * @author Patrick Tasse
+ */
+public class ResourcesPresentationProvider extends TimeGraphPresentationProvider {
+
+ private long fLastThreadId = -1;
+ private Color fColorWhite;
+ private Color fColorGray;
+ private Integer fAverageCharWidth;
+
+ private enum State {
+ IDLE (new RGB(200, 200, 200)),
+ USERMODE (new RGB( 0, 200, 0)),
+ SYSCALL (new RGB( 0, 0, 200)),
+ IRQ (new RGB(200, 0, 100)),
+ SOFT_IRQ (new RGB(200, 150, 100)),
+ IRQ_ACTIVE (new RGB(200, 0, 100)),
+ SOFT_IRQ_RAISED (new RGB(200, 200, 0)),
+ SOFT_IRQ_ACTIVE (new RGB(200, 150, 100));
+
+ public final RGB rgb;
+
+ private State(RGB rgb) {
+ this.rgb = rgb;
+ }
+ }
+
+ /**
+ * Default constructor
+ */
+ public ResourcesPresentationProvider() {
+ super();
+ }
+
+ private static State[] getStateValues() {
+ return State.values();
+ }
+
+ private static State getEventState(TimeEvent event) {
+ if (event.hasValue()) {
+ ResourcesEntry entry = (ResourcesEntry) event.getEntry();
+ int value = event.getValue();
+
+ if (entry.getType() == Type.CPU) {
+ if (value == StateValues.CPU_STATUS_IDLE) {
+ return State.IDLE;
+ } else if (value == StateValues.CPU_STATUS_RUN_USERMODE) {
+ return State.USERMODE;
+ } else if (value == StateValues.CPU_STATUS_RUN_SYSCALL) {
+ return State.SYSCALL;
+ } else if (value == StateValues.CPU_STATUS_IRQ) {
+ return State.IRQ;
+ } else if (value == StateValues.CPU_STATUS_SOFTIRQ) {
+ return State.SOFT_IRQ;
+ }
+ } else if (entry.getType() == Type.IRQ) {
+ return State.IRQ_ACTIVE;
+ } else if (entry.getType() == Type.SOFT_IRQ) {
+ if (value == StateValues.CPU_STATUS_SOFT_IRQ_RAISED) {
+ return State.SOFT_IRQ_RAISED;
+ }
+ return State.SOFT_IRQ_ACTIVE;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public int getStateTableIndex(ITimeEvent event) {
+ State state = getEventState((TimeEvent) event);
+ if (state != null) {
+ return state.ordinal();
+ }
+ if (event instanceof NullTimeEvent) {
+ return INVISIBLE;
+ }
+ return TRANSPARENT;
+ }
+
+ @Override
+ public StateItem[] getStateTable() {
+ State[] states = getStateValues();
+ StateItem[] stateTable = new StateItem[states.length];
+ for (int i = 0; i < stateTable.length; i++) {
+ State state = states[i];
+ stateTable[i] = new StateItem(state.rgb, state.toString());
+ }
+ return stateTable;
+ }
+
+ @Override
+ public String getEventName(ITimeEvent event) {
+ State state = getEventState((TimeEvent) event);
+ if (state != null) {
+ return state.toString();
+ }
+ if (event instanceof NullTimeEvent) {
+ return null;
+ }
+ return Messages.ResourcesView_multipleStates;
+ }
+
+ @Override
+ public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) {
+
+ Map<String, String> retMap = new LinkedHashMap<>();
+ if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
+
+ TimeEvent tcEvent = (TimeEvent) event;
+ ResourcesEntry entry = (ResourcesEntry) event.getEntry();
+
+ if (tcEvent.hasValue()) {
+ ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
+ if (ss == null) {
+ return retMap;
+ }
+ // Check for IRQ or Soft_IRQ type
+ if (entry.getType().equals(Type.IRQ) || entry.getType().equals(Type.SOFT_IRQ)) {
+
+ // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
+ int cpu = tcEvent.getValue();
+ if (cpu >= 0) {
+ retMap.put(Messages.ResourcesView_attributeCpuName, String.valueOf(cpu));
+ }
+ }
+
+ // Check for type CPU
+ else if (entry.getType().equals(Type.CPU)) {
+ int status = tcEvent.getValue();
+
+ if (status == StateValues.CPU_STATUS_IRQ) {
+ // In IRQ state get the IRQ that caused the interruption
+ int cpu = entry.getId();
+
+ try {
+ List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
+ List<Integer> irqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.IRQS, "*"); //$NON-NLS-1$
+
+ for (int irqQuark : irqQuarks) {
+ if (fullState.get(irqQuark).getStateValue().unboxInt() == cpu) {
+ ITmfStateInterval value = ss.querySingleState(event.getTime(), irqQuark);
+ if (!value.getStateValue().isNull()) {
+ int irq = Integer.parseInt(ss.getAttributeName(irqQuark));
+ retMap.put(Messages.ResourcesView_attributeIrqName, String.valueOf(irq));
+ }
+ break;
+ }
+ }
+ } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
+ Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
+ }
+ } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
+ // In SOFT_IRQ state get the SOFT_IRQ that caused the interruption
+ int cpu = entry.getId();
+
+ try {
+ List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
+ List<Integer> softIrqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
+
+ for (int softIrqQuark : softIrqQuarks) {
+ if (fullState.get(softIrqQuark).getStateValue().unboxInt() == cpu) {
+ ITmfStateInterval value = ss.querySingleState(event.getTime(), softIrqQuark);
+ if (!value.getStateValue().isNull()) {
+ int softIrq = Integer.parseInt(ss.getAttributeName(softIrqQuark));
+ retMap.put(Messages.ResourcesView_attributeSoftIrqName, String.valueOf(softIrq));
+ }
+ break;
+ }
+ }
+ } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
+ Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
+ }
+ } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL) {
+ // In running state get the current tid
+
+ try {
+ retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
+ int cpuQuark = entry.getQuark();
+ int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
+ ITmfStateInterval interval = ss.querySingleState(hoverTime, currentThreadQuark);
+ if (!interval.getStateValue().isNull()) {
+ ITmfStateValue value = interval.getStateValue();
+ int currentThreadId = value.unboxInt();
+ retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
+ int execNameQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
+ interval = ss.querySingleState(hoverTime, execNameQuark);
+ if (!interval.getStateValue().isNull()) {
+ value = interval.getStateValue();
+ retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
+ }
+ if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
+ int syscallQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
+ interval = ss.querySingleState(hoverTime, syscallQuark);
+ if (!interval.getStateValue().isNull()) {
+ value = interval.getStateValue();
+ retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
+ }
+ }
+ }
+ } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
+ Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
+ }
+ }
+ }
+ }
+ }
+
+ return retMap;
+ }
+
+ @Override
+ public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
+ if (fColorGray == null) {
+ fColorGray = gc.getDevice().getSystemColor(SWT.COLOR_GRAY);
+ }
+ if (fColorWhite == null) {
+ fColorWhite = gc.getDevice().getSystemColor(SWT.COLOR_WHITE);
+ }
+ if (fAverageCharWidth == null) {
+ fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth();
+ }
+
+ ITmfTimeGraphDrawingHelper drawingHelper = getDrawingHelper();
+ if (bounds.width <= fAverageCharWidth) {
+ return;
+ }
+
+ if (!(event instanceof TimeEvent)) {
+ return;
+ }
+ TimeEvent tcEvent = (TimeEvent) event;
+ if (!tcEvent.hasValue()) {
+ return;
+ }
+
+ ResourcesEntry entry = (ResourcesEntry) event.getEntry();
+ if (!entry.getType().equals(Type.CPU)) {
+ return;
+ }
+
+ int status = tcEvent.getValue();
+ if (status != StateValues.CPU_STATUS_RUN_USERMODE && status != StateValues.CPU_STATUS_RUN_SYSCALL) {
+ return;
+ }
+
+ ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
+ if (ss == null) {
+ return;
+ }
+ long time = event.getTime();
+ try {
+ while (time < event.getTime() + event.getDuration()) {
+ int cpuQuark = entry.getQuark();
+ int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
+ ITmfStateInterval tidInterval = ss.querySingleState(time, currentThreadQuark);
+ long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
+ int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
+ if (x >= bounds.x + bounds.width) {
+ break;
+ }
+ if (!tidInterval.getStateValue().isNull()) {
+ ITmfStateValue value = tidInterval.getStateValue();
+ int currentThreadId = value.unboxInt();
+ long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
+ int xForEndTime = drawingHelper.getXForTime(endTime);
+ if (xForEndTime > bounds.x) {
+ int width = Math.min(xForEndTime, bounds.x + bounds.width) - x - 1;
+ if (width > 0) {
+ String attribute = null;
+ int beginIndex = 0;
+ if (status == StateValues.CPU_STATUS_RUN_USERMODE && currentThreadId != fLastThreadId) {
+ attribute = Attributes.EXEC_NAME;
+ } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
+ attribute = Attributes.SYSTEM_CALL;
+ /*
+ * Remove the "sys_" or "syscall_entry_" or similar from what we
+ * draw in the rectangle. This depends on the trace's event layout.
+ */
+ ITmfTrace trace = entry.getTrace();
+ if (trace instanceof IKernelTrace) {
+ IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout();
+ beginIndex = layout.eventSyscallEntryPrefix().length();
+ }
+ }
+ if (attribute != null) {
+ int quark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), attribute);
+ ITmfStateInterval interval = ss.querySingleState(time, quark);
+ if (!interval.getStateValue().isNull()) {
+ value = interval.getStateValue();
+ gc.setForeground(fColorWhite);
+ int drawn = Utils.drawText(gc, value.unboxStr().substring(beginIndex), x + 1, bounds.y, width, bounds.height, true, true);
+ if (drawn > 0 && status == StateValues.CPU_STATUS_RUN_USERMODE) {
+ fLastThreadId = currentThreadId;
+ }
+ }
+ }
+ if (xForEndTime < bounds.x + bounds.width) {
+ gc.setForeground(fColorGray);
+ gc.drawLine(xForEndTime, bounds.y + 1, xForEndTime, bounds.y + bounds.height - 2);
+ }
+ }
+ }
+ }
+ // make sure next time is at least at the next pixel
+ time = Math.max(tidInterval.getEndTime() + 1, drawingHelper.getTimeAtX(x + 1));
+ }
+ } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
+ Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
+ }
+ }
+
+ @Override
+ public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) {
+ fLastThreadId = -1;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 Ericsson, École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ * Geneviève Bastien - Move code to provide base classes for time graph views
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.analysis.os.linux.core.signals.TmfCpuSelectedSignal;
+import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.FollowCpuAction;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.UnfollowCpuAction;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesEntry.Type;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractStateSystemTimeGraphView;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
+
+/**
+ * Main implementation for the LTTng 2.0 kernel Resource view
+ *
+ * @author Patrick Tasse
+ */
+public class ResourcesView extends AbstractStateSystemTimeGraphView {
+
+ /** View ID. */
+ public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.resources"; //$NON-NLS-1$
+
+ private static final String[] FILTER_COLUMN_NAMES = new String[] {
+ Messages.ResourcesView_stateTypeName
+ };
+
+ private int fCurrentCpu = -1;
+
+ // Timeout between updates in the build thread in ms
+ private static final long BUILD_UPDATE_TIMEOUT = 500;
+
+ // ------------------------------------------------------------------------
+ // Constructors
+ // ------------------------------------------------------------------------
+
+ /**
+ * Default constructor
+ */
+ public ResourcesView() {
+ super(ID, new ResourcesPresentationProvider());
+ setFilterColumns(FILTER_COLUMN_NAMES);
+ setFilterLabelProvider(new ResourcesFilterLabelProvider());
+ setEntryComparator(new ResourcesEntryComparator());
+ setAutoExpandLevel(1);
+ }
+
+ private static class ResourcesEntryComparator implements Comparator<ITimeGraphEntry> {
+ @Override
+ public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
+ ResourcesEntry entry1 = (ResourcesEntry) o1;
+ ResourcesEntry entry2 = (ResourcesEntry) o2;
+ if (entry1.getType() == Type.NULL && entry2.getType() == Type.NULL) {
+ /* sort trace entries alphabetically */
+ return entry1.getName().compareTo(entry2.getName());
+ }
+ /* sort resource entries by their defined order */
+ return entry1.compareTo(entry2);
+ }
+ }
+
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ protected void fillTimeGraphEntryContextMenu(@NonNull IMenuManager menuManager) {
+ ISelection selection = getSite().getSelectionProvider().getSelection();
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection sSel = (IStructuredSelection) selection;
+ if (sSel.getFirstElement() instanceof ResourcesEntry) {
+ ResourcesEntry resourcesEntry = (ResourcesEntry) sSel.getFirstElement();
+ if (resourcesEntry.getType().equals(ResourcesEntry.Type.CPU)) {
+ if (fCurrentCpu >= 0) {
+ menuManager.add(new UnfollowCpuAction(ResourcesView.this, resourcesEntry.getId(), resourcesEntry.getTrace()));
+ } else {
+ menuManager.add(new FollowCpuAction(ResourcesView.this, resourcesEntry.getId(), resourcesEntry.getTrace()));
+ }
+ }
+ }
+ }
+ }
+
+ private static class ResourcesFilterLabelProvider extends TreeLabelProvider {
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ ResourcesEntry entry = (ResourcesEntry) element;
+ if (columnIndex == 0) {
+ return entry.getName();
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ }
+
+ // ------------------------------------------------------------------------
+ // Internal
+ // ------------------------------------------------------------------------
+
+ @Override
+ protected String getNextText() {
+ return Messages.ResourcesView_nextResourceActionNameText;
+ }
+
+ @Override
+ protected String getNextTooltip() {
+ return Messages.ResourcesView_nextResourceActionToolTipText;
+ }
+
+ @Override
+ protected String getPrevText() {
+ return Messages.ResourcesView_previousResourceActionNameText;
+ }
+
+ @Override
+ protected String getPrevTooltip() {
+ return Messages.ResourcesView_previousResourceActionToolTipText;
+ }
+
+ @Override
+ protected void buildEntryList(ITmfTrace trace, ITmfTrace parentTrace, final IProgressMonitor monitor) {
+ final ITmfStateSystem ssq = TmfStateSystemAnalysisModule.getStateSystem(trace, KernelAnalysisModule.ID);
+ if (ssq == null) {
+ return;
+ }
+
+ Map<Integer, ResourcesEntry> entryMap = new HashMap<>();
+ TimeGraphEntry traceEntry = null;
+
+ long startTime = ssq.getStartTime();
+ long start = startTime;
+ setStartTime(Math.min(getStartTime(), startTime));
+ boolean complete = false;
+ while (!complete) {
+ if (monitor.isCanceled()) {
+ return;
+ }
+ complete = ssq.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
+ if (ssq.isCancelled()) {
+ return;
+ }
+ long end = ssq.getCurrentEndTime();
+ if (start == end && !complete) {
+ // when complete execute one last time regardless of end time
+ continue;
+ }
+ long endTime = end + 1;
+ setEndTime(Math.max(getEndTime(), endTime));
+
+ if (traceEntry == null) {
+ traceEntry = new ResourcesEntry(trace, trace.getName(), startTime, endTime, 0);
+ List<TimeGraphEntry> entryList = Collections.singletonList(traceEntry);
+ addToEntryList(parentTrace, ssq, entryList);
+ } else {
+ traceEntry.updateEndTime(endTime);
+ }
+ List<Integer> cpuQuarks = ssq.getQuarks(Attributes.CPUS, "*"); //$NON-NLS-1$
+ createCpuEntriesWithQuark(trace, ssq, entryMap, traceEntry, startTime, endTime, cpuQuarks);
+ if (parentTrace.equals(getTrace())) {
+ refresh();
+ }
+ final List<@NonNull TimeGraphEntry> traceEntryChildren = traceEntry.getChildren();
+ final long resolution = Math.max(1, (endTime - ssq.getStartTime()) / getDisplayWidth());
+ queryFullStates(ssq, ssq.getStartTime(), end, resolution, monitor, new IQueryHandler() {
+ @Override
+ public void handle(List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState) {
+ for (TimeGraphEntry child : traceEntryChildren) {
+ if (!populateEventsRecursively(fullStates, prevFullState, child).isOK()) {
+ return;
+ }
+ }
+ }
+
+ private IStatus populateEventsRecursively(@NonNull List<List<ITmfStateInterval>> fullStates, @Nullable List<ITmfStateInterval> prevFullState, @NonNull TimeGraphEntry entry) {
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+ List<ITimeEvent> eventList = getEventList(entry, ssq, fullStates, prevFullState, monitor);
+ if (eventList != null) {
+ /* Start a new event list on first iteration, then append to it */
+ if (prevFullState == null) {
+ entry.setEventList(eventList);
+ } else {
+ for (ITimeEvent event : eventList) {
+ entry.addEvent(event);
+ }
+ }
+ }
+ for (TimeGraphEntry child : entry.getChildren()) {
+ IStatus status = populateEventsRecursively(fullStates, prevFullState, child);
+ if (!status.isOK()) {
+ return status;
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ });
+
+ start = end;
+ }
+
+ }
+
+ private static void createCpuEntriesWithQuark(@NonNull ITmfTrace trace, final ITmfStateSystem ssq, Map<Integer, ResourcesEntry> entryMap, TimeGraphEntry traceEntry, long startTime, long endTime, List<Integer> cpuQuarks) {
+ for (Integer cpuQuark : cpuQuarks) {
+ final @NonNull String cpuName = ssq.getAttributeName(cpuQuark);
+ int cpu = Integer.parseInt(cpuName);
+ ResourcesEntry cpuEntry = entryMap.get(cpuQuark);
+ if (cpuEntry == null) {
+ cpuEntry = new ResourcesEntry(cpuQuark, trace, startTime, endTime, Type.CPU, cpu);
+ entryMap.put(cpuQuark, cpuEntry);
+ traceEntry.addChild(cpuEntry);
+ } else {
+ cpuEntry.updateEndTime(endTime);
+ }
+ List<Integer> irqQuarks = ssq.getQuarks(Attributes.CPUS, cpuName, Attributes.IRQS, "*"); //$NON-NLS-1$
+ createCpuInterruptEntryWithQuark(trace, ssq, entryMap, startTime, endTime, traceEntry, cpuEntry, irqQuarks, Type.IRQ);
+ List<Integer> softIrqQuarks = ssq.getQuarks(Attributes.CPUS, cpuName, Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
+ createCpuInterruptEntryWithQuark(trace, ssq, entryMap, startTime, endTime, traceEntry, cpuEntry, softIrqQuarks, Type.SOFT_IRQ);
+ }
+ }
+
+ /**
+ * Create and add execution contexts to a cpu entry. Also creates an
+ * aggregate entry in the root trace entry. The execution context is
+ * basically what the cpu is doing in its execution stack. It can be in an
+ * IRQ, Soft IRQ. MCEs, NMIs, Userland and Kernel execution is not yet
+ * supported.
+ *
+ * @param trace
+ * the trace
+ * @param ssq
+ * the state system
+ * @param entryMap
+ * the entry map
+ * @param startTime
+ * the start time in nanoseconds
+ * @param endTime
+ * the end time in nanoseconds
+ * @param traceEntry
+ * the trace timegraph entry
+ * @param cpuEntry
+ * the cpu timegraph entry (the entry under the trace entry
+ * @param childrenQuarks
+ * the quarks to add to cpu entry
+ * @param type
+ * the type of entry being added
+ */
+ private static void createCpuInterruptEntryWithQuark(@NonNull ITmfTrace trace,
+ final ITmfStateSystem ssq, Map<Integer, ResourcesEntry> entryMap,
+ long startTime, long endTime,
+ TimeGraphEntry traceEntry, ResourcesEntry cpuEntry,
+ List<Integer> childrenQuarks, Type type) {
+ for (Integer quark : childrenQuarks) {
+ final @NonNull String resourceName = ssq.getAttributeName(quark);
+ int resourceId = Integer.parseInt(resourceName);
+ ResourcesEntry interruptEntry = entryMap.get(quark);
+ if (interruptEntry == null) {
+ interruptEntry = new ResourcesEntry(quark, trace, startTime, endTime, type, resourceId);
+ entryMap.put(quark, interruptEntry);
+ cpuEntry.addChild(interruptEntry);
+ boolean found = false;
+ for (ITimeGraphEntry rootElem : traceEntry.getChildren()) {
+ if (rootElem instanceof AggregateResourcesEntry) {
+ AggregateResourcesEntry aggregateInterruptEntry = (AggregateResourcesEntry) rootElem;
+ if (aggregateInterruptEntry.getId() == resourceId && aggregateInterruptEntry.getType().equals(type)) {
+ found = true;
+ aggregateInterruptEntry.addContributor(interruptEntry);
+ final AggregateResourcesEntry irqCpuEntry = new AggregateResourcesEntry(trace, cpuEntry.getName(), startTime, endTime, type, cpuEntry.getId());
+ irqCpuEntry.addContributor(interruptEntry);
+ aggregateInterruptEntry.addChild(irqCpuEntry);
+ break;
+ }
+ }
+ }
+ if (!found) {
+ AggregateResourcesEntry aggregateInterruptEntry = new AggregateResourcesEntry(trace, startTime, endTime, type, resourceId);
+ aggregateInterruptEntry.addContributor(interruptEntry);
+ final AggregateResourcesEntry irqCpuEntry = new AggregateResourcesEntry(trace, cpuEntry.getName(), startTime, endTime, type, cpuEntry.getId());
+ irqCpuEntry.addContributor(interruptEntry);
+ aggregateInterruptEntry.addChild(irqCpuEntry);
+ traceEntry.addChild(aggregateInterruptEntry);
+ }
+ } else {
+ interruptEntry.updateEndTime(endTime);
+ }
+ }
+ }
+
+ @Override
+ protected @Nullable List<ITimeEvent> getEventList(@NonNull TimeGraphEntry entry, ITmfStateSystem ssq,
+ @NonNull List<List<ITmfStateInterval>> fullStates, @Nullable List<ITmfStateInterval> prevFullState, @NonNull IProgressMonitor monitor) {
+ ResourcesEntry resourcesEntry = (ResourcesEntry) entry;
+ int quark = resourcesEntry.getQuark();
+
+ if (resourcesEntry.getType().equals(Type.CPU)) {
+ return createCpuEventsList(entry, ssq, fullStates, prevFullState, monitor, quark);
+ } else if ((resourcesEntry.getType().equals(Type.IRQ) || resourcesEntry.getType().equals(Type.SOFT_IRQ)) && (quark >= 0)) {
+ return createIrqEventsList(entry, fullStates, prevFullState, monitor, quark);
+ }
+
+ return null;
+ }
+
+ private static List<ITimeEvent> createCpuEventsList(ITimeGraphEntry entry, ITmfStateSystem ssq, List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState, IProgressMonitor monitor, int quark) {
+ List<ITimeEvent> eventList;
+ int statusQuark;
+ try {
+ statusQuark = ssq.getQuarkRelative(quark, Attributes.STATUS);
+ } catch (AttributeNotFoundException e) {
+ /*
+ * The sub-attribute "status" is not available. May happen if the
+ * trace does not have sched_switch events enabled.
+ */
+ return null;
+ }
+ boolean isZoomThread = Thread.currentThread() instanceof ZoomThread;
+ eventList = new ArrayList<>(fullStates.size());
+ ITmfStateInterval lastInterval = prevFullState == null || statusQuark >= prevFullState.size() ? null : prevFullState.get(statusQuark);
+ long lastStartTime = lastInterval == null ? -1 : lastInterval.getStartTime();
+ long lastEndTime = lastInterval == null ? -1 : lastInterval.getEndTime() + 1;
+ for (List<ITmfStateInterval> fullState : fullStates) {
+ if (monitor.isCanceled()) {
+ return null;
+ }
+ if (statusQuark >= fullState.size()) {
+ /* No information on this CPU (yet?), skip it for now */
+ continue;
+ }
+ ITmfStateInterval statusInterval = fullState.get(statusQuark);
+ int status = statusInterval.getStateValue().unboxInt();
+ long time = statusInterval.getStartTime();
+ long duration = statusInterval.getEndTime() - time + 1;
+ if (time == lastStartTime) {
+ continue;
+ }
+ if (!statusInterval.getStateValue().isNull()) {
+ if (lastEndTime != time && lastEndTime != -1) {
+ eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
+ }
+ eventList.add(new TimeEvent(entry, time, duration, status));
+ } else if (isZoomThread) {
+ eventList.add(new NullTimeEvent(entry, time, duration));
+ }
+ lastStartTime = time;
+ lastEndTime = time + duration;
+ }
+ return eventList;
+ }
+
+ private static List<ITimeEvent> createIrqEventsList(ITimeGraphEntry entry, List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState, IProgressMonitor monitor, int quark) {
+ List<ITimeEvent> eventList;
+ boolean isZoomThread = Thread.currentThread() instanceof ZoomThread;
+ eventList = new ArrayList<>(fullStates.size());
+ ITmfStateInterval lastInterval = prevFullState == null || quark >= prevFullState.size() ? null : prevFullState.get(quark);
+ long lastStartTime = lastInterval == null ? -1 : lastInterval.getStartTime();
+ long lastEndTime = lastInterval == null ? -1 : lastInterval.getEndTime() + 1;
+ boolean lastIsNull = lastInterval == null ? false : lastInterval.getStateValue().isNull();
+ for (List<ITmfStateInterval> fullState : fullStates) {
+ if (monitor.isCanceled()) {
+ return null;
+ }
+ if (quark >= fullState.size()) {
+ /* No information on this IRQ (yet?), skip it for now */
+ continue;
+ }
+ ITmfStateInterval irqInterval = fullState.get(quark);
+ long time = irqInterval.getStartTime();
+ long duration = irqInterval.getEndTime() - time + 1;
+ if (time == lastStartTime) {
+ continue;
+ }
+ if (!irqInterval.getStateValue().isNull()) {
+ int cpu = irqInterval.getStateValue().unboxInt();
+ eventList.add(new TimeEvent(entry, time, duration, cpu));
+ lastIsNull = false;
+ } else {
+ if (lastEndTime != time && lastIsNull) {
+ /*
+ * This is a special case where we want to show IRQ_ACTIVE
+ * state but we don't know the CPU (it is between two null
+ * samples)
+ */
+ eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime, -1));
+ }
+ if (isZoomThread) {
+ eventList.add(new NullTimeEvent(entry, time, duration));
+ }
+ lastIsNull = true;
+ }
+ lastStartTime = time;
+ lastEndTime = time + duration;
+ }
+ return eventList;
+ }
+
+ /**
+ * Signal handler for a cpu selected signal.
+ *
+ * @param signal
+ * the cpu selected signal
+ * @since 2.0
+ */
+ @TmfSignalHandler
+ public void listenToCpu(TmfCpuSelectedSignal signal) {
+ if (signal.getCore() >= 0) {
+ fCurrentCpu = signal.getCore();
+ } else {
+ fCurrentCpu = -1;
+ }
+ }
+
+}
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
import org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow.ControlFlowView;
-import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesView;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import java.util.Arrays;
import org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow.ControlFlowView;
-import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesView;
import org.eclipse.tracecompass.internal.lttng2.control.ui.views.ControlView;
import org.eclipse.tracecompass.internal.lttng2.kernel.ui.views.PerspectiveFactory;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.AbstractPerspectiveChecker;
package org.eclipse.tracecompass.internal.lttng2.kernel.ui.views;
import org.eclipse.tracecompass.analysis.os.linux.ui.views.controlflow.ControlFlowView;
-import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesView;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesView;
import org.eclipse.tracecompass.internal.lttng2.control.ui.views.ControlView;
import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard;
import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView;