use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class ThreadStatusDataProvider method fetchTree.
@Override
@NonNull
public TmfModelResponse<@NonNull TmfTreeModel<@NonNull TimeGraphEntryModel>> fetchTree(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
if (fLastEnd == Long.MAX_VALUE) {
return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), filter(Objects.requireNonNull(fTraceEntry), fTidToEntry, fetchParameters)), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
fModule.waitForInitialization();
ITmfStateSystem ss = fModule.getStateSystem();
if (ss == null) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
}
/*
* As we are caching the intermediate result, we only want a single thread to
* update them.
*/
synchronized (fBuildMap) {
boolean complete = ss.waitUntilBuilt(0);
@NonNull List<@NonNull TimeGraphEntryModel> list = Collections.emptyList();
/* Don't query empty state system */
if (ss.getNbAttributes() > 0 && ss.getStartTime() != Long.MIN_VALUE) {
long end = ss.getCurrentEndTime();
fLastEnd = Long.max(fLastEnd, ss.getStartTime());
TreeMultimap<Integer, ITmfStateInterval> threadData = TreeMultimap.create(Comparator.naturalOrder(), Comparator.comparing(ITmfStateInterval::getStartTime));
/*
* Create a List with the threads' PPID and EXEC_NAME quarks for the 2D query .
*/
List<Integer> quarks = new ArrayList<>(ss.getQuarks(Attributes.THREADS, WILDCARD, Attributes.EXEC_NAME));
quarks.addAll(ss.getQuarks(Attributes.THREADS, WILDCARD, Attributes.PPID));
quarks.addAll(ss.getQuarks(Attributes.THREADS, WILDCARD, Attributes.PID));
try {
for (ITmfStateInterval interval : ss.query2D(quarks, Long.min(fLastEnd, end), end)) {
if (monitor != null && monitor.isCanceled()) {
return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
}
threadData.put(interval.getAttribute(), interval);
}
} catch (TimeRangeException | StateSystemDisposedException e) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, e.getClass().getName() + ':' + String.valueOf(e.getMessage()));
}
// update the trace Entry.
TimeGraphEntryModel traceEntry = new TimeGraphEntryModel(fTraceId, -1, getTrace().getName(), ss.getStartTime(), end);
fTraceEntry = traceEntry;
for (Integer threadQuark : ss.getQuarks(Attributes.THREADS, WILDCARD)) {
String threadAttributeName = ss.getAttributeName(threadQuark);
Pair<Integer, Integer> entryKey = Attributes.parseThreadAttributeName(threadAttributeName);
int threadId = entryKey.getFirst();
if (threadId < 0) {
// ignore the 'unknown' (-1) thread
continue;
}
int execNameQuark = ss.optQuarkRelative(threadQuark, Attributes.EXEC_NAME);
int ppidQuark = ss.optQuarkRelative(threadQuark, Attributes.PPID);
int pidQuark = ss.optQuarkRelative(threadQuark, Attributes.PID);
NavigableSet<ITmfStateInterval> ppidIntervals = threadData.get(ppidQuark);
NavigableSet<ITmfStateInterval> pidIntervals = threadData.get(pidQuark);
for (ITmfStateInterval execNameInterval : threadData.get(execNameQuark)) {
if (monitor != null && monitor.isCanceled()) {
return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
}
updateEntry(threadQuark, entryKey, ppidIntervals, execNameInterval, pidIntervals);
}
}
fLastEnd = end;
list = filter(traceEntry, fTidToEntry, fetchParameters);
}
for (TimeGraphEntryModel model : list) {
fEntryMetadata.put(model.getId(), model.getMetadata());
}
if (complete) {
fBuildMap.clear();
fLastEnd = Long.MAX_VALUE;
return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
}
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class ThreadStatusDataProvider method filter.
/**
* Filter the threads from a {@link TreeMultimap} according to if they are
* active or not
* @param traceEntry
*
* @param tidToEntry
* Threads to filter
* @param filter
* time range to query
* @return a list of the active threads
*/
@NonNull
private List<@NonNull TimeGraphEntryModel> filter(TimeGraphEntryModel traceEntry, TreeMultimap<Integer, ThreadEntryModel.Builder> tidToEntry, @NonNull Map<@NonNull String, @NonNull Object> parameters) {
// avoid putting everything as a child of the swapper thread.
Boolean isActiveFilter = DataProviderParameterUtils.extractBoolean(parameters, ACTIVE_THREAD_FILTER_KEY);
if (!Boolean.TRUE.equals(isActiveFilter)) {
ImmutableList.Builder<TimeGraphEntryModel> builder = ImmutableList.builder();
builder.add(traceEntry);
for (ThreadEntryModel.Builder entryBuilder : tidToEntry.values()) {
builder.add(build(entryBuilder));
}
return builder.build();
}
ITmfStateSystem ss = fModule.getStateSystem();
if (ss == null) {
return Collections.emptyList();
}
List<@NonNull Long> filter = DataProviderParameterUtils.extractTimeRequested(parameters);
if (filter == null || filter.isEmpty()) {
return Collections.emptyList();
}
long start = Long.max(filter.get(0), ss.getStartTime());
long end = Long.min(filter.get(filter.size() - 1), ss.getCurrentEndTime());
if (start > end) {
return Collections.emptyList();
}
List<@NonNull Long> selectedItems = DataProviderParameterUtils.extractSelectedItems(parameters);
if (selectedItems != null) {
Set<Long> cpus = Sets.newHashSet(selectedItems);
List<@NonNull Integer> quarks = ss.getQuarks(Attributes.THREADS, WILDCARD, Attributes.CURRENT_CPU_RQ);
Set<TimeGraphEntryModel> models = new HashSet<>();
models.add(traceEntry);
Map<Integer, Integer> rqToPidCache = new HashMap<>();
try {
for (ITmfStateInterval interval : ss.query2D(quarks, Long.max(ss.getStartTime(), start), end)) {
Object o = interval.getValue();
if (o instanceof Number && cpus.contains(((Number) o).longValue())) {
int attribute = interval.getAttribute();
try {
// Get the name of the thread
int nameQuark = ss.getQuarkRelative(ss.getParentAttributeQuark(attribute), Attributes.EXEC_NAME);
Iterable<@NonNull ITmfStateInterval> names2d = ss.query2D(Collections.singleton(nameQuark), interval.getStartTime(), interval.getEndTime());
Iterable<@NonNull String> names = Iterables.transform(names2d, intervalName -> String.valueOf(intervalName.getValue()));
int tid = rqToPidCache.computeIfAbsent(attribute, a -> Attributes.parseThreadAttributeName(ss.getAttributeName(ss.getParentAttributeQuark(a))).getFirst());
// Skip Idle (thread 0)
if (tid == 0) {
continue;
}
for (ThreadEntryModel.Builder model : tidToEntry.get(tid)) {
if (interval.getStartTime() <= model.getEndTime() && model.getStartTime() <= interval.getEndTime()) {
ThreadEntryModel build = build(model);
if (!Iterables.any(names, name -> name.equals(build.getName()))) {
continue;
}
models.add(build);
}
}
} catch (AttributeNotFoundException e) {
// $NON-NLS-1$
Activator.getDefault().logWarning("Unable to get the quark for the attribute name", e);
}
}
}
} catch (IndexOutOfBoundsException | TimeRangeException e) {
// $NON-NLS-1$
Activator.getDefault().logError("Invalid query parameters", e);
} catch (StateSystemDisposedException e) {
return Collections.emptyList();
}
return Lists.newArrayList(models);
}
ImmutableList.Builder<TimeGraphEntryModel> builder = ImmutableList.builder();
builder.add(traceEntry);
for (ThreadEntryModel.Builder thread : tidToEntry.values()) {
Integer statusQuark = fQuarkMap.get(thread.getId());
if (statusQuark == null) {
continue;
}
QuarkIterator iterator = new QuarkIterator(ss, statusQuark, start, end);
Iterator<Object> values = Iterators.transform(iterator, ITmfStateInterval::getValue);
if (Iterators.any(values, ACTIVE_STATES::contains)) {
builder.add(build(thread));
}
}
return builder.build();
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class ControlFlowCheckActiveProvider method getActiveIds.
private Set<Long> getActiveIds(TimeGraphEntry cfe, TmfTimeRange range) {
ITimeGraphDataProvider<? extends TimeGraphEntryModel> dataProvider = BaseDataProviderTimeGraphView.getProvider(cfe);
if (range.equals(fRange) && dataProvider.equals(fProvider) || !(dataProvider instanceof ThreadStatusDataProvider)) {
return fActive;
}
TimeQueryFilter filter = new TimeQueryFilter(range.getStartTime().toNanos(), range.getEndTime().toNanos(), 2);
Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
parameters.put(ThreadStatusDataProvider.ACTIVE_THREAD_FILTER_KEY, true);
TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> response = ((ThreadStatusDataProvider) dataProvider).fetchTree(parameters, null);
TmfTreeModel<@NonNull TimeGraphEntryModel> model = response.getModel();
if (model == null) {
// query must have failed, return empty and don't invalidate the cache.
return Collections.emptySet();
}
fRange = range;
fActive = model.getEntries().stream().map(TimeGraphEntryModel::getId).collect(Collectors.toSet());
return fActive;
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class ActiveThreadsFilter method getActiveThreads.
@NonNull
private static Set<Long> getActiveThreads(TmfTimeRange winRange, @NonNull ITmfTrace trace) {
ThreadStatusDataProvider threadStatusProvider = DataProviderManager.getInstance().getDataProvider(trace, ThreadStatusDataProvider.ID, ThreadStatusDataProvider.class);
if (threadStatusProvider == null) {
return Collections.emptySet();
}
long beginTS = winRange.getStartTime().getValue();
long endTS = winRange.getEndTime().getValue();
TimeQueryFilter filter = new TimeQueryFilter(beginTS, endTS, 2);
Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
parameters.put(ThreadStatusDataProvider.ACTIVE_THREAD_FILTER_KEY, true);
TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> response = threadStatusProvider.fetchTree(parameters, null);
TmfTreeModel<@NonNull TimeGraphEntryModel> model = response.getModel();
if (model == null) {
return Collections.emptySet();
}
HashSet<Long> activeThreads = Sets.newHashSet(Iterables.transform(model.getEntries(), TimeGraphEntryModel::getId));
return activeThreads == null ? Collections.emptySet() : activeThreads;
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class FlameChartView method getPreviousEventAction.
/**
* Get the previous event action.
*
* @return The Action object
*/
private Action getPreviousEventAction() {
Action prevAction = fPrevEventAction;
if (prevAction == null) {
Action superPrevAction = getTimeGraphViewer().getPreviousEventAction();
prevAction = new Action() {
@Override
public void run() {
TimeGraphViewer viewer = getTimeGraphViewer();
ITimeGraphEntry entry = viewer.getSelection();
if (entry instanceof TimeGraphEntry) {
TimeGraphEntry callStackEntry = (TimeGraphEntry) entry;
ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider = getProvider(callStackEntry);
long selectionBegin = viewer.getSelectionBegin();
SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(Lists.newArrayList(Long.MIN_VALUE, selectionBegin), Collections.singleton(callStackEntry.getEntryModel().getId()));
TmfModelResponse<@NonNull TimeGraphModel> response = provider.fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
TimeGraphModel model = response.getModel();
if (model == null || model.getRows().size() != 1) {
return;
}
List<@NonNull ITimeGraphState> row = model.getRows().get(0).getStates();
if (row.size() != 1) {
return;
}
ITimeGraphState stackInterval = row.get(0);
viewer.setSelectedTimeNotify(stackInterval.getStartTime(), true);
int stackLevel = stackInterval.getValue();
ITimeGraphEntry selectedEntry = callStackEntry.getParent().getChildren().get(Integer.max(0, stackLevel - 1));
viewer.setSelection(selectedEntry, true);
viewer.getTimeGraphControl().fireSelectionChanged();
startZoomThread(viewer.getTime0(), viewer.getTime1());
}
}
};
prevAction.setText(superPrevAction.getText());
prevAction.setToolTipText(superPrevAction.getToolTipText());
prevAction.setImageDescriptor(superPrevAction.getImageDescriptor());
fPrevEventAction = prevAction;
}
return prevAction;
}
Aggregations