1 /*******************************************************************************
2 * Copyright (c) 2015, 2016 EfficiOS Inc., Ericsson
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.latency
;
12 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
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
;
21 import java
.util
.function
.Function
;
22 import java
.util
.stream
.Collectors
;
24 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
25 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
26 import org
.eclipse
.jdt
.annotation
.NonNull
;
27 import org
.eclipse
.jdt
.annotation
.Nullable
;
28 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelTidAspect
;
29 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.tid
.TidAnalysisModule
;
30 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.trace
.IKernelAnalysisEventLayout
;
31 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.trace
.IKernelTrace
;
32 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.AbstractSegmentStoreAnalysisEventBasedModule
;
33 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
34 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.IAnalysisModule
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.segment
.ISegmentAspect
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
40 import com
.google
.common
.collect
.ImmutableList
;
41 import com
.google
.common
.collect
.ImmutableSet
;
44 * @author Alexandre Montplaisir
47 public class SystemCallLatencyAnalysis
extends AbstractSegmentStoreAnalysisEventBasedModule
{
50 * The ID of this analysis
52 public static final String ID
= "org.eclipse.tracecompass.analysis.os.linux.latency.syscall"; //$NON-NLS-1$
54 private static final String DATA_FILENAME
= "latency-analysis.dat"; //$NON-NLS-1$
56 private static final Collection
<ISegmentAspect
> BASE_ASPECTS
=
57 ImmutableList
.of(SyscallNameAspect
.INSTANCE
);
60 public String
getId() {
65 protected Iterable
<IAnalysisModule
> getDependentAnalyses() {
66 ITmfTrace trace
= getTrace();
68 throw new IllegalStateException();
70 IAnalysisModule module
= trace
.getAnalysisModule(TidAnalysisModule
.ID
);
72 return Collections
.EMPTY_SET
;
74 return ImmutableSet
.of(module
);
78 public Iterable
<ISegmentAspect
> getSegmentAspects() {
83 public @NonNull String
getDataFileName() {
88 public AbstractSegmentStoreAnalysisRequest
createAnalysisRequest(ISegmentStore
<ISegment
> syscalls
) {
89 return new SyscallLatencyAnalysisRequest(syscalls
);
93 protected Object
[] readObject(ObjectInputStream ois
) throws ClassNotFoundException
, IOException
{
94 return checkNotNull((Object
[]) ois
.readObject());
97 private class SyscallLatencyAnalysisRequest
extends AbstractSegmentStoreAnalysisRequest
{
99 private final Map
<Integer
, SystemCall
.InitialInfo
> fOngoingSystemCalls
= new HashMap
<>();
100 private @Nullable IKernelAnalysisEventLayout fLayout
;
101 private final IProgressMonitor fMonitor
= new NullProgressMonitor();
103 public SyscallLatencyAnalysisRequest(ISegmentStore
<ISegment
> syscalls
) {
108 public void handleData(final ITmfEvent event
) {
109 super.handleData(event
);
110 IKernelAnalysisEventLayout layout
= fLayout
;
111 if (layout
== null) {
112 IKernelTrace trace
= (IKernelTrace
) event
.getTrace();
113 layout
= trace
.getKernelEventLayout();
116 final String eventName
= event
.getType().getName();
118 if (eventName
.startsWith(layout
.eventSyscallEntryPrefix()) ||
119 eventName
.startsWith(layout
.eventCompatSyscallEntryPrefix())) {
120 /* This is a system call entry event */
124 tid
= KernelTidAspect
.INSTANCE
.resolve(event
, true, fMonitor
);
125 } catch (InterruptedException e
) {
129 // no information on this event/trace ?
133 /* Record the event's data into the intial system call info */
134 // String syscallName = fLayout.getSyscallNameFromEvent(event);
135 long startTime
= event
.getTimestamp().getValue();
136 String syscallName
= eventName
.substring(layout
.eventSyscallEntryPrefix().length());
138 Map
<String
, String
> args
= event
.getContent().getFieldNames().stream()
139 .collect(Collectors
.toMap(Function
.identity(),
140 input
-> checkNotNull(event
.getContent().getField(input
).toString())));
142 SystemCall
.InitialInfo newSysCall
= new SystemCall
.InitialInfo(startTime
, checkNotNull(syscallName
), checkNotNull(args
));
143 fOngoingSystemCalls
.put(tid
, newSysCall
);
145 } else if (eventName
.startsWith(layout
.eventSyscallExitPrefix())) {
146 /* This is a system call exit event */
150 tid
= KernelTidAspect
.INSTANCE
.resolve(event
, true, fMonitor
);
151 } catch (InterruptedException e
) {
158 SystemCall
.InitialInfo info
= fOngoingSystemCalls
.remove(tid
);
161 * We have not seen the entry event corresponding to this
162 * exit (lost event, or before start of trace).
167 long endTime
= event
.getTimestamp().getValue();
168 int ret
= ((Long
) event
.getContent().getField("ret").getValue()).intValue(); //$NON-NLS-1$
169 ISegment syscall
= new SystemCall(info
, endTime
, ret
);
170 getSegmentStore().add(syscall
);
175 public void handleCompleted() {
176 fOngoingSystemCalls
.clear();
177 super.handleCompleted();
181 public void handleCancel() {
182 fMonitor
.setCanceled(true);
183 super.handleCancel();
187 private static class SyscallNameAspect
implements ISegmentAspect
{
188 public static final ISegmentAspect INSTANCE
= new SyscallNameAspect();
190 private SyscallNameAspect() { }
193 public String
getHelpText() {
194 return checkNotNull(Messages
.SegmentAspectHelpText_SystemCall
);
197 public String
getName() {
198 return checkNotNull(Messages
.SegmentAspectName_SystemCall
);
201 public @Nullable Comparator
<?
> getComparator() {
205 public @Nullable String
resolve(ISegment segment
) {
206 if (segment
instanceof SystemCall
) {
207 return ((SystemCall
) segment
).getName();