tmf: Add the dependency level to the analyses' event requests
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / analysis / os / linux / core / latency / SystemCallLatencyAnalysis.java
1 /*******************************************************************************
2 * Copyright (c) 2015, 2016 EfficiOS Inc., 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.latency;
11
12 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
13
14 import java.io.IOException;
15 import java.io.ObjectInputStream;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.Comparator;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.function.Function;
22 import java.util.stream.Collectors;
23
24 import org.eclipse.jdt.annotation.NonNull;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelTidAspect;
27 import org.eclipse.tracecompass.analysis.os.linux.core.tid.TidAnalysisModule;
28 import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
29 import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
30 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisEventBasedModule;
31 import org.eclipse.tracecompass.segmentstore.core.ISegment;
32 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
33 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
34 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
35 import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
36 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
37
38 import com.google.common.collect.ImmutableList;
39 import com.google.common.collect.ImmutableSet;
40
41 /**
42 * @author Alexandre Montplaisir
43 * @since 2.0
44 */
45 public class SystemCallLatencyAnalysis extends AbstractSegmentStoreAnalysisEventBasedModule {
46
47 /**
48 * The ID of this analysis
49 */
50 public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.latency.syscall"; //$NON-NLS-1$
51
52 private static final String DATA_FILENAME = "latency-analysis.dat"; //$NON-NLS-1$
53
54 private static final Collection<ISegmentAspect> BASE_ASPECTS =
55 ImmutableList.of(SyscallNameAspect.INSTANCE);
56
57 @Override
58 public String getId() {
59 return ID;
60 }
61
62 @Override
63 protected Iterable<IAnalysisModule> getDependentAnalyses() {
64 ITmfTrace trace = getTrace();
65 if (trace == null) {
66 throw new IllegalStateException();
67 }
68 IAnalysisModule module = trace.getAnalysisModule(TidAnalysisModule.ID);
69 if (module == null) {
70 return Collections.EMPTY_SET;
71 }
72 return ImmutableSet.of(module);
73 }
74
75 @Override
76 public Iterable<ISegmentAspect> getSegmentAspects() {
77 return BASE_ASPECTS;
78 }
79
80 @Override
81 public @NonNull String getDataFileName() {
82 return DATA_FILENAME;
83 }
84
85 @Override
86 public AbstractSegmentStoreAnalysisRequest createAnalysisRequest(ISegmentStore<ISegment> syscalls) {
87 return new SyscallLatencyAnalysisRequest(syscalls);
88 }
89
90 @Override
91 protected Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
92 return checkNotNull((Object[]) ois.readObject());
93 }
94
95 private class SyscallLatencyAnalysisRequest extends AbstractSegmentStoreAnalysisRequest {
96
97 private final Map<Integer, SystemCall.InitialInfo> fOngoingSystemCalls = new HashMap<>();
98 private @Nullable IKernelAnalysisEventLayout fLayout;
99
100 public SyscallLatencyAnalysisRequest(ISegmentStore<ISegment> syscalls) {
101 super(syscalls);
102 }
103
104 @Override
105 public void handleData(final ITmfEvent event) {
106 super.handleData(event);
107 IKernelAnalysisEventLayout layout = fLayout;
108 if (layout == null) {
109 IKernelTrace trace = (IKernelTrace) event.getTrace();
110 layout = trace.getKernelEventLayout();
111 fLayout = layout;
112 }
113 final String eventName = event.getType().getName();
114
115 if (eventName.startsWith(layout.eventSyscallEntryPrefix()) ||
116 eventName.startsWith(layout.eventCompatSyscallEntryPrefix())) {
117 /* This is a system call entry event */
118
119 Integer tid = KernelTidAspect.INSTANCE.resolve(event);
120 if (tid == null) {
121 // no information on this event/trace ?
122 return;
123 }
124
125 /* Record the event's data into the intial system call info */
126 // String syscallName = fLayout.getSyscallNameFromEvent(event);
127 long startTime = event.getTimestamp().getValue();
128 String syscallName = eventName.substring(layout.eventSyscallEntryPrefix().length());
129
130 Map<String, String> args = event.getContent().getFieldNames().stream()
131 .collect(Collectors.toMap(Function.identity(),
132 input -> checkNotNull(event.getContent().getField(input).toString())));
133
134 SystemCall.InitialInfo newSysCall = new SystemCall.InitialInfo(startTime, checkNotNull(syscallName), checkNotNull(args));
135 fOngoingSystemCalls.put(tid, newSysCall);
136
137 } else if (eventName.startsWith(layout.eventSyscallExitPrefix())) {
138 /* This is a system call exit event */
139
140 Integer tid = KernelTidAspect.INSTANCE.resolve(event);
141 if (tid == null) {
142 return;
143 }
144
145 SystemCall.InitialInfo info = fOngoingSystemCalls.remove(tid);
146 if (info == null) {
147 /*
148 * We have not seen the entry event corresponding to this
149 * exit (lost event, or before start of trace).
150 */
151 return;
152 }
153
154 long endTime = event.getTimestamp().getValue();
155 int ret = ((Long) event.getContent().getField("ret").getValue()).intValue(); //$NON-NLS-1$
156 ISegment syscall = new SystemCall(info, endTime, ret);
157 getSegmentStore().add(syscall);
158 }
159 }
160
161 @Override
162 public void handleCompleted() {
163 fOngoingSystemCalls.clear();
164 }
165 }
166
167 private static class SyscallNameAspect implements ISegmentAspect {
168 public static final ISegmentAspect INSTANCE = new SyscallNameAspect();
169
170 private SyscallNameAspect() { }
171
172 @Override
173 public String getHelpText() {
174 return checkNotNull(Messages.SegmentAspectHelpText_SystemCall);
175 }
176 @Override
177 public String getName() {
178 return checkNotNull(Messages.SegmentAspectName_SystemCall);
179 }
180 @Override
181 public @Nullable Comparator<?> getComparator() {
182 return null;
183 }
184 @Override
185 public @Nullable String resolve(ISegment segment) {
186 if (segment instanceof SystemCall) {
187 return ((SystemCall) segment).getName();
188 }
189 return EMPTY_STRING;
190 }
191 }
192
193 }
This page took 0.044745 seconds and 5 git commands to generate.