Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lttng-ust: Add cpu analysis to be able to query the callsite statesystem
This analysis is needed because the callsite state system cannot be queried by a data provider if the user only has a ust trace. [Added] UstCpuAnalysisModule and UstCpuStateProvider Change-Id: I0f161ce4847c59b8dc7239482d6e0c3fc247cf27 Signed-off-by: Arnaud Fiorini <fiorini.arnaud@gmail.com> Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/188705 Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org> Tested-by: Marco Miller <marco.miller@ericsson.com> Reviewed-by: Marco Miller <marco.miller@ericsson.com>
- Loading branch information
1 parent
154bd2e
commit aaed95b
Showing
6 changed files
with
321 additions
and
1 deletion.
There are no files selected for viewing
164 changes: 164 additions & 0 deletions
164
...org/eclipse/tracecompass/lttng2/ust/core/tests/analysis/cpu/UstCpuAnalysisModuleTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/******************************************************************************* | ||
* 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.lttng2.ust.core.tests.analysis.cpu; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.assertTrue; | ||
import static org.junit.Assert.fail; | ||
|
||
import java.util.List; | ||
import java.util.stream.StreamSupport; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; | ||
import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.cpu.UstCpuAnalysisModule; | ||
import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.cpu.UstCpuStateProvider; | ||
import org.eclipse.tracecompass.lttng2.ust.core.tests.shared.LttngUstTestTraceUtils; | ||
import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace; | ||
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; | ||
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | ||
import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | ||
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; | ||
import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace; | ||
import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement; | ||
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; | ||
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Tests for the {@link UstCpuAnalysisModule} | ||
* | ||
* @author Arnaud Fiorini | ||
*/ | ||
public class UstCpuAnalysisModuleTest { | ||
|
||
private static final @NonNull CtfTestTrace TRACE_WITHOUT_VTID = CtfTestTrace.DEBUG_INFO4; | ||
private static final @NonNull CtfTestTrace TRACE_WITH_VTID = CtfTestTrace.CYG_PROFILE; | ||
|
||
private UstCpuAnalysisModule fModule; | ||
|
||
/** | ||
* Test setup | ||
*/ | ||
@Before | ||
public void setup() { | ||
fModule = new UstCpuAnalysisModule(); | ||
} | ||
|
||
/** | ||
* Test cleanup | ||
*/ | ||
@After | ||
public void tearDown() { | ||
fModule.dispose(); | ||
fModule = null; | ||
} | ||
|
||
/** | ||
* Test for {@link UstCpuAnalysisModule#getAnalysisRequirements()} | ||
*/ | ||
@Test | ||
public void testGetAnalysisRequirements() { | ||
Iterable<TmfAbstractAnalysisRequirement> requirements = fModule.getAnalysisRequirements(); | ||
assertNotNull(requirements); | ||
assertEquals(1, StreamSupport.stream(requirements.spliterator(), false).count()); | ||
} | ||
|
||
/** | ||
* Test that the analysis can execute on a valid trace. | ||
*/ | ||
@Test | ||
public void testCanExecute() { | ||
LttngUstTrace trace = LttngUstTestTraceUtils.getTrace(TRACE_WITH_VTID); | ||
assertTrue(fModule.canExecute(trace)); | ||
LttngUstTestTraceUtils.dispose(TRACE_WITH_VTID); | ||
} | ||
|
||
/** | ||
* Test that the analysis correctly refuses to execute on a trace that does | ||
* not provide vtid. | ||
*/ | ||
@Test | ||
public void testCannotExcecute() { | ||
LttngUstTrace invalidTrace = LttngUstTestTraceUtils.getTrace(TRACE_WITHOUT_VTID); | ||
assertFalse(fModule.canExecute(invalidTrace)); | ||
LttngUstTestTraceUtils.dispose(TRACE_WITHOUT_VTID); | ||
} | ||
|
||
private void executeModule(@NonNull ITmfTrace trace) { | ||
try { | ||
fModule.setTrace(trace); | ||
} catch (TmfAnalysisException e) { | ||
fail(); | ||
} | ||
fModule.schedule(); | ||
fModule.waitForCompletion(); | ||
} | ||
|
||
/** | ||
* Test that basic execution of the module works well. | ||
*/ | ||
@Test | ||
public void testExecution() { | ||
LttngUstTrace trace = LttngUstTestTraceUtils.getTrace(TRACE_WITH_VTID); | ||
executeModule(trace); | ||
ITmfStateSystem ss = fModule.getStateSystem(); | ||
assertNotNull(ss); | ||
LttngUstTestTraceUtils.dispose(TRACE_WITH_VTID); | ||
} | ||
|
||
/** | ||
* Test that the state system generated is correct. | ||
*/ | ||
@Test | ||
public void testGetCpuForThread() { | ||
LttngUstTrace trace = LttngUstTestTraceUtils.getTrace(TRACE_WITH_VTID); | ||
executeModule(trace); | ||
ITmfStateSystem ss = fModule.getStateSystem(); | ||
assertNotNull(ss); | ||
|
||
// Test threads quark exists | ||
int parentThreadsQuark = -1; | ||
try { | ||
parentThreadsQuark = ss.getQuarkAbsolute(UstCpuStateProvider.THREADS); | ||
} catch (AttributeNotFoundException e) { | ||
fail(); | ||
} | ||
|
||
// Test that there is the correct number of threads | ||
List<@NonNull Integer> threadsQuarks = ss.getSubAttributes(parentThreadsQuark, false); | ||
assertEquals(1, threadsQuarks.size()); | ||
|
||
// Test that at multiple specific time the cpu value is correct | ||
Integer threadQuark = threadsQuarks.iterator().next(); | ||
try { | ||
// End of the trace | ||
ITmfStateInterval cpuState = ss.querySingleState(ss.getCurrentEndTime(), threadQuark); | ||
assertNotNull(cpuState.getValue()); | ||
assertEquals(3, cpuState.getValue()); | ||
// Beginning of the trace | ||
cpuState = ss.querySingleState(ss.getStartTime(), threadQuark); | ||
assertNotNull(cpuState.getValue()); | ||
assertEquals(0, cpuState.getValue()); | ||
// Middle of the trace | ||
cpuState = ss.querySingleState(ss.getStartTime() + (ss.getCurrentEndTime() - ss.getStartTime()) / 2, threadQuark); | ||
assertNotNull(cpuState.getValue()); | ||
assertEquals(3, cpuState.getValue()); | ||
} catch (StateSystemDisposedException e) { | ||
fail(); | ||
} | ||
LttngUstTestTraceUtils.dispose(TRACE_WITH_VTID); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
.../org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/cpu/UstCpuAnalysisModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/******************************************************************************* | ||
* 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.internal.lttng2.ust.core.analysis.cpu; | ||
|
||
import java.util.Collections; | ||
import java.util.Objects; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; | ||
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.ContextVtidAspect; | ||
import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace; | ||
import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement; | ||
import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement.PriorityLevel; | ||
import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; | ||
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | ||
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
|
||
/** | ||
* This analysis builds a state system from the cpu | ||
* | ||
* @author Arnaud Fiorini | ||
*/ | ||
public class UstCpuAnalysisModule extends TmfStateSystemAnalysisModule { | ||
|
||
/** | ||
* Analysis ID, it should match that in the plugin.xml file | ||
*/ | ||
public static final @NonNull String ID = "org.eclipse.linuxtools.lttng2.ust.analysis.cpu"; //$NON-NLS-1$ | ||
|
||
private static final @NonNull TmfAbstractAnalysisRequirement VTID_ASPECT_REQUIREMENT = new TmfAbstractAnalysisRequirement( | ||
Collections.emptySet(), PriorityLevel.MANDATORY) { | ||
@Override | ||
public boolean test(ITmfTrace trace) { | ||
if (trace instanceof LttngUstTrace) { | ||
Iterable<@NonNull ITmfEventAspect<?>> eventAspects = TmfTraceUtils.getEventAspects(trace, ContextVtidAspect.class); | ||
return eventAspects.iterator().hasNext(); | ||
} | ||
return false; | ||
} | ||
}; | ||
|
||
@Override | ||
public ITmfStateProvider createStateProvider() { | ||
return new UstCpuStateProvider(Objects.requireNonNull(getTrace())); | ||
} | ||
|
||
@Override | ||
public Iterable<TmfAbstractAnalysisRequirement> getAnalysisRequirements() { | ||
return ImmutableSet.of(VTID_ASPECT_REQUIREMENT); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
...c/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/cpu/UstCpuStateProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/******************************************************************************* | ||
* 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.internal.lttng2.ust.core.analysis.cpu; | ||
|
||
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; | ||
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.ContextVtidAspect; | ||
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; | ||
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | ||
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | ||
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; | ||
import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; | ||
|
||
/** | ||
* Creates a state system with a quark for each thread describing which CPU is | ||
* in use. | ||
* | ||
* This state system is useful to get the CPU number in analysis of LTTng UST | ||
* traces. More specifically, to get callsite information or other analyses. | ||
* | ||
* Attribute tree: | ||
* | ||
* <pre> | ||
* |- Threads | ||
* | |- <TID> -> CPU number for this TID depending on LTTng UST events | ||
* </pre> | ||
* | ||
* @author Arnaud Fiorini | ||
*/ | ||
public class UstCpuStateProvider extends AbstractTmfStateProvider { | ||
|
||
/** | ||
* State system ID | ||
*/ | ||
public static final @NonNull String ID = "org.eclipse.linuxtools.lttng2.ust.analysis.cpu.stateprovider"; //$NON-NLS-1$ | ||
|
||
/** State system attribute name for the Threads to CPU mappings */ | ||
public static final String THREADS = "Threads"; //$NON-NLS-1$ | ||
|
||
/** | ||
* @param trace | ||
* the trace to build the state system | ||
*/ | ||
public UstCpuStateProvider(@NonNull ITmfTrace trace) { | ||
super(trace, ID); | ||
} | ||
|
||
@Override | ||
public int getVersion() { | ||
return 0; | ||
} | ||
|
||
@Override | ||
public @NonNull ITmfStateProvider getNewInstance() { | ||
return new UstCpuStateProvider(getTrace()); | ||
} | ||
|
||
@Override | ||
protected void eventHandle(@NonNull ITmfEvent event) { | ||
ITmfStateSystemBuilder ssb = checkNotNull(getStateSystemBuilder()); | ||
CtfTmfEvent ctfEvent = (CtfTmfEvent) event; | ||
int cpuId = ctfEvent.getCPU(); | ||
Object vtid = TmfTraceUtils.resolveEventAspectOfClassForEvent(getTrace(), ContextVtidAspect.class, event); | ||
if (vtid != null) { | ||
int threadQuark = ssb.getQuarkAbsoluteAndAdd(THREADS, vtid.toString()); | ||
ssb.modifyAttribute(event.getTimestamp().getValue(), cpuId, threadQuark); | ||
} | ||
} | ||
} |