From 2ee89cfc75c5967cbfa4efea2462449715fcbc20 Mon Sep 17 00:00:00 2001 From: Bernd Hufmann Date: Fri, 30 Sep 2022 09:10:27 -0400 Subject: [PATCH] linux: support columns in ThreadStatusDataProvider tree model 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 --- .../META-INF/MANIFEST.MF | 2 +- .../os/linux/core/event/aspect/Messages.java | 7 +++ .../core/event/aspect/messages.properties | 2 + .../os/linux/core/model/OsStrings.java | 40 +++++++++++++++ .../core/threadstatus/ThreadEntryModel.java | 50 ++++++++++++++++--- .../ThreadStatusDataProvider.java | 21 +++++--- 6 files changed, 107 insertions(+), 15 deletions(-) diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF index 5584c4452c..1a85c56724 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/META-INF/MANIFEST.MF @@ -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 diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/Messages.java index 7b62d0eab5..aca6a7a662 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/Messages.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/Messages.java @@ -34,6 +34,9 @@ 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 @@ -41,6 +44,10 @@ public class Messages extends NLS { */ 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; diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/messages.properties index e9d18405b8..a1283a251a 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/messages.properties +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/event/aspect/messages.properties @@ -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 diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/model/OsStrings.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/model/OsStrings.java index 9d7d439770..21b25ed575 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/model/OsStrings.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/model/OsStrings.java @@ -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 * @@ -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 * @@ -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 * @@ -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); + } + } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java index a5af26993a..41d949d04f 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java @@ -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; /** @@ -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; @@ -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 @@ -61,9 +64,9 @@ public static final class Builder { * -1 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; @@ -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; } /** @@ -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; @@ -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 * diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java index 82f294d4fd..e907d3f0b3 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java @@ -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; @@ -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(); @@ -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)) { @@ -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); } } @@ -305,7 +314,7 @@ private void updateEntry(Integer threadQuark, Pair 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 { /* @@ -314,7 +323,7 @@ private void updateEntry(Integer threadQuark, Pair entryKey, */ entry.setEndTime(endTime); entry.setPpid(ppid); - entry.setName(Collections.singletonList(execName)); + entry.setName(execName); } fBuildMap.put(entryKey, entry); fTidToEntry.put(threadId, entry);