Skip to content

Commit

Permalink
callstack: Bring CallGraphAnalysis from Incubator
Browse files Browse the repository at this point in the history
Do so along with the related dependencies. CallGraphAnalysis being
another building block for incubated callstack main-lining in TC core.

Also bring incubated ICalledFunction at this stage, now that its
slightly augmented interface is required by hereby added classes.

For now, bring all these in using the callstack.core package, as a flat
list. The follow-up commits shall refactor the packaging, based on this
whole added content and the relationships.

Have InstrumentedCallStackAnalysis import the sibling profiling.core's
CallStackStateProvider still after this excubation. This is to not
change Incubator's use of the latter in its current
InstrumentedCallStackAnalysis. This added dependency on profiling.core
is to likely be removed once ready to deprecate that plugin. I.e., after
callstack.core becomes ready enough as the new Callstack plugin in TC.

Change-Id: I58c11d0e4c34c1514e5e1e7bbb9fe0f8f53214d2
Signed-off-by: Marco Miller <marco.miller@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/199452
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
  • Loading branch information
marco-miller committed Mar 31, 2023
1 parent fbf1eaa commit c04e58f
Show file tree
Hide file tree
Showing 41 changed files with 5,791 additions and 6 deletions.
Expand Up @@ -11,11 +11,16 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Automatic-Module-Name: org.eclipse.tracecompass.analysis.callstack.core
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional,
org.eclipse.tracecompass.analysis.os.linux.core,
org.eclipse.tracecompass.analysis.profiling.core,
org.eclipse.tracecompass.analysis.timing.core,
org.eclipse.tracecompass.common.core,
org.eclipse.tracecompass.datastore.core,
org.eclipse.tracecompass.segmentstore.core,
org.eclipse.tracecompass.tmf.core
Export-Package: org.eclipse.tracecompass.internal.analysis.callstack.core;x-friends:="org.eclipse.tracecompass.analysis.callstack.core.tests"
Import-Package: com.google.common.annotations,
com.google.common.collect
com.google.common.base,
com.google.common.cache,
com.google.common.collect,
org.apache.commons.lang3
@@ -0,0 +1,182 @@
/*******************************************************************************
* Copyright (c) 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.internal.analysis.callstack.core;

import java.util.Comparator;
import java.util.Objects;

import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;

import com.google.common.collect.Ordering;

/**
* Called Function common class, defines the start, end, depth, parent and
* children. Does not define the symbol
*
* @author Matthew Khouzam
* @author Sonia Farrah
*/
abstract class AbstractCalledFunction implements ICalledFunction {

private static final Comparator<ISegment> COMPARATOR;
static {
/*
* requireNonNull() has to be called separately, or else it breaks the
* type inference.
*/
Comparator<ISegment> comp = Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR).compound(SegmentComparators.INTERVAL_END_COMPARATOR);
COMPARATOR = Objects.requireNonNull(comp);
}

/**
* Serial Version UID
*/
private static final long serialVersionUID = -7585356855392065628L;

protected final long fStart;
protected final long fEnd;
protected long fSelfTime = 0;

private final @Nullable ICalledFunction fParent;
private final int fProcessId;
private final int fThreadId;

private final transient IHostModel fModel;
private transient long fCpuTime = Long.MIN_VALUE;

protected AbstractCalledFunction(long start, long end, int processId, int threadId, @Nullable ICalledFunction parent, IHostModel model) {
if (start > end) {
throw new IllegalArgumentException(Messages.TimeError + "[" + start + "," + end + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
fStart = start;
fEnd = end;
fParent = parent;
// It'll be modified once we add a child to it
fSelfTime = fEnd - fStart;
fProcessId = processId;
fThreadId = threadId;
if (parent instanceof AbstractCalledFunction) {
((AbstractCalledFunction) parent).addChild(this);
}
fModel = model;
}

@Override
public long getStart() {
return fStart;
}

@Override
public long getEnd() {
return fEnd;
}

@Override
public @Nullable ICalledFunction getParent() {
return fParent;
}

@Override
public String getName() {
return NonNullUtils.nullToEmptyString(SymbolAspect.SYMBOL_ASPECT.resolve(this));
}

/**
* Add the child to the segment's children, and subtract the child's
* duration to the duration of the segment so we can calculate its self
* time.
*
* @param child
* The child to add to the segment's children
*/
protected void addChild(ICalledFunction child) {
if (child.getParent() != this) {
throw new IllegalArgumentException("Child parent not the same as child being added to."); //$NON-NLS-1$
}
substractChildDuration(child.getEnd() - child.getStart());
}

/**
* Subtract the child's duration to the duration of the segment.
*
* @param childDuration
* The child's duration
*/
private void substractChildDuration(long childDuration) {
fSelfTime -= childDuration;
}

@Override
public long getSelfTime() {
return fSelfTime;
}

@Override
public long getCpuTime() {
long cpuTime = fCpuTime;
if (cpuTime == Long.MIN_VALUE) {
cpuTime = fModel.getCpuTime(fThreadId, fStart, fEnd);
fCpuTime = cpuTime;
}
return cpuTime;
}

@Override
public int getProcessId() {
return fProcessId;
}

@Override
public int getThreadId() {
return fThreadId;
}

@Override
public int compareTo(@Nullable ISegment o) {
if (o == null) {
throw new IllegalArgumentException();
}
return COMPARATOR.compare(this, o);
}

@Override
public String toString() {
return '[' + String.valueOf(fStart) + ", " + String.valueOf(fEnd) + ']' + " Duration: " + getLength() + ", Self Time: " + fSelfTime; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}

@Override
public int hashCode() {
return Objects.hash(fEnd, fParent, fSelfTime, fStart, getSymbol());
}

@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AbstractCalledFunction other = (AbstractCalledFunction) obj;
return (fEnd == other.fEnd &&
fSelfTime == other.fSelfTime &&
fStart == other.fStart &&
Objects.equals(fParent, other.getParent()) &&
Objects.equals(getSymbol(), other.getSymbol()));
}
}

0 comments on commit c04e58f

Please sign in to comment.