ss: Replace AttributeNotFoundException with IOOBE for quark parameters
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / internal / analysis / os / linux / core / inputoutput / DiskWriteModel.java
CommitLineData
6d02c5c1
HD
1/*******************************************************************************
2 * Copyright (c) 2016 École Polytechnique de Montréal
3 *
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 *******************************************************************************/
9
10package org.eclipse.tracecompass.internal.analysis.os.linux.core.inputoutput;
11
12import java.util.HashMap;
13import java.util.Map;
14
15import org.eclipse.jdt.annotation.Nullable;
16import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.Attributes;
d0043318 17import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.Disk;
6d02c5c1
HD
18import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.IoOperationType;
19import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.StateValues;
6d02c5c1
HD
20import org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator;
21import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
22import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
23import org.eclipse.tracecompass.statesystem.core.StateSystemBuilderUtils;
24import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
25import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
26import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
27import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
28import org.eclipse.tracecompass.tmf.core.statesystem.TmfAttributePool;
29import org.eclipse.tracecompass.tmf.core.statesystem.TmfAttributePool.QueueType;
30import org.eclipse.tracecompass.tmf.core.util.Pair;
31
6d02c5c1
HD
32/**
33 * Class that represents a disk on a system. This class provides operation to
34 * save the analysis data in a state system.
35 *
36 * @author Houssem Daoud
37 * @since 2.0
38 */
d0043318 39public class DiskWriteModel extends Disk {
6d02c5c1
HD
40 private final Map<Long, Pair<Request, Integer>> fDriverQueue = new HashMap<>();
41 private final Map<Long, Pair<Request, Integer>> fWaitingQueue = new HashMap<>();
42 private final ITmfStateSystemBuilder fSs;
6d02c5c1
HD
43 private final TmfAttributePool fWaitingQueueAttrib;
44 private final TmfAttributePool fDriverQueueAttrib;
6d02c5c1
HD
45
46 /**
47 * Constructor
48 *
49 * @param dev
50 * The device number of the disk
51 * @param ss
52 * The state system this disk will be saved to
53 */
d0043318
GB
54 public DiskWriteModel(Integer dev, ITmfStateSystemBuilder ss) {
55 super(dev, ss, ss.getQuarkAbsoluteAndAdd(Attributes.DISKS, String.valueOf(dev)));
6d02c5c1 56 fSs = ss;
d0043318 57 int diskQuark = getQuark();
6d02c5c1 58 /* Initialize the state system for this disk */
d0043318
GB
59 fSs.getQuarkRelativeAndAdd(diskQuark, Attributes.SECTORS_WRITTEN);
60 fSs.getQuarkRelativeAndAdd(diskQuark, Attributes.SECTORS_READ);
61 int wqQuark = fSs.getQuarkRelativeAndAdd(diskQuark, Attributes.WAITING_QUEUE);
6d02c5c1 62 fWaitingQueueAttrib = new TmfAttributePool(fSs, wqQuark, QueueType.PRIORITY);
d0043318
GB
63 fSs.getQuarkRelativeAndAdd(diskQuark, Attributes.WAITING_QUEUE_LENGTH);
64 int dqQuark = fSs.getQuarkRelativeAndAdd(diskQuark, Attributes.DRIVER_QUEUE);
6d02c5c1 65 fDriverQueueAttrib = new TmfAttributePool(fSs, dqQuark, QueueType.PRIORITY);
d0043318 66 fSs.getQuarkRelativeAndAdd(diskQuark, Attributes.DRIVER_QUEUE_LENGTH);
6d02c5c1
HD
67 }
68
d0043318 69 @Override
6d02c5c1 70 public void setDiskName(String diskname) {
d0043318 71 super.setDiskName(diskname);
6d02c5c1 72 try {
d0043318 73 fSs.modifyAttribute(fSs.getCurrentEndTime(), TmfStateValue.newValueString(diskname), getQuark());
ed48dc75 74 } catch (StateValueTypeException e) {
6d02c5c1
HD
75 Activator.getDefault().logError("Cannot set the diskname for disk " + diskname, e); //$NON-NLS-1$
76 }
77 }
78
79 /**
80 * Return a request from the waiting queue starting at requested base sector
81 *
82 * @param sector
83 * The sector where the requests starts
84 * @return The request corresponding to this sector, or null if no request
85 * available
86 */
87 public @Nullable Request getWaitingRequest(Long sector) {
88 Pair<Request, Integer> reqQuark = fWaitingQueue.get(sector);
89 if (reqQuark == null) {
90 return null;
91 }
92 return reqQuark.getFirst();
93 }
94
95 /**
96 * Removes the request starting at sector from the waiting queue
97 *
98 * @param ts
99 * The timestamp at which to add this request
100 * @param sector
101 * The sector where the requests starts
102 * @return The quark of the request that was removed or
103 * {@link ITmfStateSystem.INVALID_ATTRIBUTE} if the request was not
104 * present
105 */
106 private int removeWaitingRequest(long ts, Long sector) {
107 Pair<Request, Integer> reqQuark = fWaitingQueue.remove(sector);
108 if (reqQuark == null) {
109 return ITmfStateSystem.INVALID_ATTRIBUTE;
110 }
111 int slotQuark = reqQuark.getSecond();
112 fWaitingQueueAttrib.recycle(slotQuark, ts);
113 return slotQuark;
114 }
115
116 /**
117 * Add a request to the waiting queue. Also saves this request to the state
118 * system
119 *
120 * @param ts
121 * The timestamp at which to add this request
122 * @param request
123 * The requests to put
124 * @return The quark of the request that has been added
125 */
126 public int addWaitingRequest(long ts, Request request) {
127 int slotQuark = insertInWaitingQueue(ts, request);
128 updateQueuesLength(ts);
129 return slotQuark;
130 }
131
132 private int insertInWaitingQueue(long ts, Request request) {
133 ITmfStateValue statusState = request.getType() == IoOperationType.READ ? StateValues.READING_REQUEST_VALUE : StateValues.WRITING_REQUEST_VALUE;
134 int slotQuark = fWaitingQueueAttrib.getAvailable();
135
136 /* Insertion in waiting queue */
137 try {
138 fSs.modifyAttribute(ts, statusState, slotQuark);
139
140 int currentRequestQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.CURRENT_REQUEST);
141 fSs.modifyAttribute(ts, TmfStateValue.newValueLong(request.getSector()), currentRequestQuark);
142
143 int requestSizeQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.REQUEST_SIZE);
144 fSs.modifyAttribute(ts, TmfStateValue.newValueInt(request.getNrSector()), requestSizeQuark);
145
146 int mergedInQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.MERGED_IN);
147 fSs.modifyAttribute(ts, TmfStateValue.nullValue(), mergedInQuark);
ed48dc75 148 } catch (StateValueTypeException e) {
6d02c5c1
HD
149 Activator.getDefault().logError("Error inserting request", e); //$NON-NLS-1$
150 }
151 fWaitingQueue.put(request.getSector(), new Pair<>(request, slotQuark));
152
153 return slotQuark;
154 }
155
156 /**
157 * Update a request in the waiting queue. Also saves this request to the
158 * state system. If the request did not exist previously, it will be added
159 * to the queue. Since the sector may have been updated, the initialSector
160 * parameters allows to say which was the original sector this request was
161 * known for.
162 *
163 * @param ts
164 * The timestamp at which to add this request
165 * @param request
166 * The requests to put
167 * @param initialSector
168 * The original base sector of this request.
169 * @return The quark of the request that has been updated
170 */
171 public int updateWaitingRequest(long ts, Request request, Long initialSector) {
172 Pair<Request, Integer> reqQuark = fWaitingQueue.get(initialSector);
173 if (reqQuark == null) {
174 return addWaitingRequest(ts, request);
abba5403 175 } else if (!initialSector.equals(request.getSector())) {
6d02c5c1
HD
176 fWaitingQueue.remove(initialSector);
177 fWaitingQueue.put(request.getSector(), reqQuark);
178 }
179
180 int slotQuark = reqQuark.getSecond();
181
182 /*
183 * Update the sector, number of sectors and merged in request in waiting
184 * queue
185 */
186 try {
187 int currentRequestQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.CURRENT_REQUEST);
188 fSs.modifyAttribute(ts, TmfStateValue.newValueLong(request.getSector()), currentRequestQuark);
189
190 int requestSizeQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.REQUEST_SIZE);
191 fSs.modifyAttribute(ts, TmfStateValue.newValueInt(request.getNrSector()), requestSizeQuark);
192
193 int mergedInQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.MERGED_IN);
194 fSs.modifyAttribute(ts, TmfStateValue.nullValue(), mergedInQuark);
ed48dc75 195 } catch (StateValueTypeException e) {
6d02c5c1
HD
196 Activator.getDefault().logError("Error inserting request", e); //$NON-NLS-1$
197 }
198
199 updateQueuesLength(ts);
200 return slotQuark;
201 }
202
203 /**
204 * Get the size of the waiting queue
205 *
206 * @return The waiting queue size
207 */
208 public int getWaitingQueueSize() {
209 return fWaitingQueue.size();
210 }
211
212 /**
213 * Return a request from the driver queue starting at requested base sector
214 *
215 * @param sector
216 * The sector where the requests starts
217 * @return The request corresponding to this sector, or null if no request
218 * available
219 */
220 public @Nullable Request getDriverRequest(Long sector) {
221 Pair<Request, Integer> reqQuark = fDriverQueue.get(sector);
222 if (reqQuark == null) {
223 return null;
224 }
225 return reqQuark.getFirst();
226 }
227
228 /**
229 * Removes the request starting at sector from the driver queue
230 *
231 * @param ts
232 * The timestamp at which to add this request
233 * @param sector
234 * The sector where the requests starts
235 */
236 private void removeDriverRequest(long ts, Long sector) {
237 Pair<Request, Integer> reqQuark = fDriverQueue.remove(sector);
238 if (reqQuark == null) {
239 return;
240 }
241 fDriverQueueAttrib.recycle(reqQuark.getSecond(), ts);
242 }
243
244 /**
245 * Issues a request to the disk. This method removes the request from the
246 * waiting queue if necessary and adds it to the driver queue.
247 *
248 * @param ts
249 * The timestamp of this operation
250 * @param request
251 * The requests to put
252 * @return The quark of the request that was just issued
253 */
254 public int issueRequest(long ts, Request request) {
255 /* Remove from waiting queue */
256 TmfStateValue issuedFromValue = TmfStateValue.nullValue();
257 int fromQuark = removeWaitingRequest(ts, request.getSector());
258 if (fromQuark != ITmfStateSystem.INVALID_ATTRIBUTE) {
259 String reqQueueId = fSs.getAttributeName(fromQuark);
260 issuedFromValue = TmfStateValue.newValueInt(Integer.parseInt(reqQueueId));
261 }
262
263 ITmfStateValue statusState = request.getType() == IoOperationType.READ ? StateValues.READING_REQUEST_VALUE : StateValues.WRITING_REQUEST_VALUE;
264 int slotQuark = fDriverQueueAttrib.getAvailable();
265
266 /* Insertion in driver queue */
267 try {
268 fSs.modifyAttribute(ts, statusState, slotQuark);
269
270 int currentRequestQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.CURRENT_REQUEST);
271 fSs.modifyAttribute(ts, TmfStateValue.newValueLong(request.getSector()), currentRequestQuark);
272
273 int requestSizeQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.REQUEST_SIZE);
274 fSs.modifyAttribute(ts, TmfStateValue.newValueInt(request.getNrSector()), requestSizeQuark);
275
276 int issuedFromQuark = fSs.getQuarkRelativeAndAdd(slotQuark, Attributes.ISSUED_FROM);
277 fSs.modifyAttribute(ts, issuedFromValue, issuedFromQuark);
ed48dc75 278 } catch (StateValueTypeException e) {
6d02c5c1
HD
279 Activator.getDefault().logError("Error issuing request", e); //$NON-NLS-1$
280 }
281
282 fDriverQueue.put(request.getSector(), new Pair<>(request, slotQuark));
283 updateQueuesLength(ts);
284 return slotQuark;
285 }
286
287 /**
288 * Completes a request on the disk. It adds to the total of sectors read and
289 * written on this disk. It also removes the request from the driver queue
290 * if necessary.
291 *
292 * @param ts
293 * The timestamp of this operation
294 * @param request
295 * The requests to put
296 */
297 public void completeRequest(long ts, Request request) {
298 /* Add the total number of sectors read or written */
299 try {
300 switch (request.getType()) {
301 case READ:
d0043318 302 int readQuark = fSs.getQuarkRelativeAndAdd(getQuark(), Attributes.SECTORS_READ);
6d02c5c1
HD
303 StateSystemBuilderUtils.incrementAttributeInt(fSs, ts, readQuark, request.getNrSector());
304 break;
305 case WRITE:
d0043318 306 int writtenQuark = fSs.getQuarkRelativeAndAdd(getQuark(), Attributes.SECTORS_WRITTEN);
6d02c5c1
HD
307 StateSystemBuilderUtils.incrementAttributeInt(fSs, ts, writtenQuark, request.getNrSector());
308 break;
309 default:
310 throw new IllegalStateException("Complete request: the request cannot be other than READ or WRITE:" + request.getType()); //$NON-NLS-1$
311 }
312 } catch (StateValueTypeException | AttributeNotFoundException e) {
313 Activator.getDefault().logError("Error completing request", e); //$NON-NLS-1$
314 }
315
316 /* Remove the request from driver queue */
317 removeDriverRequest(ts, request.getSector());
318 updateQueuesLength(ts);
319 }
320
321 /**
322 * Merges 2 requests from the waiting queue. The second request will be
323 * removed from the queue while the first one will be udpated
324 *
325 * @param ts
326 * The timestamp of this operation
327 * @param baseRequest
328 * The base request that will be kept
329 * @param mergedRequest
330 * The merged request to be removed from the queue
331 */
332 public void mergeRequests(long ts, Request baseRequest, Request mergedRequest) {
333 int mergedQuark = removeWaitingRequest(ts, mergedRequest.getSector());
334 Long baseSector = baseRequest.getSector();
335 baseRequest.mergeRequest(mergedRequest);
336 int baseQuark = updateWaitingRequest(ts, baseRequest, baseSector);
337 if (mergedQuark != ITmfStateSystem.INVALID_ATTRIBUTE) {
338 /* Add the merge information */
339 try {
340 String reqQueueId = fSs.getAttributeName(baseQuark);
341
342 int issuedFromQuark = fSs.getQuarkRelativeAndAdd(mergedQuark, Attributes.MERGED_IN);
343 fSs.modifyAttribute(ts, TmfStateValue.newValueInt(Integer.parseInt(reqQueueId)), issuedFromQuark);
ed48dc75 344 } catch (StateValueTypeException e) {
6d02c5c1
HD
345 Activator.getDefault().logError("Error adding the merged request information", e); //$NON-NLS-1$
346 }
347 }
348 updateQueuesLength(ts);
349 }
350
351 /**
352 * Get the size of the driver queue
353 *
354 * @return The driver queue size
355 */
356 public int getDriverQueueSize() {
357 return fDriverQueue.size();
358 }
359
6d02c5c1
HD
360 private void updateQueuesLength(long ts) {
361 try {
d0043318 362 int fDriverQueueLength = fSs.getQuarkRelativeAndAdd(getQuark(), Attributes.DRIVER_QUEUE_LENGTH);
6d02c5c1 363 fSs.modifyAttribute(ts, TmfStateValue.newValueInt(getDriverQueueSize()), fDriverQueueLength);
d0043318 364 int fWaitinQueueLength = fSs.getQuarkRelativeAndAdd(getQuark(), Attributes.WAITING_QUEUE_LENGTH);
6d02c5c1 365 fSs.modifyAttribute(ts, TmfStateValue.newValueInt(getWaitingQueueSize()), fWaitinQueueLength);
ed48dc75 366 } catch (StateValueTypeException e) {
6d02c5c1
HD
367 Activator.getDefault().logError("Error updating queues lengths", e); //$NON-NLS-1$
368 }
369 }
370
6d02c5c1 371}
This page took 0.042354 seconds and 5 git commands to generate.