Skip to content

Commit

Permalink
linux: Move SWSLatency analysis to Trace Compass core
Browse files Browse the repository at this point in the history
The SWSLatency computes the latency between the sched_wakeup event and
the sched_switch event for each thread. It is a subclass of
AbstractSegmentStoreAnalysisEventBasedModule.

This commit moves the SWSLatency analysis from the incubator to Trace
Compass core by copying the necessary files from
org.eclipse.tracecompass.incubator.internal.kernel.core.swslatency to
org.eclipse.tracecompass.analysis.os.linux.core.swslatency and making
necessary changes to existing configuration files. It also moves unit
tests for the analysis to Trace Compass core.

To test the analysis:

[1] Run the unit tests in
org.eclipse.tracecompass.analysis.os.linux.core.tests.swslatency
as J-unit plug-in tests. Confirm that they all pass. The goal is to test
that the analysis runs and provides expected output.
[2] Run the unit tests in
org.eclipse.tracecompass.integration.core.tests.dataproviders
as J-unit plug-in tests. Confirm that they all pass. Adding the new
analysis generates new DataProviderDescriptor(s). This is to make sure
that the existing test in this package is updated.
[3] Open Trace Compass. Open a kernel trace. Make sure that the
Scheduler Wakeup to Scheduler Switch Latency analysis is visible and not
crossed out under Views in the Project Explorer. It is normal to have no
output under the analysis because they are not yet included in this
commit. This is required to make sure that the analysis is exposed to
users in the UI of the Trace Compass application.

To be done in subsequent patches:

[1] Migrate outputs of the SWSLatency analysis
[2] Renaming the SWSLatency analysis to
SchedulerWakeupToSchedulerSwitchLatency to make the name of the analysis
easier to understand
[3] Add documentation
[4] Deprecate the SWSLatency analysis in the incubator

[Added] SWSLatency (SchedulerWakeupToSchedulerSwitchLatency) analysis

Change-Id: I7e105c4bae2042fd230d43eee9e97972113b8529
Signed-off-by: Hoang Thuan Pham <hoang.pham@calian.ca>
Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/203530
Tested-by: Marco Miller <marco.miller@ericsson.com>
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Reviewed-by: Marco Miller <marco.miller@ericsson.com>
  • Loading branch information
hoangphamEclipse authored and marco-miller committed Aug 15, 2023
1 parent 121f90e commit 37f9cf2
Show file tree
Hide file tree
Showing 12 changed files with 858 additions and 2 deletions.
@@ -0,0 +1,142 @@
/*******************************************************************************
* Copyright (c) 2021 É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.analysis.os.linux.core.tests.swslatency;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.analysis.os.linux.core.swslatency.SWSLatencyAnalysis;
import org.eclipse.tracecompass.analysis.os.linux.core.swslatency.SchedWS;
import org.eclipse.tracecompass.analysis.os.linux.core.swslatency.SchedWS.InitialInfo;
import org.eclipse.tracecompass.analysis.os.linux.core.tests.Activator;
import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.trace.TmfXmlKernelTraceStub;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.common.collect.ImmutableList;

/**
* Test suite for the {@link SWSLatencyAnalysis} class
*
* @author Abdellah Rahmani
*/
public class SWSLatencyTest {

private static final String SWS_USAGE_FILE = "testfiles/sws_analysis.xml";
private IKernelTrace fTrace;
private SWSLatencyAnalysis fModule;

private static void deleteSuppFiles(ITmfTrace trace) {
/* Remove supplementary files */
if (trace != null) {
File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
for (File file : suppDir.listFiles()) {
file.delete();
}
}
}

/**
* Setup the trace for the tests
*/
@Before
public void setUp() {
IKernelTrace trace = new TmfXmlKernelTraceStub();
IPath filePath = Activator.getAbsoluteFilePath(SWS_USAGE_FILE);
IStatus status = trace.validate(null, filePath.toOSString());
if (!status.isOK()) {
fail(status.getException().getMessage());
}
try {
trace.initTrace(null, filePath.toOSString(), TmfEvent.class);
} catch (TmfTraceException e) {
fail(e.getMessage());
}
deleteSuppFiles(trace);
((TmfTrace) trace).traceOpened(new TmfTraceOpenedSignal(this, trace, null));
fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, SWSLatencyAnalysis.class, SWSLatencyAnalysis.ID);
assertNotNull(fModule);
fModule.schedule();
fModule.waitForCompletion();
fTrace = trace;
}

/**
* Dispose everything
*/
@After
public void cleanup() {
ITmfTrace testTrace = fTrace;
if (testTrace != null) {
testTrace.dispose();
}
}

/**
* This will load the analysis and test it. as it depends on Kernel, this
* test runs the kernel trace first then the analysis
*/
@SuppressWarnings("null")
@Test
public void testSmallTraceSequential() {
SWSLatencyAnalysis swsModule = fModule;
assertNotNull(swsModule);
ISegmentStore<@NonNull ISegment> segmentStore = swsModule.getSegmentStore();
assertNotNull(segmentStore);
assertEquals(false, segmentStore.isEmpty());
assertEquals(5, segmentStore.size());

List<InitialInfo> info = ImmutableList.of(new InitialInfo(0, "proc1", 2), new InitialInfo(3, "proc3", 3),
new InitialInfo(6, "proc4", 4), new InitialInfo(10, "proc1", 1), new InitialInfo(3, "proc2", 2));
List<SchedWS> expected = ImmutableList.of(new SchedWS(info.get(0), 1, 20), new SchedWS(info.get(1), 5, 0),
new SchedWS(info.get(2), 10, 20), new SchedWS(info.get(3), 15, 20), new SchedWS(info.get(4), 25, 20));

Iterator<ISegment> it = segmentStore.iterator();
for (int i = 0; i < expected.size(); i++) {
if (it.hasNext()) {
SchedWS segment = (SchedWS) it.next();
long startTime = expected.get(i).getStart();
long endTime = expected.get(i).getEnd();
long duration = expected.get(i).getLength();
int threadID = expected.get(i).getTid();
int priority = expected.get(i).getPriority();
String name = expected.get(i).getName();

assertEquals("Start time of the segment " + i, startTime, segment.getStart());
assertEquals("End time of the segment " + i, endTime, segment.getEnd());
assertEquals("Duration of the segment " + i, duration, segment.getLength());
assertEquals("TID in segment " + i, threadID, segment.getTid());
assertEquals("Priority of the process in segment " + i, priority, segment.getPriority());
assertEquals("Name of the process in segment " + i, name, segment.getName());
}
}
}
}
@@ -0,0 +1,132 @@
<!--*******************************************************************************
* Copyright (c) 2021 É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
*******************************************************************************-->

<trace>
<set_aspects>
<field name="cpu" value="1" type="int" />
</set_aspects>
<event timestamp="0" name="sched_wakeup">
<field name="cpu" value="0" type="int" />
<field name="comm" value="proc1" type="string" />
<field name="tid" value="2" type="long" />
<field name="prio" value="20" type="long" />
</event>
<event timestamp="1" name="sched_switch">
<field name="cpu" value="0" type="int" />
<field name="prev_comm" value="proc1" type="string" />
<field name="prev_tid" value="1" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc2" type="string" />
<field name="next_tid" value="2" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="2" name="sched_switch">
<field name="cpu" value="1" type="int" />
<field name="prev_comm" value="proc3" type="string" />
<field name="prev_tid" value="3" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc4" type="string" />
<field name="next_tid" value="4" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="3" name="sched_wakeup">
<field name="cpu" value="0" type="int" />
<field name="comm" value="proc3" type="string" />
<field name="tid" value="3" type="long" />
<field name="prio" value="0" type="long" />
</event>
<event timestamp="3" name="sched_wakeup">
<field name="cpu" value="0" type="int" />
<field name="comm" value="proc2" type="string" />
<field name="tid" value="2" type="long" />
<field name="prio" value="20" type="long" />
</event>
<event timestamp="5" name="sched_switch">
<field name="cpu" value="1" type="int" />
<field name="prev_comm" value="proc4" type="string" />
<field name="prev_tid" value="4" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc3" type="string" />
<field name="next_tid" value="3" type="long" />
<field name="next_prio" value="0" type="long" />
</event>
<event timestamp="6" name="sched_wakeup">
<field name="cpu" value="0" type="int" />
<field name="comm" value="proc4" type="string" />
<field name="tid" value="4" type="long" />
<field name="prio" value="20" type="long" />
</event>
<event timestamp="10" name="sched_wakeup">
<field name="cpu" value="0" type="int" />
<field name="comm" value="proc1" type="string" />
<field name="tid" value="1" type="long" />
<field name="prio" value="20" type="long" />
</event>
<event timestamp="10" name="sched_switch">
<field name="cpu" value="1" type="int" />
<field name="prev_comm" value="proc3" type="string" />
<field name="prev_tid" value="3" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc4" type="string" />
<field name="next_tid" value="4" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="15" name="sched_switch">
<field name="cpu" value="1" type="int" />
<field name="prev_comm" value="proc4" type="string" />
<field name="prev_tid" value="4" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc1" type="string" />
<field name="next_tid" value="1" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="20" name="sched_switch">
<field name="cpu" value="1" type="int" />
<field name="prev_comm" value="proc1" type="string" />
<field name="prev_tid" value="1" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc4" type="string" />
<field name="next_tid" value="4" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="20" name="sched_switch">
<field name="cpu" value="0" type="int" />
<field name="prev_comm" value="proc2" type="string" />
<field name="prev_tid" value="2" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc3" type="string" />
<field name="next_tid" value="3" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="25" name="sched_switch">
<field name="cpu" value="0" type="int" />
<field name="prev_comm" value="proc3" type="string" />
<field name="prev_tid" value="3" type="long" />
<field name="prev_prio" value="20" type="long" />
<field name="prev_state" value="0" type="long" />
<field name="next_comm" value="proc2" type="string" />
<field name="next_tid" value="2" type="long" />
<field name="next_prio" value="20" type="long" />
</event>
<event timestamp="30" name="sched_wakeup">
<field name="cpu" value="0" type="int" />
<field name="comm" value="proc1" type="string" />
<field name="tid" value="1" type="long" />
<field name="prio" value="20" type="long" />
</event>
</trace>
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
Bundle-Version: 8.0.0.qualifier
Bundle-Version: 8.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 Expand Up @@ -36,6 +36,7 @@ Export-Package: org.eclipse.tracecompass.analysis.os.linux.core.contextswitch,
org.eclipse.tracecompass.analysis.os.linux.core.memory,
org.eclipse.tracecompass.analysis.os.linux.core.model,
org.eclipse.tracecompass.analysis.os.linux.core.signals,
org.eclipse.tracecompass.analysis.os.linux.core.swslatency,
org.eclipse.tracecompass.analysis.os.linux.core.tid,
org.eclipse.tracecompass.analysis.os.linux.core.trace,
org.eclipse.tracecompass.internal.analysis.os.linux.core;x-internal:=true,
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -25,5 +25,6 @@ analysis.kernelmemory = Kernel memory usage
analysis.io = Input/Output
analysis.tid = Active Thread
analysis.execgraph = OS Execution Graph
analysis.swsLatency.wakeupswitch = Scheduler Wakeup to Scheduler Switch Latency

extensionpoint.graphhandler.name = Operating System Graph Handler
extensionpoint.graphhandler.name = Operating System Graph Handler
Expand Up @@ -88,6 +88,18 @@
class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace">
</tracetype>
</module>
<module
analysis_module="org.eclipse.tracecompass.analysis.os.linux.core.swslatency.SWSLatencyAnalysis"
applies_experiment="false"
automatic="false"
icon="icons/swslatency.png"
id="org.eclipse.tracecompass.analysis.os.linux.core.swslatency.sws"
name="%analysis.swsLatency.wakeupswitch">
<tracetype
applies="true"
class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace">
</tracetype>
</module>
<tracetype
applies="true"
class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace"
Expand Down
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2021 É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.analysis.os.linux.core.swslatency;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.osgi.util.NLS;

/**
* Messages for Sched_Wakeup Sched_switch latency analysis.
*
* @author Abdellah Rahmani
* @since 8.1
*/
public class Messages extends NLS {

private static final String BUNDLE_NAME = "org.eclipse.tracecompass.analysis.os.linux.core.swslatency.messages"; //$NON-NLS-1$

/** Sched_Wakeup/Sched_switch TID aspect help text */
public static @Nullable String SegmentAspectHelpText_SWSTid;

/** Sched_Wakeup/Sched_switch priority aspect help text */
public static @Nullable String SegmentAspectHelpText_SWSPrio;

/** Sched_Wakeup/Sched_switch priority aspect name */
public static @Nullable String SegmentAspectName_SWSPrio;

static {
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}

private Messages() {
}

/**
* Helper method to expose externalized strings as non-null objects.
*/
static String getMessage(@Nullable String msg) {
if (msg == null) {
return StringUtils.EMPTY;
}
return msg;
}
}

0 comments on commit 37f9cf2

Please sign in to comment.