tmf: Use tabs in statistics view for each traces
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.core / src / org / eclipse / linuxtools / internal / lttng / core / control / LttngSyntheticEventProvider.java
CommitLineData
5d10d135
ASL
1/*******************************************************************************
2 * Copyright (c) 2010 Ericsson
0c32e4c5 3 *
5d10d135
ASL
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
0c32e4c5 8 *
5d10d135
ASL
9 * Contributors:
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
3f2b9283 11 * Marc Dumais (marc.dumais@ericsson.com) - Fix for 316455 (first part)
5d10d135
ASL
12 *******************************************************************************/
13
5945cec9 14package org.eclipse.linuxtools.internal.lttng.core.control;
5d10d135
ASL
15
16import java.util.HashMap;
3f2b9283
FC
17import java.util.Iterator;
18import java.util.List;
5d10d135 19import java.util.Map;
3f2b9283 20import java.util.Vector;
5d10d135 21
5945cec9 22import org.eclipse.linuxtools.internal.lttng.core.TraceDebug;
5945cec9
FC
23import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventType;
24import org.eclipse.linuxtools.internal.lttng.core.event.LttngSyntheticEvent;
5945cec9 25import org.eclipse.linuxtools.internal.lttng.core.event.LttngSyntheticEvent.SequenceInd;
c32744d6 26import org.eclipse.linuxtools.internal.lttng.core.event.LttngTimestamp;
5945cec9
FC
27import org.eclipse.linuxtools.internal.lttng.core.model.LTTngTreeNode;
28import org.eclipse.linuxtools.internal.lttng.core.request.LttngBaseEventRequest;
29import org.eclipse.linuxtools.internal.lttng.core.state.evProcessor.ITransEventProcessor;
30import org.eclipse.linuxtools.internal.lttng.core.state.evProcessor.state.StateEventToHandlerFactory;
31import org.eclipse.linuxtools.internal.lttng.core.state.model.LttngTraceState;
32import org.eclipse.linuxtools.internal.lttng.core.state.trace.IStateTraceManager;
6c13869b 33import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
0c32e4c5 34import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
6c13869b
FC
35import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
36import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
6c13869b
FC
37import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
38import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
39import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
40import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal;
41import org.eclipse.linuxtools.tmf.core.signal.TmfStartSynchSignal;
42import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
43import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
44import org.eclipse.linuxtools.tmf.core.trace.TmfCheckpoint;
45import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
9e0640dc 46import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
5d10d135
ASL
47
48/**
49 * @author alvaro
0c32e4c5 50 *
5d10d135 51 */
0c32e4c5 52public class LttngSyntheticEventProvider extends TmfEventProvider {
5d10d135
ASL
53
54 // ========================================================================
55 // Data
56 // ========================================================================
a79913eb 57 public static final int BLOCK_SIZE = 50000;
3d62f8b7 58 public static final int NB_EVENTS = 1;
f9673903 59 public static final int QUEUE_SIZE = 1; // lttng specific, one event at a time
5d10d135 60
0c32e4c5 61 private ITmfDataRequest fmainRequest = null;
c1c69938
FC
62 private LttngBaseEventRequest fSubRequest = null;
63
3f2b9283
FC
64 private final List<IStateTraceManager> fEventProviderRequests = new Vector<IStateTraceManager>();
65
5d10d135 66 private final LttngSyntheticEvent fStatusEvent;
5d10d135
ASL
67 volatile boolean startIndSent = false;
68 private LTTngTreeNode fExperiment = null;
0c32e4c5 69 private final ITransEventProcessor fstateUpdateProcessor = StateEventToHandlerFactory.getInstance();
5d10d135 70 private boolean waitForRequest = false;
3f2b9283 71 long dispatchTime = 0L;
a79913eb
FC
72 long dispatchIndex = 0L;
73 long eventIndex;
0c32e4c5 74 private final Map<ITmfTrace, LttngTraceState> traceToTraceStateModel = new HashMap<ITmfTrace, LttngTraceState>();
5d10d135 75
c1c69938
FC
76 private boolean fIsExperimentNotified = false;
77
5d10d135
ASL
78 // ========================================================================
79 // Constructor
80 // ========================================================================
81 /**
82 * Accessibility to package - use factory instead of this constructor
0c32e4c5 83 *
5d10d135
ASL
84 * @param type
85 */
86 LttngSyntheticEventProvider(Class<LttngSyntheticEvent> type) {
9c4eb5f7 87 super("LttngSyntheticEventProvider", type, QUEUE_SIZE); //$NON-NLS-1$
5d10d135
ASL
88
89 // prepare empty instance status indicators and allow them to travel via
90 // the framework
99005796 91 String source = this.toString();
5d10d135 92 LttngEventType dtype = new LttngEventType();
f9673903 93 LttngTimestamp statusTimeStamp = new LttngTimestamp(
a4115405 94 TmfTimestamp.ZERO);
5d10d135 95
f9673903
FC
96 fStatusEvent = new LttngSyntheticEvent(null, statusTimeStamp, source,
97 dtype, null, null, null);
5d10d135 98 fStatusEvent.setSequenceInd(SequenceInd.STARTREQ);
5d10d135
ASL
99 }
100
101 // ========================================================================
102 // Methods
103 // ========================================================================
550d787e 104
5d10d135
ASL
105 @SuppressWarnings("unchecked")
106 @Override
0c32e4c5 107 public synchronized ITmfContext armRequest(final ITmfDataRequest request) {
5d10d135
ASL
108 // validate
109 // make sure we have the right type of request
0c32e4c5 110 if (!(request instanceof ITmfEventRequest)) {
5d10d135 111 request.cancel();
9c4eb5f7 112 TraceDebug.debug("Request is not an instance of ITmfEventRequest"); //$NON-NLS-1$
5d10d135
ASL
113 return null;
114 }
115
116 if (fExperiment == null) {
9c4eb5f7 117 TraceDebug.debug("Experiment is null"); //$NON-NLS-1$
5d10d135
ASL
118 request.cancel();
119 return null;
120 }
121
122 // get ready to start processing
123 reset(fExperiment);
124
125 // At least one base provider shall be available
550d787e 126 if (fEventProviderRequests.size() < 1) {
5d10d135 127 request.cancel();
9c4eb5f7 128 TraceDebug.debug("No Base event providers available"); //$NON-NLS-1$
5d10d135
ASL
129 return null;
130 }
131
132 fmainRequest = request;
c1c69938 133
5d10d135 134 // define event data handling
0c32e4c5 135 ITmfEventRequest eventRequest = (ITmfEventRequest) fmainRequest;
5d10d135 136 TmfTimeRange reqWindow = eventRequest.getRange();
550d787e 137
9c4eb5f7 138 TraceDebug.debug("Main Synthethic event request started on thread: " + Thread.currentThread().getName()); //$NON-NLS-1$
5d10d135 139
0c32e4c5 140 TmfExperiment experiment = (TmfExperiment) fExperiment.getValue();
9b635e61 141 experiment.startSynch(new TmfStartSynchSignal(0));
0c32e4c5 142
3f2b9283 143 TmfTimeRange adjustedRange = reqWindow;
a79913eb
FC
144 long adjustedIndex = eventRequest.getIndex();
145 int nbRequested = eventRequest.getNbRequested();
0c32e4c5 146
3f2b9283 147 // Figure-out if we need to increase the range of the request: if some
0c32e4c5
AM
148 // checkpoints are before the beginning of the range, increase the
149 // range to catch them. We will then exercise the state system of
3f2b9283 150 // those traces until the requested beginning time range, discarding
0c32e4c5 151 // the unrequested data.
3f2b9283
FC
152 IStateTraceManager traceManager;
153 Iterator<IStateTraceManager> iter = fEventProviderRequests.iterator();
154 // For each traceManager in the current experiment...
155 while(iter.hasNext()) {
156 traceManager = iter.next();
5d10d135 157 // restore trace state system to nearest check point
a79913eb
FC
158 TmfCheckpoint checkPoint = null;
159 if (eventRequest.getIndex() > 0) {
160 checkPoint = traceManager.restoreCheckPointByIndex(eventRequest.getIndex());
161 } else {
162 checkPoint = traceManager.restoreCheckPointByTimestamp(reqWindow.getStartTime());
163 }
550d787e 164
3f2b9283
FC
165 // validate that the checkpoint restored is within requested bounds
166 // (not outside the current trace's range or after the end of requested range)
ce970a71 167 TmfTimeRange traceRange = traceManager.getStateTrace().getTimeRange();
a79913eb
FC
168 if ((checkPoint == null) ||
169 checkPoint.getTimestamp().getValue() < traceRange.getStartTime().getValue() ||
170 checkPoint.getTimestamp().getValue() > traceRange.getEndTime().getValue() ||
171 checkPoint.getTimestamp().getValue() >= reqWindow.getEndTime().getValue()
550d787e 172 ) {
3f2b9283
FC
173 // checkpoint is out of trace bounds; no need to adjust request for this
174 // trace
175 }
176 else {
177 // use checkpoint time as new startTime for request if it's earlier than
178 // current startTime
a79913eb
FC
179 if (adjustedRange.getStartTime().getValue() > checkPoint.getTimestamp().getValue() || adjustedIndex > (Long) checkPoint.getLocation().getLocation()) {
180 adjustedRange = new TmfTimeRange(checkPoint.getTimestamp(), reqWindow.getEndTime());
181 adjustedIndex = (Long) checkPoint.getLocation().getLocation();
182 if (nbRequested < TmfDataRequest.ALL_DATA) {
183 nbRequested += (eventRequest.getIndex() - adjustedIndex);
184 }
0c32e4c5
AM
185 }
186 }
3f2b9283 187 // Save which trace state model corresponds to current trace
ce970a71 188 traceToTraceStateModel.put(traceManager.getStateTrace(), traceManager.getStateModel());
3f2b9283 189 }
c1c69938 190
3f2b9283 191 dispatchTime = reqWindow.getStartTime().getValue();
a79913eb
FC
192 dispatchIndex = eventRequest.getIndex();
193 eventIndex = adjustedIndex;
c1c69938 194
3f2b9283 195 // Create a single request for all traces in the experiment, with coalesced time range.
c1c69938 196 fSubRequest = new LttngBaseEventRequest(adjustedRange, reqWindow.getStartTime(),
a79913eb 197 adjustedIndex, nbRequested, BLOCK_SIZE, eventRequest.getExecType() /*ITmfDataRequest.ExecutionType.FOREGROUND*/) {
3f2b9283
FC
198
199 private LttngSyntheticEvent syntheticEvent = null;
3f2b9283
FC
200
201 /*
202 * (non-Javadoc)
0c32e4c5 203 *
3f2b9283
FC
204 * @see org.eclipse.linuxtools.lttng.control.LttngEventRequest#handleData()
205 */
206 @Override
0c32e4c5 207 public void handleData(ITmfEvent event) {
3f2b9283
FC
208 super.handleData(event);
209 if (event != null) {
c1c69938
FC
210 synchronized (LttngSyntheticEventProvider.this) {
211 // Check if request was canceled
212 if ((fmainRequest == null) || (fmainRequest.isCompleted()) ) {
9c4eb5f7 213 TraceDebug.debug("fmainRequest was canceled. Ignoring event " + event); //$NON-NLS-1$
c1c69938 214 return;
0c32e4c5 215 }
c1c69938
FC
216
217 handleIncomingData(event);
218 }
3f2b9283 219 } else {
9c4eb5f7 220 TraceDebug.debug("handle data received with no data"); //$NON-NLS-1$
3f2b9283 221 }
5d10d135 222 }
3f2b9283
FC
223
224 /*
225 * (non-Javadoc)
0c32e4c5 226 *
c1c69938 227 * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCompleted()
3f2b9283
FC
228 */
229 @Override
c1c69938 230 public void handleCompleted() {
3f2b9283 231 // mark this sub-request as completed
c1c69938
FC
232 handleProviderDone(!isCancelled() && !isFailed());
233 super.handleCompleted();
550d787e 234 }
5d10d135 235
3f2b9283
FC
236 /**
237 * Trigger the Analysis and sequential control of the events.
0c32e4c5 238 *
3f2b9283
FC
239 * @param e
240 */
0c32e4c5 241 private void handleIncomingData(ITmfEvent e) {
3f2b9283
FC
242 long eventTime = e.getTimestamp().getValue();
243
0c32e4c5 244 ITmfTrace inTrace = e.getTrace();
3f2b9283 245 LttngTraceState traceModel = traceToTraceStateModel.get(inTrace);
0c32e4c5 246
c1c69938 247 // queue the new event data
3f2b9283 248 updateSynEvent(e);
0c32e4c5 249
3f2b9283 250 // If time at or above requested time, update application
a79913eb 251 if (eventTime >= dispatchTime && eventIndex >= dispatchIndex) {
3f2b9283
FC
252 // Before update
253 syntheticEvent.setSequenceInd(SequenceInd.BEFORE);
254 fmainRequest.handleData(syntheticEvent);
3f2b9283
FC
255
256 // Update state locally
257 syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
258 fstateUpdateProcessor.process(syntheticEvent, traceModel);
259
260 // After Update
261 syntheticEvent.setSequenceInd(SequenceInd.AFTER);
262 fmainRequest.handleData(syntheticEvent);
3f2b9283 263
3f2b9283
FC
264 } else {
265 // event time is between checkpoint adjusted time and
266 // requested time i.e. application does not expect the
267 // event, however the state system needs to be re-built
268 // to the dispatch point
269 syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
270 fstateUpdateProcessor.process(syntheticEvent, traceModel);
5d10d135 271 }
a79913eb 272 eventIndex++;
3f2b9283
FC
273 }
274
275 /**
276 * Create a synthetic event from the received new reference, if
277 * the reference is the same there is no need for a new instance
0c32e4c5 278 *
3f2b9283
FC
279 * if this is the first event for this request, call start
280 * handler
0c32e4c5 281 *
3f2b9283
FC
282 * @param e
283 * @return
284 */
0c32e4c5 285 private LttngSyntheticEvent updateSynEvent(ITmfEvent e) {
c1c69938 286 if ((syntheticEvent == null) || (syntheticEvent.getBaseEvent() != e)) {
3f2b9283 287 syntheticEvent = new LttngSyntheticEvent(e);
5d10d135 288 }
3f2b9283 289
0c32e4c5 290 ITmfTrace inTrace = e.getTrace();
3f2b9283 291 LttngTraceState traceModel = traceToTraceStateModel.get(inTrace);
0c32e4c5 292
3f2b9283
FC
293 // Trace model needed by application handlers
294 syntheticEvent.setTraceModel(traceModel);
295
296 // send the start request indication once per request thread
297 if (!startIndSent) {
9c4eb5f7 298 TraceDebug.debug("Thread started: " + Thread.currentThread().getName()); //$NON-NLS-1$
3f2b9283
FC
299 handleProviderStarted(traceModel);
300 startIndSent = true;
5d10d135
ASL
301 }
302
3f2b9283
FC
303 return syntheticEvent;
304 }
305 };
306
307 // start request
0c32e4c5 308 TmfExperiment provider = (TmfExperiment) fExperiment.getValue();
c1c69938 309 provider.sendRequest(fSubRequest);
3f2b9283 310
c1c69938
FC
311 // notify LTTngEvent provider that all requests were sent
312 synchronized (this) {
313 TmfExperiment.getCurrentExperiment().notifyPendingRequest(false);
314 fIsExperimentNotified = false;
315 }
5d10d135 316
9b635e61
FC
317 experiment.endSynch(new TmfEndSynchSignal(0));
318
5d10d135 319 // Return a dummy context, not used for relay provider
c1c69938 320 return new TmfContext();
5d10d135
ASL
321 }
322
323 /**
324 * Notify listeners to prepare to receive data e.g. clean previous data etc.
325 */
c1c69938 326 public synchronized void handleProviderStarted(LttngTraceState traceModel) {
3d62f8b7 327 LttngSyntheticEvent startIndEvent = new LttngSyntheticEvent(fStatusEvent);
5d10d135
ASL
328 startIndEvent.setSequenceInd(SequenceInd.STARTREQ);
329
330 // Notify application
f9673903 331 fmainRequest.handleData(startIndEvent);
5d10d135
ASL
332
333 // Notify state event processor
334 fstateUpdateProcessor.process(startIndEvent, null);
335 }
336
337 /**
f9673903
FC
338 * Notify listeners, no more events for the current request will be
339 * distributed e.g. update view.
5d10d135 340 */
c1c69938 341 public synchronized void handleProviderDone(boolean isSuccess) {
3f2b9283
FC
342 // Notify application. One notification per trace so the last state of each trace can be
343 // drawn
c1c69938
FC
344 for (LttngTraceState traceModel : traceToTraceStateModel.values()) {
345 // Take the trace model from traceToTraceStateModel list since it has a copy
346 // of the state
347 LttngSyntheticEvent finishEvent = new LttngSyntheticEvent(fStatusEvent);
348 finishEvent.setSequenceInd(SequenceInd.ENDREQ);
349 finishEvent.setTraceModel(traceModel);
350
351 fmainRequest.handleData(finishEvent);
352 }
0c32e4c5 353
c1c69938
FC
354 if(isSuccess) {
355 // Finish main request
356 fmainRequest.done();
357 }
358 else {
359 // Cancel main request
360 fmainRequest.cancel();
0c32e4c5 361
c1c69938 362 }
5d10d135
ASL
363 }
364
365 /**
366 * Reset provider to a state ready to begin thread execution
0c32e4c5 367 *
5d10d135
ASL
368 * @param experimentNode
369 */
550d787e 370 public synchronized void reset(LTTngTreeNode experimentNode) {
c1c69938
FC
371
372 conditionallyCancelRequests();
5d10d135 373
550d787e 374 fEventProviderRequests.clear();
5d10d135
ASL
375 startIndSent = false;
376
377 // set of base event providers
378 if (fExperiment != null) {
379 LTTngTreeNode[] traces = fExperiment.getChildren();
380 for (LTTngTreeNode trace : traces) {
381 IStateTraceManager traceBaseEventProvider = (IStateTraceManager) trace;
3f2b9283 382 fEventProviderRequests.add(traceBaseEventProvider);
5d10d135
ASL
383 }
384 }
385
386 if (fExperiment != experimentNode) {
387 updateExperimentNode(experimentNode);
388 }
389 }
390
391 /**
392 * Point to a new experiment reference
0c32e4c5 393 *
5d10d135
ASL
394 * @param experiment
395 */
396 private synchronized void updateExperimentNode(LTTngTreeNode experiment) {
0c32e4c5
AM
397 if (experiment == null) {
398 return;
399 }
400 if (experiment.getValue() instanceof TmfExperiment) {
5d10d135
ASL
401 fExperiment = experiment;
402 } else {
f9a8715c
FC
403 TraceDebug.debug("Experiment received is not instance of TmfExperiment: " //$NON-NLS-1$
404 + experiment.getClass().getName());
5d10d135
ASL
405 }
406 }
407
408 /*
409 * (non-Javadoc)
0c32e4c5 410 *
f9673903
FC
411 * @see
412 * org.eclipse.linuxtools.tmf.component.TmfDataProvider#sendRequest(org.
5d10d135
ASL
413 * eclipse.linuxtools.tmf.request.TmfDataRequest)
414 */
cb866e08 415 @Override
0c32e4c5 416 public void sendRequest(final ITmfDataRequest request) {
c1c69938
FC
417 synchronized (this) {
418 if (!fIsExperimentNotified) {
0c32e4c5 419 TmfExperiment experiment = TmfExperiment.getCurrentExperiment();
c1c69938
FC
420 if (experiment != null) {
421 experiment.notifyPendingRequest(true);
422 fIsExperimentNotified = true;
423 }
424 }
425 }
426
5d10d135
ASL
427 super.sendRequest(request);
428 if (waitForRequest) {
429 try {
430 request.waitForCompletion();
431 } catch (InterruptedException e) {
5d10d135
ASL
432 }
433 }
434 }
435
436 /**
437 * @return the waitForRequest
438 */
439 public boolean isWaitForRequest() {
440 return waitForRequest;
441 }
442
443 /**
444 * @param waitForRequest
445 * configures the provider to wait for the request completion
446 */
447 public void setWaitForRequest(boolean waitForRequest) {
448 this.waitForRequest = waitForRequest;
449 }
450
cb866e08 451 @Override
3d62f8b7
FC
452 public LttngSyntheticEvent getNext(ITmfContext context) {
453 try {
454 fmainRequest.waitForCompletion();
455 } catch (InterruptedException e) {
3d62f8b7
FC
456 }
457 return null;
cb866e08
FC
458 }
459
c1c69938
FC
460 /**
461 * Cancels the ongoing requests for this data provider if necessary
462 */
463 public synchronized void conditionallyCancelRequests() {
464 if ((fSubRequest != null) && (!fSubRequest.isCompleted())) {
0c32e4c5 465
9c4eb5f7 466 TraceDebug.debug("Canceling synthethic event request!"); //$NON-NLS-1$
c1c69938
FC
467
468 // This will also cancel the fmainRequest
469 fSubRequest.cancel();
470 // Reset the request references
471 fSubRequest = null;
472 fmainRequest = null;
473 }
474 }
a79913eb
FC
475
476 @Override
0c32e4c5 477 protected void queueBackgroundRequest(ITmfDataRequest request, int blockSize, boolean indexing) {
a79913eb
FC
478 // do not split background synthetic requests
479 queueRequest(request);
480 }
5d10d135 481}
This page took 0.102374 seconds and 5 git commands to generate.