Skip to content

Commit

Permalink
linux: support columns in ThreadStatusDataProvider tree model
Browse files Browse the repository at this point in the history
Add process ID (PID), parent PID (PPID) and thread ID (TID) columns as
part of the ThreadStatusDataProvider. This will be used in the trace
server.

[Added] PID, PPID and TID column in the ThreadStatusDataProvider tree

Signed-off-by: Bernd Hufmann <[email protected]>
  • Loading branch information
bhufmann committed Nov 27, 2024
1 parent 4c5e201 commit 1801704
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
Bundle-Version: 9.0.1.qualifier
Bundle-Version: 9.1.0.qualifier
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.tracecompass.analysis.os.linux.core;singleton:=true
Bundle-Activator: org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,20 @@ public class Messages extends NLS {
/** Label for the parent's thread ID
* @since 4.2*/
public static @Nullable String AspectName_Ptid;
/** Description for the parent's thread ID
* @since 9.1*/
public static @Nullable String AspectHelpText_Ptid;

/**
* String to identify the executable name
* @since 4.1
*/
public static @Nullable String AspectName_ExecName;

/** Description for the exec name
* @since 9.1*/
public static @Nullable String AspectHelpText_ExecName;

public static @Nullable String AspectHelpText_Tid;

public static @Nullable String AspectName_Prio;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ AspectName_Prio=Prio
AspectHelpText_Prio=The priority of the thread this event belongs to

AspectName_ExecName=Exec_Name
AspectHelpText_ExecName=The Exec name of the thread

AspectName_Ptid=PTID
AspectHelpText_Ptid=The ID of the parent thread this event belongs to
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ public static String tid() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectName_Tid);
}

/**
* Description string for the thread ID
*
* @return The externalized description text for thread ID
* @since 9.1
*/
public static String tidDesc() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectHelpText_Tid);
}

/**
* Get the string for the process ID
*
Expand All @@ -52,6 +62,16 @@ public static String pid() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectName_Pid);
}

/**
* Description string for the process ID
*
* @return The externalized description text for process ID
* @since 9.1
*/
public static String pidDesc() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectHelpText_Pid);
}

/**
* Get the string for the parent's thread ID
*
Expand All @@ -62,6 +82,16 @@ public static String ptid() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectName_Ptid);
}

/**
* Description string for the parent thread ID
*
* @return The externalized description text for parent thread ID
* @since 9.1
*/
public static String ptidDesc() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectHelpText_Ptid);
}

/**
* Get the externalized string for the executable name of a thread
*
Expand All @@ -72,4 +102,14 @@ public static String execName() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectName_ExecName);
}

/**
* Description string for the executable name of a thread
*
* @return The externalized label for exec name description
* @since 9.1
*/
public static String execNameDesc() {
return Objects.requireNonNull(org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.Messages.AspectHelpText_ExecName);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.analysis.os.linux.core.model.OsStrings;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.TableColumnDescriptor;
import org.eclipse.tracecompass.tmf.core.model.ITableColumnDescriptor;
import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;

/**
Expand All @@ -34,7 +37,7 @@ public class ThreadEntryModel extends TimeGraphEntryModel {
*/
public static final class Builder {
private final long fId;
private @NonNull List<@NonNull String> fLabels;
private @NonNull String fExecName;
private final long fStartTime;
private long fEndTime;
private final int fTid;
Expand All @@ -46,8 +49,8 @@ public static final class Builder {
*
* @param id
* The unique ID for this Entry model for its trace
* @param labels
* the thread labels
* @param execName
* the exec name
* @param start
* the thread's start time
* @param end
Expand All @@ -61,9 +64,9 @@ public static final class Builder {
* <code>-1</code> can be used. The PID will be assumed to be
* the same as the TID
*/
public Builder(long id, @NonNull List<@NonNull String> labels, long start, long end, int tid, int ppid, int pid) {
public Builder(long id, @NonNull String execName, long start, long end, int tid, int ppid, int pid) {
fId = id;
fLabels = labels;
fExecName = execName;
fStartTime = start;
fEndTime = end;
fTid = tid;
Expand Down Expand Up @@ -113,8 +116,8 @@ public int getPpid() {
* @param name
* the new name
*/
public void setName(@NonNull List<@NonNull String> name) {
fLabels = name;
public void setName(@NonNull String name) {
fExecName = name;
}

/**
Expand Down Expand Up @@ -159,8 +162,13 @@ public void setPid(int pid) {
* {@link NullPointerException} if the parent Id is not set.
*/
public ThreadEntryModel build(long parentId) {
return new ThreadEntryModel(fId, parentId, fLabels, fStartTime, fEndTime, fTid, fPpid, fPid);
@NonNull List<@NonNull String> labels = ImmutableList.of(fExecName,
String.valueOf(fTid),
fPid <= 0 ? String.valueOf(fTid) : String.valueOf(fPid),
fPpid > 0 ? String.valueOf(fPpid) : ""); //$NON-NLS-1$
return new ThreadEntryModel(fId, parentId, labels, fStartTime, fEndTime, fTid, fPpid, fPid);
}

}

private final int fThreadId;
Expand Down Expand Up @@ -203,6 +211,32 @@ public ThreadEntryModel(long id, long parentId, @NonNull List<@NonNull String> l

}

/**
* Get the column descriptors corresponding to the of labels in the ThreadEntryModel
*
* @return list of column descriptor
*/
public static @NonNull List<@NonNull ITableColumnDescriptor> getColumnDescriptors() {
ImmutableList.Builder<@NonNull ITableColumnDescriptor> headers = new ImmutableList.Builder<>();
TableColumnDescriptor.Builder builder = new TableColumnDescriptor.Builder();
builder.setText(OsStrings.execName());
builder.setTooltip(OsStrings.execNameDesc());
headers.add(builder.build());
builder = new TableColumnDescriptor.Builder();
builder.setText(OsStrings.tid());
builder.setTooltip(OsStrings.tidDesc());
headers.add(builder.build());
builder = new TableColumnDescriptor.Builder();
builder.setText(OsStrings.pid());
builder.setTooltip(OsStrings.pidDesc());
headers.add(builder.build());
builder = new TableColumnDescriptor.Builder();
builder.setText(OsStrings.ptid());
builder.setTooltip(OsStrings.ptidDesc());
headers.add(builder.build());
return headers.build();
}

/**
* Gets the entry thread ID
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.eclipse.tracecompass.analysis.os.linux.core.model.OsStrings;
import org.eclipse.tracecompass.analysis.os.linux.core.model.ProcessStatus;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator;
import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.StateValues;
Expand Down Expand Up @@ -200,7 +201,10 @@ public ThreadStatusDataProvider(@NonNull ITmfTrace trace, TmfStateSystemAnalysis
@Override
public @NonNull 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);
TmfTreeModel.Builder<@NonNull TimeGraphEntryModel> treeModelBuilder = new TmfTreeModel.Builder();
treeModelBuilder.setColumnDescriptors(ThreadEntryModel.getColumnDescriptors());
treeModelBuilder.setEntries(filter(Objects.requireNonNull(fTraceEntry), fTidToEntry, fetchParameters));
return new TmfModelResponse<>(treeModelBuilder.build(), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}

fModule.waitForInitialization();
Expand Down Expand Up @@ -242,7 +246,8 @@ public ThreadStatusDataProvider(@NonNull ITmfTrace trace, TmfStateSystemAnalysis
}

// update the trace Entry.
TimeGraphEntryModel traceEntry = new TimeGraphEntryModel(fTraceId, -1, getTrace().getName(), ss.getStartTime(), end);
List<@NonNull String> labels = ImmutableList.of(NonNullUtils.nullToEmptyString(getTrace().getName()), "", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
TimeGraphEntryModel traceEntry = new TimeGraphEntryModel(fTraceId, -1, labels, ss.getStartTime(), end);
fTraceEntry = traceEntry;

for (Integer threadQuark : ss.getQuarks(Attributes.THREADS, WILDCARD)) {
Expand Down Expand Up @@ -276,13 +281,17 @@ public ThreadStatusDataProvider(@NonNull ITmfTrace trace, TmfStateSystemAnalysis
fEntryMetadata.put(model.getId(), model.getMetadata());
}

TmfTreeModel.Builder<@NonNull TimeGraphEntryModel> treeModelBuilder = new TmfTreeModel.Builder();
treeModelBuilder.setColumnDescriptors(ThreadEntryModel.getColumnDescriptors());
treeModelBuilder.setEntries(list);
TmfTreeModel<@NonNull TimeGraphEntryModel> returnModel = treeModelBuilder.build();
if (complete) {
fBuildMap.clear();
fLastEnd = Long.MAX_VALUE;
return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
return new TmfModelResponse<>(returnModel, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}

return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
return new TmfModelResponse<>(returnModel, ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
}
}

Expand All @@ -305,7 +314,7 @@ private void updateEntry(Integer threadQuark, Pair<Integer, Integer> entryKey,

if (entry == null) {
long id = fAtomicLong.getAndIncrement();
entry = new ThreadEntryModel.Builder(id, Collections.singletonList(execName), startTime, endTime, threadId, ppid, pid);
entry = new ThreadEntryModel.Builder(id, execName, startTime, endTime, threadId, ppid, pid);
fQuarkMap.put(id, threadQuark);
} else {
/*
Expand All @@ -314,7 +323,7 @@ private void updateEntry(Integer threadQuark, Pair<Integer, Integer> entryKey,
*/
entry.setEndTime(endTime);
entry.setPpid(ppid);
entry.setName(Collections.singletonList(execName));
entry.setName(execName);
}
fBuildMap.put(entryKey, entry);
fTidToEntry.put(threadId, entry);
Expand Down

0 comments on commit 1801704

Please sign in to comment.