com.efficios.jabberwocky.lttng.kernel.views.timegraph.threads.ThreadsModelArrowProviderCpus.java Source code

Java tutorial

Introduction

Here is the source code for com.efficios.jabberwocky.lttng.kernel.views.timegraph.threads.ThreadsModelArrowProviderCpus.java

Source

/*
 * Copyright (C) 2017 EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
 *
 * 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 com.efficios.jabberwocky.lttng.kernel.views.timegraph.threads;

import ca.polymtl.dorsal.libdelorean.IStateSystemReader;
import ca.polymtl.dorsal.libdelorean.StateSystemUtils;
import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException;
import ca.polymtl.dorsal.libdelorean.exceptions.StateSystemDisposedException;
import ca.polymtl.dorsal.libdelorean.interval.StateInterval;
import ca.polymtl.dorsal.libdelorean.statevalue.IntegerStateValue;
import ca.polymtl.dorsal.libdelorean.statevalue.StateValue;
import com.efficios.jabberwocky.common.TimeRange;
import com.efficios.jabberwocky.lttng.kernel.analysis.os.Attributes;
import com.efficios.jabberwocky.lttng.kernel.analysis.os.KernelAnalysis;
import com.efficios.jabberwocky.views.common.FlatUIColors;
import com.efficios.jabberwocky.views.timegraph.model.provider.statesystem.StateSystemModelArrowProvider;
import com.efficios.jabberwocky.views.timegraph.model.render.TimeGraphEvent;
import com.efficios.jabberwocky.views.timegraph.model.render.arrows.TimeGraphArrow;
import com.efficios.jabberwocky.views.timegraph.model.render.arrows.TimeGraphArrowRender;
import com.efficios.jabberwocky.views.timegraph.model.render.arrows.TimeGraphArrowSeries;
import com.efficios.jabberwocky.views.timegraph.model.render.arrows.TimeGraphArrowSeries.LineStyle;
import com.efficios.jabberwocky.views.timegraph.model.render.tree.TimeGraphTreeElement;
import com.efficios.jabberwocky.views.timegraph.model.render.tree.TimeGraphTreeRender;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Ints;
import org.jetbrains.annotations.Nullable;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.FutureTask;

import static java.util.Objects.requireNonNull;

public class ThreadsModelArrowProviderCpus extends StateSystemModelArrowProvider {

    private static final TimeGraphArrowSeries ARROW_SERIES = new TimeGraphArrowSeries(
            requireNonNull(Messages.arrowSeriesCPUs), FlatUIColors.RED, LineStyle.FULL);

    public ThreadsModelArrowProviderCpus() {
        super(ARROW_SERIES, KernelAnalysis.instance());
    }

    @Override
    public TimeGraphArrowRender getArrowRender(TimeGraphTreeRender treeRender, TimeRange timeRange,
            @Nullable FutureTask<?> task) {
        IStateSystemReader ss = getStateSystem();
        if (ss == null) {
            return TimeGraphArrowRender.EMPTY_RENDER;
        }

        List<Integer> threadLineQuarks = ss.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
        List<List<TimeGraphArrow>> allArrows = new LinkedList<>();
        try {
            for (int threadLineQuark : threadLineQuarks) {
                List<StateInterval> intervals = StateSystemUtils.queryHistoryRange(ss, threadLineQuark,
                        timeRange.getStartTime(), timeRange.getEndTime(), 1, task);
                if (task != null && task.isCancelled()) {
                    return TimeGraphArrowRender.EMPTY_RENDER;
                }
                if (intervals.size() < 2) {
                    /* Not enough states to establish a timeline */
                    continue;
                }

                String cpuName = ss.getAttributeName(ss.getParentAttributeQuark(threadLineQuark));
                Integer cpu = Ints.tryParse(cpuName);
                List<TimeGraphArrow> arrows = getArrowsFromStates(treeRender, intervals, cpu);
                allArrows.add(arrows);
            }

        } catch (AttributeNotFoundException | StateSystemDisposedException e) {
            e.printStackTrace();
            return TimeGraphArrowRender.EMPTY_RENDER;
        }

        Iterable<TimeGraphArrow> flattenedArrows = Iterables.concat(allArrows);
        return new TimeGraphArrowRender(timeRange, flattenedArrows);
    }

    private List<TimeGraphArrow> getArrowsFromStates(TimeGraphTreeRender treeRender,
            List<StateInterval> threadTimeline, @Nullable Integer cpu) {
        List<TimeGraphArrow> arrows = new LinkedList<>();
        for (int i = 1; i < threadTimeline.size(); i++) {
            StateInterval interval1 = threadTimeline.get(i - 1);
            StateInterval interval2 = threadTimeline.get(i);

            StateValue sv1 = interval1.getStateValue();
            StateValue sv2 = interval2.getStateValue();

            if (!(sv1 instanceof IntegerStateValue) || !(sv2 instanceof IntegerStateValue)) {
                continue;
            }

            int thread1 = ((IntegerStateValue) sv1).getValue();
            int thread2 = ((IntegerStateValue) sv2).getValue();

            if (thread1 == -1 || thread2 == -1) {
                /* No arrow to draw here */
                continue;
            }

            TimeGraphTreeElement startTreeElem = getTreeElementFromThread(treeRender, thread1, cpu);
            TimeGraphTreeElement endTreeElem = getTreeElementFromThread(treeRender, thread2, cpu);
            TimeGraphEvent startEvent = new TimeGraphEvent(interval1.getEnd(), startTreeElem);
            TimeGraphEvent endEvent = new TimeGraphEvent(interval2.getStart(), endTreeElem);

            TimeGraphArrow arrow = new TimeGraphArrow(startEvent, endEvent, getArrowSeries());
            arrows.add(arrow);
        }
        return arrows;
    }

    private static TimeGraphTreeElement getTreeElementFromThread(TimeGraphTreeRender treeRender, int tid,
            @Nullable Integer cpu) {
        if (tid != 0) {
            // FIXME Could be improved via indexing, to avoid iterating the
            // whole array for every single tid.
            return Iterables.find(treeRender.getAllTreeElements(), treeElem -> {
                if (!(treeElem instanceof ThreadsTreeElement)) {
                    return false;
                }
                ThreadsTreeElement cfvTreeElem = (ThreadsTreeElement) treeElem;
                return (cfvTreeElem.getTid() == tid);
            });
        }
        if (cpu == null) {
            throw new IllegalStateException();
        }
        String prefix = "0/" + cpu.toString(); //$NON-NLS-1$
        return Iterables.find(treeRender.getAllTreeElements(), treeElem -> {
            if (!(treeElem instanceof ThreadsTreeElement)) {
                return false;
            }
            ThreadsTreeElement cfvTreeElem = (ThreadsTreeElement) treeElem;
            return cfvTreeElem.getName().startsWith(prefix);
        });
    }
}