Skip to content

Commit

Permalink
OTF2: Create generic class representing a SystemTreeNode
Browse files Browse the repository at this point in the history
Added a generic class representing system tree nodes. This class can be
inherited by the different OTF2 analyzes that use the system
architecture. With this class, some recurrent functions related to
system tree nodes do not need to be duplicated in these analyzes.

Also changed the callstack state provider so it makes use of this new
class.

Signed-off-by: yoann-heitz <yoann.heitz@polymtl.ca>
Change-Id: Ic62bc6ed55dd180adf7f92922d93996446e2c5cc
Reviewed-on: https://git.eclipse.org/r/c/tracecompass.incubator/org.eclipse.tracecompass.incubator/+/190902
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Marco Miller <marco.miller@ericsson.com>
  • Loading branch information
yoann-heitz authored and marco-miller committed May 19, 2022
1 parent a4f2697 commit dc98dab
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 56 deletions.
Expand Up @@ -237,4 +237,37 @@ public static CollectiveOperation getOperation(int operationCode) {
return CollectiveOperation.UNKNOWN_OPERATION;
}
}
}

/**
* long constant representing OTF2 undefined uint32 value
*/
long OTF2_UNDEFINED_UINT32 = (1L << 32) - 1;

/**
* In the following lines, undefined and unknown constants are defined for
* the different OTF2 references.
*
* The undefined constants should be used when no issues occurred while
* reading a reference field but when the reference value is the undefined
* value in the OTF2 standards.
*
* The unknown constants should be used when an issue occurred while reading
* a reference but a default value should be used to continue to process the
* trace.
*/

/**
* Constant representing an unknown string reference.
*/
long OTF2_UNKNOWN_STRING = OTF2_UNDEFINED_UINT32;

/**
* Constant representing an undefined system tree node reference.
*/
long OTF2_UNDEFINED_SYSTEM_TREE_NODE = OTF2_UNDEFINED_UINT32;

/**
* Constant representing an unknown system tree node reference.
*/
long OTF2_UNKNOWN_SYSTEM_TREE_NODE = OTF2_UNDEFINED_UINT32;
}
Expand Up @@ -11,33 +11,34 @@

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

import java.util.Map;
import java.util.Queue;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread;
import org.eclipse.tracecompass.incubator.callstack.core.base.EdgeStateValue;
import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.AbstractOtf2StateProvider;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Constants;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Events;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Fields;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2GlobalDefinitions;
import org.eclipse.tracecompass.incubator.internal.otf2.core.mpi.AllToRootIdentifiers;
import org.eclipse.tracecompass.incubator.internal.otf2.core.mpi.MessageIdentifiers;
import org.eclipse.tracecompass.incubator.internal.otf2.core.mpi.RootToAllIdentifiers;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.AbstractOtf2StateProvider;
import org.eclipse.tracecompass.incubator.internal.otf2.core.trace.SystemTreeNode;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;

/**
* Main state provider that defines the enter/leave states
Expand All @@ -53,16 +54,6 @@ public class Otf2CallStackStateProvider extends AbstractOtf2StateProvider {
*/
public static final String PROCESSES = "Processes"; //$NON-NLS-1$

/**
* Whitespace string
*/
public static final String WHITESPACE = " "; //$NON-NLS-1$

/**
* Long representing the maximum value for a 32-bits unsigned integer
*/
protected static final long MAX_UINT32 = (1L << 32) - 1;

/**
* A class representing a node from the system tree. It is used to represent
* how the different machines are distributed into a MPI cluster and how the
Expand All @@ -71,26 +62,14 @@ public class Otf2CallStackStateProvider extends AbstractOtf2StateProvider {
* @author Yoann Heitz
*
*/
private class SystemTreeNode {
private final long fParentId;
private final int fNameId;
private final int fClassNameId;
private class CallstackSystemTreeNode extends SystemTreeNode {
private int fSystemTreeNodeQuark;

public SystemTreeNode(long parentId, int nameId, int classNameId) {
fParentId = parentId;
fNameId = nameId;
fClassNameId = classNameId;
public CallstackSystemTreeNode(ITmfEvent event) {
super(event);
fSystemTreeNodeQuark = UNKNOWN_ID;
}

public String getFullName() {
Map<Integer, String> stringIds = getStringId();
String name = stringIds.get(fNameId);
String className = stringIds.get(fClassNameId);
return className + WHITESPACE + name;
}

/*
* The method used to initialize the quark associated to this node. If
* the node ID of the parent of this node is the maximum value for
Expand All @@ -99,20 +78,22 @@ public String getFullName() {
* retrieved and initialized if it was not done before.
*/
public void initializeQuarks(ITmfStateSystemBuilder ssb) {
if (fParentId == MAX_UINT32) {
fSystemTreeNodeQuark = ssb.getQuarkAbsoluteAndAdd(PROCESSES, getFullName());
String fullName = getFullName(getStringId());
long parentId = getParentId();
if (isRootNode()) {
fSystemTreeNodeQuark = ssb.getQuarkAbsoluteAndAdd(PROCESSES, fullName);
} else {
int machineQuark = getSystemTreeNodeQuark(fParentId);
int machineQuark = getSystemTreeNodeQuark(parentId);
if (machineQuark == UNKNOWN_ID) {
SystemTreeNode parentNode = fMapSystemTreeNode.get(fParentId);
CallstackSystemTreeNode parentNode = fMapSystemTreeNode.get(parentId);
if (parentNode == null) {
return;
}
parentNode.initializeQuarks(ssb);
machineQuark = getSystemTreeNodeQuark(fParentId);
machineQuark = getSystemTreeNodeQuark(parentId);
}
if (machineQuark != UNKNOWN_ID) {
fSystemTreeNodeQuark = ssb.getQuarkRelativeAndAdd(machineQuark, getFullName());
fSystemTreeNodeQuark = ssb.getQuarkRelativeAndAdd(machineQuark, fullName);
}
}
}
Expand All @@ -123,7 +104,7 @@ public int getQuark() {
}

private int getSystemTreeNodeQuark(long systemTreeNodeId) {
SystemTreeNode systemTreeNode = fMapSystemTreeNode.get(systemTreeNodeId);
CallstackSystemTreeNode systemTreeNode = fMapSystemTreeNode.get(systemTreeNodeId);
if (systemTreeNode == null) {
return UNKNOWN_ID;
}
Expand Down Expand Up @@ -421,7 +402,7 @@ public void mpiAllToRoot(ITmfEvent srcEvent, ITmfStateSystemBuilder ssb) {
/**
* Mapping tables required for this analysis
*/
private final Map<Long, SystemTreeNode> fMapSystemTreeNode = new HashMap<>();
private final Map<Long, CallstackSystemTreeNode> fMapSystemTreeNode = new HashMap<>();
private final Map<Integer, LocationGroup> fMapLocationGroup = new HashMap<>();
private final Map<Long, Location> fMapLocation = new HashMap<>();
private final Map<MessageIdentifiers, ITmfEvent> fMsgDataEvent = new HashMap<>();
Expand Down Expand Up @@ -513,16 +494,8 @@ private void processLocationGroupDefinition(ITmfEvent event) {
}

private void processSystemTreeNodeDefinition(ITmfEvent event) {
ITmfEventField content = event.getContent();
Long selfReference = content.getFieldValue(Long.class, IOtf2Fields.OTF2_SELF);
Integer nameReference = content.getFieldValue(Integer.class, IOtf2Fields.OTF2_NAME);
Integer classNameReference = content.getFieldValue(Integer.class, IOtf2Fields.OTF2_CLASS_NAME);
Long parentReference = content.getFieldValue(Long.class, IOtf2Fields.OTF2_SYSTEM_TREE_PARENT);
if (selfReference == null || nameReference == null || classNameReference == null || parentReference == null) {
return;
}
SystemTreeNode systemTreeNode = new SystemTreeNode(parentReference, nameReference, classNameReference);
fMapSystemTreeNode.put(selfReference, systemTreeNode);
CallstackSystemTreeNode systemTreeNode = new CallstackSystemTreeNode(event);
fMapSystemTreeNode.put(systemTreeNode.getId(), systemTreeNode);
}

@Override
Expand Down Expand Up @@ -579,7 +552,7 @@ protected void processOtf2Event(ITmfEvent event, String name, ITmfStateSystemBui
* Iterates over all the location and initializes the associated quarks
*/
private void initializeQuarks(ITmfStateSystemBuilder ssb) {
for (SystemTreeNode systemTreeNode : fMapSystemTreeNode.values()) {
for (CallstackSystemTreeNode systemTreeNode : fMapSystemTreeNode.values()) {
systemTreeNode.initializeQuarks(ssb);
}
for (LocationGroup locationGroup : fMapLocationGroup.values()) {
Expand Down
@@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2022 É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 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.incubator.internal.otf2.core.trace;

import static org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Constants.OTF2_UNKNOWN_STRING;
import static org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Constants.OTF2_UNKNOWN_SYSTEM_TREE_NODE;

import java.util.Map;

import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Constants;
import org.eclipse.tracecompass.incubator.internal.otf2.core.analysis.IOtf2Fields;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;

/**
* A generic class representing an OTF2 system tree node (it may be a cluster or
* a physical node for example).
*
* @author Yoann Heitz
*/
public class SystemTreeNode {

private static final String WHITESPACE = " "; //$NON-NLS-1$

private final long fId;
private final long fParentId;
private final long fNameId;
private final long fClassNameId;

/**
* Constructs an instance of a SystemTreeNode based on an ITmfEvent
*
* @param event
* the event that will be parsed
*/
public SystemTreeNode(ITmfEvent event) {
ITmfEventField content = event.getContent();
Long id = content.getFieldValue(Long.class, IOtf2Fields.OTF2_SELF);
fId = id == null ? OTF2_UNKNOWN_SYSTEM_TREE_NODE : id;

Long parentId = content.getFieldValue(Long.class, IOtf2Fields.OTF2_SYSTEM_TREE_PARENT);
fParentId = parentId == null ? OTF2_UNKNOWN_SYSTEM_TREE_NODE : parentId;

Long nameId = content.getFieldValue(Long.class, IOtf2Fields.OTF2_NAME);
fNameId = nameId == null ? OTF2_UNKNOWN_STRING : nameId;

Long classNameId = content.getFieldValue(Long.class, IOtf2Fields.OTF2_CLASS_NAME);
fClassNameId = classNameId == null ? OTF2_UNKNOWN_STRING : classNameId;
}

/**
* A method to get the complete name for this system tree node
*
* @param stringIdMap
* a map containing the associations between the string IDs and
* their actual values
* @return the full name of this system tree node
*/
public String getFullName(Map<Integer, String> stringIdMap) {
String name = stringIdMap.get((int) fNameId);
String className = stringIdMap.get((int) fClassNameId);
return className + WHITESPACE + name;
}

/**
* Gets the ID of the system tree node
*
* @return the ID of this system tree node
*/
public long getId() {
return fId;
}

/**
* Gets the ID of the parent of the system tree node
*
* @return the ID of the parent of this system tree node
*/
public long getParentId() {
return fParentId;
}

/**
* Tests if this node is at the root of the system tree
*
* @return true if this node is root, false else.
*/
public boolean isRootNode() {
return getParentId() == IOtf2Constants.OTF2_UNDEFINED_SYSTEM_TREE_NODE;
}
}
@@ -0,0 +1,12 @@
/*******************************************************************************
* Copyright (c) 2022 É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 2.0 which accompanies
* this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

@org.eclipse.jdt.annotation.NonNullByDefault
package org.eclipse.tracecompass.incubator.internal.otf2.core.trace;

0 comments on commit dc98dab

Please sign in to comment.