1 /*******************************************************************************
2 * Copyright (c) 2016 École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
;
12 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
14 import java
.util
.HashMap
;
17 import org
.eclipse
.jdt
.annotation
.Nullable
;
18 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.inputoutput
.Attributes
;
19 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.trace
.IKernelAnalysisEventLayout
;
20 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
21 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.Activator
;
22 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.BlockFrontMergeHandler
;
23 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.BlockRqComplete
;
24 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.BlockRqInsertHandler
;
25 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.BlockRqIssueHandler
;
26 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.MergeRequestsHandler
;
27 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.StateDumpHandler
;
28 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.SysEntryHandler
;
29 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.inputoutput
.handlers
.SysExitHandler
;
30 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.kernel
.handlers
.KernelEventHandler
;
31 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystemBuilder
;
32 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
33 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
34 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.AbstractTmfStateProvider
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
39 import com
.google
.common
.collect
.ImmutableMap
;
42 * State provider for the I/O analysis
48 * | |- <TID> -> System Call Name
52 * | | |- BYTES_WRITTEN
54 * | |- <Disk number> -> Disk Name
56 * | | |- SECTORS_WRITTEN
57 * | | |- WAITING_QUEUE -> Root for the Attribute pool for waiting queue
58 * | | | |- <slot #1> -> Status
59 * | | | | |- CURRENT_REQUEST
60 * | | | | |- REQUEST_SIZE
61 * | | | | |- MERGED_IN
63 * | | |- WAITING_QUEUE_LENGTH
64 * | | |- DRIVER_QUEUE -> Root for the Attribute pool for driver queue
65 * | | | |- <slot #1> -> Status
66 * | | | | |- CURRENT_REQUEST
67 * | | | | |- REQUEST_SIZE
68 * | | | | |- ISSUED_FROM
70 * | | |- DRIVER_QUEUE_LENGTH
73 * @author Houssem Daoud
76 public class InputOutputStateProvider
extends AbstractTmfStateProvider
{
78 private static final int VERSION
= 1;
80 private final Map
<Integer
, DiskWriteModel
> fDisks
= new HashMap
<>();
81 private final Map
<String
, KernelEventHandler
> fEventNames
;
82 private final IKernelAnalysisEventLayout fLayout
;
84 private final KernelEventHandler fSysEntryHandler
;
85 private final KernelEventHandler fSysExitHandler
;
88 * Instantiate a new state provider plugin.
91 * The kernel trace to apply this state provider to
93 * The event layout to use for this state provider.
95 public InputOutputStateProvider(ITmfTrace trace
, IKernelAnalysisEventLayout layout
) {
96 super(trace
, "Input Output Analysis");//$NON-NLS-1$
98 fEventNames
= buildEventNames(layout
);
99 fSysEntryHandler
= new SysEntryHandler(layout
);
100 fSysExitHandler
= new SysExitHandler(layout
);
103 private Map
<String
, KernelEventHandler
> buildEventNames(IKernelAnalysisEventLayout layout
) {
104 ImmutableMap
.Builder
<String
, KernelEventHandler
> builder
= ImmutableMap
.builder();
106 builder
.put(layout
.eventBlockRqInsert(), new BlockRqInsertHandler(layout
, this));
107 builder
.put(layout
.eventBlockRqIssue(), new BlockRqIssueHandler(layout
, this));
108 builder
.put(layout
.eventBlockRqComplete(), new BlockRqComplete(layout
, this));
109 builder
.put(layout
.eventBlockBioFrontmerge(), new BlockFrontMergeHandler(layout
, this));
110 builder
.put(layout
.eventBlockRqMerge(), new MergeRequestsHandler(layout
, this));
112 final String eventStatedumpBlockDevice
= layout
.eventStatedumpBlockDevice();
113 if (eventStatedumpBlockDevice
!= null) {
114 builder
.put(eventStatedumpBlockDevice
, new StateDumpHandler(layout
, this));
117 return builder
.build();
121 public int getVersion() {
126 public InputOutputStateProvider
getNewInstance() {
127 return new InputOutputStateProvider(this.getTrace(), this.fLayout
);
131 protected void eventHandle(@Nullable ITmfEvent event
) {
137 final String eventName
= event
.getName();
140 final ITmfStateSystemBuilder ss
= NonNullUtils
.checkNotNull(getStateSystemBuilder());
142 * Feed event to the history system if it's known to cause a state
145 KernelEventHandler handler
= fEventNames
.get(eventName
);
146 if (handler
== null) {
147 if (isSyscallExit(eventName
)) {
148 handler
= fSysExitHandler
;
149 } else if (isSyscallEntry(eventName
)) {
150 handler
= fSysEntryHandler
;
153 if (handler
!= null) {
154 handler
.handleEvent(ss
, event
);
156 } catch (TimeRangeException
| StateValueTypeException
| AttributeNotFoundException e
) {
157 Activator
.getDefault().logError("Exception while building the IO state system", e
); //$NON-NLS-1$
163 * Get a disk identified by a device ID
166 * The device ID of the block device
167 * @return The disk corresponding to the device ID
169 public DiskWriteModel
getDisk(int deviceId
) {
170 DiskWriteModel disk
= fDisks
.get(deviceId
);
172 disk
= new DiskWriteModel(deviceId
, checkNotNull(getStateSystemBuilder()));
173 fDisks
.put(deviceId
, disk
);
178 private boolean isSyscallEntry(String eventName
) {
179 return (eventName
.startsWith(fLayout
.eventSyscallEntryPrefix())
180 || eventName
.startsWith(fLayout
.eventCompatSyscallEntryPrefix()));
183 private boolean isSyscallExit(String eventName
) {
184 return (eventName
.startsWith(fLayout
.eventSyscallExitPrefix()) ||
185 eventName
.startsWith(fLayout
.eventCompatSyscallExitPrefix()));
189 * Return the quark corresponding to the threads attributes
192 * the state system builder
193 * @return The quark of the {@link Attributes#THREADS} node
195 public static int getNodeThreads(ITmfStateSystemBuilder ssb
) {
196 return ssb
.getQuarkAbsoluteAndAdd(Attributes
.THREADS
);
200 * Return the quark corresponding to the system call root attributes
203 * the state system builder
204 * @return The quark of the {@link Attributes#SYSTEM_CALLS_ROOT} node
206 public static int getNodeSyscalls(ITmfStateSystemBuilder ssb
) {
207 return ssb
.getQuarkAbsoluteAndAdd(Attributes
.SYSTEM_CALLS_ROOT
);