Commit | Line | Data |
---|---|---|
d8e841d9 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | *******************************************************************************/ | |
9 | ||
10 | package org.eclipse.tracecompass.analysis.os.linux.core.tid; | |
11 | ||
12 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; | |
13 | ||
14 | import java.util.Collections; | |
15 | import java.util.Set; | |
16 | ||
17 | import org.eclipse.jdt.annotation.NonNull; | |
18 | import org.eclipse.jdt.annotation.Nullable; | |
19 | import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule; | |
1668baa9 | 20 | import org.eclipse.tracecompass.analysis.os.linux.core.trace.DefaultEventLayout; |
d8e841d9 MK |
21 | import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout; |
22 | import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace; | |
23 | import org.eclipse.tracecompass.common.core.NonNullUtils; | |
24 | import org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator; | |
25 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; | |
26 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | |
27 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
28 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; | |
29 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; | |
30 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type; | |
31 | import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement; | |
32 | import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | |
33 | import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; | |
34 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
35 | ||
36 | /** | |
37 | * Active tid analysis module, this only does one thing: figure out the active | |
38 | * tid on any given cpu. This analysis should be approx 10x faster than the full | |
39 | * {@link KernelAnalysisModule}. | |
40 | * | |
41 | * Note: this module exists as a way to accelerate the TID aspect, but also to | |
42 | * start splitting up the kernel analysis into smaller sections. | |
43 | * | |
44 | * @author Matthew Khouzam | |
45 | * @since 2.0 | |
46 | */ | |
47 | public class TidAnalysisModule extends TmfStateSystemAnalysisModule { | |
48 | ||
49 | /** The ID of this analysis module */ | |
50 | public static final @NonNull String ID = "org.eclipse.tracecompass.analysis.os.linux.kernel.tid"; //$NON-NLS-1$ | |
51 | ||
52 | /** The requirements as an immutable set */ | |
53 | private static final @NonNull Set<@NonNull TmfAnalysisRequirement> REQUIREMENTS = Collections.EMPTY_SET; | |
54 | ||
55 | @Override | |
56 | public @NonNull Iterable<@NonNull TmfAnalysisRequirement> getAnalysisRequirements() { | |
57 | return REQUIREMENTS; | |
58 | } | |
59 | ||
60 | @Override | |
61 | protected @NonNull ITmfStateProvider createStateProvider() { | |
62 | ITmfTrace trace = checkNotNull(getTrace()); | |
1668baa9 | 63 | IKernelAnalysisEventLayout layout = (trace instanceof IKernelTrace) ? ((IKernelTrace) trace).getKernelEventLayout() : DefaultEventLayout.getInstance(); |
d8e841d9 MK |
64 | return new ActiveTidStateProvider(trace, layout); |
65 | } | |
66 | ||
67 | /** | |
68 | * Gets the current thread ID on a given CPU for a given time | |
69 | * | |
70 | * @param cpu | |
71 | * the CPU | |
72 | * @param time | |
73 | * the time in nanoseconds | |
74 | * @return the current TID at the time on the CPU or {@code null} if not | |
75 | * known | |
76 | */ | |
77 | public @Nullable Integer getThreadOnCpuAtTime(int cpu, long time) { | |
78 | ITmfStateSystem stateSystem = getStateSystem(); | |
79 | if (stateSystem == null) { | |
80 | return null; | |
81 | } | |
82 | ||
83 | Integer tid = null; | |
84 | try { | |
2d9aed5e MK |
85 | int cpuQuark = stateSystem.optQuarkAbsolute(Integer.toString(cpu)); |
86 | if (cpuQuark == ITmfStateSystem.INVALID_ATTRIBUTE) { | |
87 | return null; | |
88 | } | |
d8e841d9 MK |
89 | ITmfStateValue value = stateSystem.querySingleState(time, cpuQuark).getStateValue(); |
90 | if (value.getType().equals(Type.INTEGER)) { | |
91 | tid = value.unboxInt(); | |
92 | } | |
93 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { | |
94 | Activator.getDefault().logError(NonNullUtils.nullToEmptyString(e.getMessage()), e); | |
95 | } | |
96 | return tid; | |
97 | } | |
98 | ||
99 | /** | |
100 | * Gets the CPU a thread is running on for a given time <br> | |
101 | * Note: this is not designed to be fast, only convenient | |
102 | * | |
103 | * @param tid | |
104 | * the tid | |
105 | * @param time | |
106 | * the time in nanoseconds | |
107 | * @return the current CPU at the time for a TID or {@code null} if not | |
108 | * available | |
109 | */ | |
110 | public @Nullable Integer getCpuForTidAtTime(int tid, long time) { | |
111 | ITmfStateSystem stateSystem = getStateSystem(); | |
112 | if (stateSystem == null) { | |
113 | return null; | |
114 | } | |
115 | ||
116 | try { | |
117 | for (ITmfStateInterval interval : stateSystem.queryFullState(time)) { | |
118 | if (tid == interval.getStateValue().unboxInt()) { | |
119 | return Integer.parseInt(stateSystem.getAttributeName(interval.getAttribute())); | |
120 | } | |
121 | } | |
122 | } catch (StateSystemDisposedException e) { | |
123 | Activator.getDefault().logError(NonNullUtils.nullToEmptyString(e.getMessage()), e); | |
124 | } | |
125 | return null; | |
126 | } | |
127 | } |