X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=org.eclipse.linuxtools.lttng2.kernel.ui%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Finternal%2Flttng2%2Fkernel%2Fui%2Fviews%2Fcontrolflow%2FControlFlowView.java;h=3bbd30ca991056ff451469aa084464ad561daa1b;hb=bcec0116448fab84a99a822ea9912cabb5c983f4;hp=68ed2258e0b115ba5c99692ea3627463e804c704;hpb=086f21ae5fedbff46d896d84c3ab4bc5d753ad71;p=deliverable%2Ftracecompass.git diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java index 68ed2258e0..3bbd30ca99 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2013 Ericsson, École Polytechnique de Montréal + * Copyright (c) 2012, 2014 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 @@ -14,24 +14,27 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.ui.views.controlflow; 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.jdt.annotation.Nullable; +import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes; import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Activator; import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages; -import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.lttng2.kernel.core.analysis.LttngKernelAnalysisModule; +import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem; +import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView; @@ -79,6 +82,9 @@ public class ControlFlowView extends AbstractTimeGraphView { TID_COLUMN }; + // Timeout between updates in the build thread in ms + private static final long BUILD_UPDATE_TIMEOUT = 500; + // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ @@ -91,6 +97,7 @@ public class ControlFlowView extends AbstractTimeGraphView { setTreeColumns(COLUMN_NAMES); setTreeLabelProvider(new ControlFlowTreeLabelProvider()); setFilterColumns(FILTER_COLUMN_NAMES); + setFilterLabelProvider(new ControlFlowFilterLabelProvider()); setEntryComparator(new ControlFlowEntryComparator()); } @@ -102,9 +109,19 @@ public class ControlFlowView extends AbstractTimeGraphView { if (section == null) { section = settings.addNewSection(getClass().getName()); } - manager.add(getTimeGraphCombo().getTimeGraphViewer().getHideArrowsAction(section)); - manager.add(getTimeGraphCombo().getTimeGraphViewer().getFollowArrowBwdAction()); - manager.add(getTimeGraphCombo().getTimeGraphViewer().getFollowArrowFwdAction()); + + IAction hideArrowsAction = getTimeGraphCombo().getTimeGraphViewer().getHideArrowsAction(section); + manager.add(hideArrowsAction); + + IAction followArrowBwdAction = getTimeGraphCombo().getTimeGraphViewer().getFollowArrowBwdAction(); + followArrowBwdAction.setText(Messages.ControlFlowView_followCPUBwdText); + followArrowBwdAction.setToolTipText(Messages.ControlFlowView_followCPUBwdText); + manager.add(followArrowBwdAction); + + IAction followArrowFwdAction = getTimeGraphCombo().getTimeGraphViewer().getFollowArrowFwdAction(); + followArrowFwdAction.setText(Messages.ControlFlowView_followCPUFwdText); + followArrowFwdAction.setToolTipText(Messages.ControlFlowView_followCPUFwdText); + manager.add(followArrowFwdAction); } @Override @@ -182,161 +199,210 @@ public class ControlFlowView extends AbstractTimeGraphView { } + private static class ControlFlowFilterLabelProvider extends TreeLabelProvider { + + @Override + public String getColumnText(Object element, int columnIndex) { + ControlFlowEntry entry = (ControlFlowEntry) element; + + if (columnIndex == 0) { + return entry.getName(); + } else if (columnIndex == 1) { + return Integer.toString(entry.getThreadId()); + } + return ""; //$NON-NLS-1$ + } + + } + // ------------------------------------------------------------------------ // Internal // ------------------------------------------------------------------------ @Override - protected void buildEventList(final ITmfTrace trace, IProgressMonitor monitor) { - setStartTime(Long.MAX_VALUE); - setEndTime(Long.MIN_VALUE); + protected void buildEventList(final ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor) { + LttngKernelAnalysisModule module = trace.getAnalysisModuleOfClass(LttngKernelAnalysisModule.class, LttngKernelAnalysisModule.ID); + if (module == null) { + return; + } + module.schedule(); + module.waitForInitialization(); + ITmfStateSystem ssq = module.getStateSystem(); + if (ssq == null) { + return; + } - ArrayList rootList = new ArrayList(); - for (ITmfTrace aTrace : fTraceManager.getActiveTraceSet()) { + List entryList = new ArrayList<>(); + Map entryMap = new HashMap<>(); + + long start = ssq.getStartTime(); + setStartTime(Math.min(getStartTime(), start)); + + boolean complete = false; + while (!complete) { if (monitor.isCanceled()) { return; } - if (aTrace instanceof LttngKernelTrace) { - ArrayList entryList = new ArrayList(); - LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) aTrace; - ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID); - if (!ssq.waitUntilBuilt()) { + 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; + } + setEndTime(Math.max(getEndTime(), end + 1)); + List threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$ + for (int threadQuark : threadQuarks) { + if (monitor.isCanceled()) { return; } - long start = ssq.getStartTime(); - long end = ssq.getCurrentEndTime() + 1; - setStartTime(Math.min(getStartTime(), start)); - setEndTime(Math.max(getEndTime(), end)); - List threadQuarks = ssq.getQuarks(Attributes.THREADS, "*"); //$NON-NLS-1$ - for (int threadQuark : threadQuarks) { + String threadName = ssq.getAttributeName(threadQuark); + int threadId = -1; + try { + threadId = Integer.parseInt(threadName); + } catch (NumberFormatException e1) { + continue; + } + if (threadId <= 0) { // ignore the 'unknown' (-1) and swapper (0) threads + continue; + } + + int execNameQuark; + List execNameIntervals; + try { + execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME); + execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end); + } catch (AttributeNotFoundException e) { + /* No information on this thread (yet?), skip it for now */ + continue; + } catch (StateSystemDisposedException e) { + /* State system is closing down, no point continuing */ + break; + } + + for (ITmfStateInterval execNameInterval : execNameIntervals) { if (monitor.isCanceled()) { return; } - String threadName = ssq.getAttributeName(threadQuark); - int threadId = -1; - try { - threadId = Integer.parseInt(threadName); - } catch (NumberFormatException e1) { - continue; - } - if (threadId == 0) { // ignore the swapper thread - continue; - } - int execNameQuark = -1; - try { - try { - execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME); - } catch (AttributeNotFoundException e) { - continue; - } - int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID); - List execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end - 1); - // use monitor when available in api - if (monitor.isCanceled()) { - return; - } - TimeGraphEntry entry = null; - for (ITmfStateInterval execNameInterval : execNameIntervals) { - if (monitor.isCanceled()) { - return; + ControlFlowEntry entry = entryMap.get(threadId); + if (!execNameInterval.getStateValue().isNull() && + execNameInterval.getStateValue().getType() == ITmfStateValue.Type.STRING) { + String execName = execNameInterval.getStateValue().unboxStr(); + long startTime = execNameInterval.getStartTime(); + long endTime = execNameInterval.getEndTime() + 1; + if (entry == null) { + ITmfStateInterval ppidInterval = null; + try { + int ppidQuark = ssq.getQuarkRelative(threadQuark, Attributes.PPID); + ppidInterval = ssq.querySingleState(startTime, ppidQuark); + } catch (AttributeNotFoundException e) { + /* No info, keep PPID at -1 */ + } catch (StateSystemDisposedException e) { + /* SS is closing down, time to bail */ + break; } - if (!execNameInterval.getStateValue().isNull() && - execNameInterval.getStateValue().getType() == ITmfStateValue.Type.STRING) { - String execName = execNameInterval.getStateValue().unboxStr(); - long startTime = execNameInterval.getStartTime(); - long endTime = execNameInterval.getEndTime() + 1; - int ppid = -1; - if (ppidQuark != -1) { - ITmfStateInterval ppidInterval = ssq.querySingleState(startTime, ppidQuark); - ppid = ppidInterval.getStateValue().unboxInt(); - } - if (entry == null) { - entry = new ControlFlowEntry(threadQuark, ctfKernelTrace, execName, threadId, ppid, startTime, endTime); - entryList.add(entry); - } else { - // update the name of the entry to the - // latest execName - entry.setName(execName); - } - entry.addEvent(new TimeEvent(entry, startTime, endTime - startTime)); - } else { - entry = null; + int ppid = -1; + if (!(ppidInterval == null) && !ppidInterval.getStateValue().isNull()) { + ppid = ppidInterval.getStateValue().unboxInt(); } + entry = new ControlFlowEntry(threadQuark, trace, execName, threadId, ppid, startTime, endTime); + entryList.add(entry); + entryMap.put(threadId, entry); + } else { + // update the name of the entry to the latest + // execName + entry.setName(execName); + entry.updateEndTime(endTime); } - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } catch (StateSystemDisposedException e) { - /* Ignored */ + } else { + entryMap.remove(threadId); } } - buildTree(entryList, rootList); } - Collections.sort(rootList, getEntryComparator()); - putEntryList(trace, (ArrayList) rootList.clone()); - if (trace.equals(getTrace())) { + updateTree(entryList, parentTrace); + + if (parentTrace.equals(getTrace())) { refresh(); } - } - for (TimeGraphEntry entry : rootList) { - if (monitor.isCanceled()) { - return; + + for (ControlFlowEntry entry : entryList) { + if (monitor.isCanceled()) { + return; + } + buildStatusEvents(entry.getTrace(), entry, monitor, start, end); } - buildStatusEvents(trace, entry, monitor); + + start = end; } } - private static void buildTree(ArrayList entryList, - ArrayList rootList) { - for (TimeGraphEntry listentry : entryList) { - ControlFlowEntry entry = (ControlFlowEntry) listentry; - boolean root = true; - if (entry.getParentThreadId() > 0) { - for (TimeGraphEntry parententry : entryList) { - ControlFlowEntry parent = (ControlFlowEntry) parententry; + private void updateTree(List entryList, ITmfTrace parentTrace) { + List rootListToAdd = new ArrayList<>(); + List rootListToRemove = new ArrayList<>(); + List rootList = getEntryList(parentTrace); + + for (ControlFlowEntry entry : entryList) { + boolean root = (entry.getParent() == null); + if (root && entry.getParentThreadId() > 0) { + for (ControlFlowEntry parent : entryList) { if (parent.getThreadId() == entry.getParentThreadId() && entry.getStartTime() >= parent.getStartTime() && entry.getStartTime() <= parent.getEndTime()) { parent.addChild(entry); root = false; + if (rootList != null && rootList.contains(entry)) { + rootListToRemove.add(entry); + } break; } } } - if (root) { - rootList.add(entry); + if (root && (rootList == null || !rootList.contains(entry))) { + rootListToAdd.add(entry); } } + + addToEntryList(parentTrace, rootListToAdd); + removeFromEntryList(parentTrace, rootListToRemove); } - private void buildStatusEvents(ITmfTrace trace, TimeGraphEntry entry, IProgressMonitor monitor) { - ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); + private void buildStatusEvents(ITmfTrace trace, ControlFlowEntry entry, IProgressMonitor monitor, long start, long end) { + if (start < entry.getEndTime() && end > entry.getStartTime()) { + LttngKernelAnalysisModule module = entry.getTrace().getAnalysisModuleOfClass(LttngKernelAnalysisModule.class, LttngKernelAnalysisModule.ID); + if (module == null) { + return; + } + ITmfStateSystem ssq = module.getStateSystem(); + if (ssq == null) { + return; + } - long start = ssq.getStartTime(); - long end = ssq.getCurrentEndTime() + 1; - long resolution = Math.max(1, (end - start) / getDisplayWidth()); - List eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, monitor); - if (monitor.isCanceled()) { - return; - } - entry.setEventList(eventList); - if (trace.equals(getTrace())) { - redraw(); + long startTime = Math.max(start, entry.getStartTime()); + long endTime = Math.min(end + 1, entry.getEndTime()); + long resolution = Math.max(1, (end - ssq.getStartTime()) / getDisplayWidth()); + List eventList = getEventList(entry, startTime, endTime, resolution, monitor); + if (eventList == null) { + return; + } + for (ITimeEvent event : eventList) { + entry.addEvent(event); + } + if (trace.equals(getTrace())) { + redraw(); + } } for (ITimeGraphEntry child : entry.getChildren()) { if (monitor.isCanceled()) { return; } - buildStatusEvents(trace, (TimeGraphEntry) child, monitor); + buildStatusEvents(trace, (ControlFlowEntry) child, monitor, start, end); } } @Override - protected List getEventList(TimeGraphEntry tgentry, long startTime, long endTime, long resolution, IProgressMonitor monitor) { + protected @Nullable List getEventList(TimeGraphEntry tgentry, long startTime, long endTime, long resolution, IProgressMonitor monitor) { List eventList = null; if (!(tgentry instanceof ControlFlowEntry)) { return eventList; @@ -347,11 +413,18 @@ public class ControlFlowView extends AbstractTimeGraphView { if (realEnd <= realStart) { return null; } - ITmfStateSystem ssq = entry.getTrace().getStateSystems().get(LttngKernelTrace.STATE_ID); + LttngKernelAnalysisModule module = entry.getTrace().getAnalysisModuleOfClass(LttngKernelAnalysisModule.class, LttngKernelAnalysisModule.ID); + if (module == null) { + return null; + } + ITmfStateSystem ssq = module.getStateSystem(); + if (ssq == null) { + return null; + } try { int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS); List statusIntervals = ssq.queryHistoryRange(statusQuark, realStart, realEnd - 1, resolution, monitor); - eventList = new ArrayList(statusIntervals.size()); + eventList = new ArrayList<>(statusIntervals.size()); long lastEndTime = -1; for (ITmfStateInterval statusInterval : statusIntervals) { if (monitor.isCanceled()) { @@ -371,9 +444,7 @@ public class ControlFlowView extends AbstractTimeGraphView { eventList.add(new TimeEvent(entry, time, duration, status)); lastEndTime = time + duration; } - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (TimeRangeException e) { + } catch (AttributeNotFoundException | TimeRangeException e) { e.printStackTrace(); } catch (StateSystemDisposedException e) { /* Ignored */ @@ -384,8 +455,8 @@ public class ControlFlowView extends AbstractTimeGraphView { /** * Returns a value corresponding to the selected entry. * - * Used in conjunction with selectEntry to change the selected entry. If one - * of these methods is overridden in child class, then both should be. + * Used in conjunction with synchingToTime to change the selected entry. If + * one of these methods is overridden in child class, then both should be. * * @param time * The currently selected time @@ -393,36 +464,40 @@ public class ControlFlowView extends AbstractTimeGraphView { */ private int getSelectionValue(long time) { int thread = -1; - for (ITmfTrace trace : fTraceManager.getActiveTraceSet()) { + ITmfTrace[] traces = TmfTraceManager.getTraceSet(getTrace()); + if (traces == null) { + return thread; + } + for (ITmfTrace trace : traces) { if (thread > 0) { break; } - if (trace instanceof LttngKernelTrace) { - LttngKernelTrace ctfKernelTrace = (LttngKernelTrace) trace; - ITmfStateSystem ssq = ctfKernelTrace.getStateSystems().get(LttngKernelTrace.STATE_ID); - if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) { - List currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$ - for (int currentThreadQuark : currentThreadQuarks) { - try { - ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark); - int currentThread = currentThreadInterval.getStateValue().unboxInt(); - if (currentThread > 0) { - int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS); - ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark); - if (statusInterval.getStartTime() == time) { - thread = currentThread; - break; - } + LttngKernelAnalysisModule module = trace.getAnalysisModuleOfClass(LttngKernelAnalysisModule.class, LttngKernelAnalysisModule.ID); + if (module == null) { + continue; + } + ITmfStateSystem ssq = module.getStateSystem(); + if (ssq == null) { + continue; + } + if (time >= ssq.getStartTime() && time <= ssq.getCurrentEndTime()) { + List currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$ + for (int currentThreadQuark : currentThreadQuarks) { + try { + ITmfStateInterval currentThreadInterval = ssq.querySingleState(time, currentThreadQuark); + int currentThread = currentThreadInterval.getStateValue().unboxInt(); + if (currentThread > 0) { + int statusQuark = ssq.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThread), Attributes.STATUS); + ITmfStateInterval statusInterval = ssq.querySingleState(time, statusQuark); + if (statusInterval.getStartTime() == time) { + thread = currentThread; + break; } - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } catch (StateSystemDisposedException e) { - /* Ignored */ } + } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) { + e.printStackTrace(); + } catch (StateSystemDisposedException e) { + /* Ignored */ } } } @@ -448,50 +523,63 @@ public class ControlFlowView extends AbstractTimeGraphView { @Override protected List getLinkList(long startTime, long endTime, long resolution, IProgressMonitor monitor) { - List list = new ArrayList(); + List list = new ArrayList<>(); ITmfTrace[] traces = TmfTraceManager.getTraceSet(getTrace()); - List entryList = getEntryListMap().get(getTrace()); + List entryList = getEntryList(getTrace()); if (traces == null || entryList == null) { return list; } for (ITmfTrace trace : traces) { - if (trace instanceof LttngKernelTrace) { - ITmfStateSystem ssq = trace.getStateSystems().get(LttngKernelTrace.STATE_ID); - try { - long start = Math.max(startTime, ssq.getStartTime()); - long end = Math.min(endTime, ssq.getCurrentEndTime()); - if (end < start) { - continue; - } - List currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$ - for (int currentThreadQuark : currentThreadQuarks) { - List currentThreadIntervals = ssq.queryHistoryRange(currentThreadQuark, start, end, resolution, monitor); - int prevThread = 0; - long prevEnd = 0; - for (ITmfStateInterval currentThreadInterval : currentThreadIntervals) { - if (monitor.isCanceled()) { - return null; - } - long time = currentThreadInterval.getStartTime(); - int thread = currentThreadInterval.getStateValue().unboxInt(); - if (thread > 0 && prevThread > 0 && thread != prevThread && time == prevEnd) { - ITimeGraphEntry prevEntry = findEntry(entryList, trace, prevThread); - ITimeGraphEntry nextEntry = findEntry(entryList, trace, thread); - list.add(new TimeLinkEvent(prevEntry, nextEntry, time, 0, 0)); - } + LttngKernelAnalysisModule module = trace.getAnalysisModuleOfClass(LttngKernelAnalysisModule.class, LttngKernelAnalysisModule.ID); + if (module == null) { + continue; + } + ITmfStateSystem ssq = module.getStateSystem(); + if (ssq == null) { + continue; + } + try { + long start = Math.max(startTime, ssq.getStartTime()); + long end = Math.min(endTime, ssq.getCurrentEndTime()); + if (end < start) { + continue; + } + List currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$ + for (int currentThreadQuark : currentThreadQuarks) { + // adjust the query range to include the previous and following intervals + long qstart = Math.max(ssq.querySingleState(start, currentThreadQuark).getStartTime() - 1, ssq.getStartTime()); + long qend = Math.min(ssq.querySingleState(end, currentThreadQuark).getEndTime() + 1, ssq.getCurrentEndTime()); + List currentThreadIntervals = ssq.queryHistoryRange(currentThreadQuark, qstart, qend, resolution, monitor); + int prevThread = 0; + long prevEnd = 0; + long lastEnd = 0; + for (ITmfStateInterval currentThreadInterval : currentThreadIntervals) { + if (monitor.isCanceled()) { + return null; + } + long time = currentThreadInterval.getStartTime(); + if (time != lastEnd) { + // don't create links where there are gaps in intervals due to the resolution + prevThread = 0; + prevEnd = 0; + } + int thread = currentThreadInterval.getStateValue().unboxInt(); + if (thread > 0 && prevThread > 0) { + ITimeGraphEntry prevEntry = findEntry(entryList, trace, prevThread); + ITimeGraphEntry nextEntry = findEntry(entryList, trace, thread); + list.add(new TimeLinkEvent(prevEntry, nextEntry, prevEnd, time - prevEnd, 0)); + } + lastEnd = currentThreadInterval.getEndTime() + 1; + if (thread != 0) { prevThread = thread; - prevEnd = currentThreadInterval.getEndTime() + 1; + prevEnd = lastEnd; } } - } catch (TimeRangeException e) { - e.printStackTrace(); - } catch (AttributeNotFoundException e) { - e.printStackTrace(); - } catch (StateValueTypeException e) { - e.printStackTrace(); - } catch (StateSystemDisposedException e) { - /* Ignored */ } + } catch (TimeRangeException | AttributeNotFoundException | StateValueTypeException e) { + e.printStackTrace(); + } catch (StateSystemDisposedException e) { + /* Ignored */ } } return list;