analysis: add abstract latency analysis module and use it in LTTng
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / analysis / os / linux / core / latency / LatencyAnalysis.java
1 /*******************************************************************************
2 * Copyright (c) 2015 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.HashMap;
17 import java.util.Map;
18
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelTidAspect;
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.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule;
24 import org.eclipse.tracecompass.common.core.NonNullUtils;
25 import org.eclipse.tracecompass.segmentstore.core.ISegment;
26 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
27 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
28
29 import com.google.common.base.Function;
30 import com.google.common.collect.FluentIterable;
31
32 /**
33 * @author Alexandre Montplaisir
34 * @since 2.0
35 */
36 public class LatencyAnalysis extends AbstractSegmentStoreAnalysisModule {
37
38 /**
39 * The ID of this analysis
40 */
41 public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.latency"; //$NON-NLS-1$
42
43 private static final String DATA_FILENAME = "latency-analysis.dat"; //$NON-NLS-1$
44
45 @Override
46 public String getId() {
47 return ID;
48 }
49
50 @Override
51 public String getDataFileName() {
52 return DATA_FILENAME;
53 }
54
55 @Override
56 public AbstractSegmentStoreAnalysisRequest createAnalysisRequest(ISegmentStore<ISegment> syscalls) {
57 return new SyscallLatencyAnalysisRequest(syscalls);
58 }
59
60 @Override
61 protected Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
62 return checkNotNull((Object[]) ois.readObject());
63 }
64
65 private static class SyscallLatencyAnalysisRequest extends AbstractSegmentStoreAnalysisRequest {
66
67 private final Map<Integer, SystemCall.InitialInfo> fOngoingSystemCalls = new HashMap<>();
68 private @Nullable IKernelAnalysisEventLayout fLayout;
69
70 public SyscallLatencyAnalysisRequest(ISegmentStore<ISegment> syscalls) {
71 super(syscalls);
72 }
73
74 @Override
75 public void handleData(final ITmfEvent event) {
76 super.handleData(event);
77 IKernelAnalysisEventLayout layout = fLayout;
78 if (layout == null) {
79 IKernelTrace trace = checkNotNull((IKernelTrace) event.getTrace());
80 layout = trace.getKernelEventLayout();
81 fLayout = layout;
82 }
83 final String eventName = event.getType().getName();
84
85 if (eventName.startsWith(layout.eventSyscallEntryPrefix()) ||
86 eventName.startsWith(layout.eventCompatSyscallEntryPrefix())) {
87 /* This is a system call entry event */
88
89 Integer tid = KernelTidAspect.INSTANCE.resolve(event);
90 if (tid == null) {
91 // no information on this event/trace ?
92 return;
93 }
94
95 /* Record the event's data into the intial system call info */
96 // String syscallName = fLayout.getSyscallNameFromEvent(event);
97 long startTime = event.getTimestamp().getValue();
98 String syscallName = eventName.substring(layout.eventSyscallEntryPrefix().length());
99 FluentIterable<String> argNames = FluentIterable.from(event.getContent().getFieldNames());
100 Map<String, String> args = argNames.toMap(new Function<String, String>() {
101 @Override
102 public String apply(@Nullable String input) {
103 return checkNotNull(event.getContent().getField(input).getValue().toString());
104 }
105 });
106 SystemCall.InitialInfo newSysCall = new SystemCall.InitialInfo(startTime, NonNullUtils.checkNotNull(syscallName), NonNullUtils.checkNotNull(args));
107 fOngoingSystemCalls.put(tid, newSysCall);
108
109 } else if (eventName.startsWith(layout.eventSyscallExitPrefix())) {
110 /* This is a system call exit event */
111
112 Integer tid = KernelTidAspect.INSTANCE.resolve(event);
113 if (tid == null) {
114 return;
115 }
116
117 SystemCall.InitialInfo info = fOngoingSystemCalls.remove(tid);
118 if (info == null) {
119 /*
120 * We have not seen the entry event corresponding to this
121 * exit (lost event, or before start of trace).
122 */
123 return;
124 }
125
126 long endTime = event.getTimestamp().getValue();
127 int ret = ((Long) event.getContent().getField("ret").getValue()).intValue(); //$NON-NLS-1$
128 ISegment syscall = new SystemCall(info, endTime, ret);
129 getSegmentStore().add(syscall);
130 }
131 }
132
133 @Override
134 public void handleCompleted() {
135 fOngoingSystemCalls.clear();
136 }
137 }
138
139 }
This page took 0.041205 seconds and 6 git commands to generate.