Added TMF statistics feature (Bug 360572)
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / state / experiment / StateExperimentManager.java
CommitLineData
5d10d135 1/*******************************************************************************
3f2b9283 2 * Copyright (c) 2009, 2010 Ericsson
5d10d135
ASL
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 * Contributors:
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
3f2b9283 11 * Marc Dumais (marc.dumais@ericsson.com) - Fix for 316455 (second part)
5d10d135
ASL
12 *******************************************************************************/
13package org.eclipse.linuxtools.lttng.state.experiment;
14
550d787e
FC
15import java.util.HashMap;
16import java.util.Map;
17
8016d660 18import org.eclipse.linuxtools.lttng.LttngConstants;
8827c197
FC
19import org.eclipse.linuxtools.lttng.TraceDebug;
20import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory;
e31e01e8 21import org.eclipse.linuxtools.lttng.event.LttngEvent;
550d787e
FC
22import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
23import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
8827c197 24import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
8827c197
FC
25import org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener;
26import org.eclipse.linuxtools.lttng.signal.StateExperimentListener;
c1c69938 27import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
8827c197 28import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager;
5d10d135 29import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
e31e01e8 30import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
550d787e
FC
31import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
32import org.eclipse.linuxtools.tmf.request.ITmfEventRequest;
550d787e 33import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
a79913eb 34import org.eclipse.linuxtools.tmf.signal.TmfExperimentRangeUpdatedSignal;
8827c197 35import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
5d10d135
ASL
36
37/**
38 * @author alvaro
39 *
40 */
8827c197
FC
41public class StateExperimentManager extends LTTngTreeNode implements
42 ILttExperimentSelectedListener, IStateExperimentManager {
5d10d135
ASL
43
44 // ========================================================================
45 // Data
46 // =======================================================================
8827c197
FC
47 private LTTngTreeNode fSelectedExperiment = null; // one selected experiment
48 // supported
49 private final StateExperimentListener fexperimentListener;
50 private boolean fwaitForCompletion = false;
550d787e
FC
51 /**
52 * Used to route incoming events to proper trace manager, during check point
53 * building
54 */
c1c69938
FC
55 private final Map<ITmfTrace, StateTraceHelper> ftraceToManagerMap = new HashMap<ITmfTrace, StateTraceHelper>();
56
550d787e 57 private LttngSyntheticEvent syntheticEvent = null;
a79913eb
FC
58 private ITmfDataRequest<LttngEvent> fStateCheckPointRequest = null;
59 private boolean fCheckPointUpdateBusy = false;
60 private boolean fCheckPointUpdatePending = false;
61 private int fCheckPointUpdateIndex = 0;
62 private TmfTimeRange fCheckPointUpdateRange = null;
63 private long fCheckPointNbEventsHandled = 0;
64 private final Object fCheckPointUpdateSyncObj = new Object();
8827c197 65
5d10d135
ASL
66
67 // ========================================================================
68 // Constructors
69 // =======================================================================
8827c197
FC
70 public StateExperimentManager(Long id, String name) {
71 super(id, null, name, null);
9c4eb5f7 72 fexperimentListener = new StateExperimentListener("Experiment Manager", this); //$NON-NLS-1$
88144d4a 73 }
5d10d135 74
8827c197 75
5d10d135
ASL
76 // ========================================================================
77 // Methods
78 // =======================================================================
79
550d787e
FC
80// /* (non-Javadoc)
81// * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperimentTimeWindow(org.eclipse.linuxtools.tmf.event.TmfTimeRange, java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
82// */
83// public ILttngSyntEventRequest readExperimentTimeWindow(TmfTimeRange trange,
84// Object source, IRequestStatusListener listener,
85// ITransEventProcessor processor) {
86//
87// ILttngSyntEventRequest request = null;
88//
89// // validate
90// if (fSelectedExperiment != null) {
91// // Get all trace manager nodes
92// LTTngTreeNode[] traceMgrs = fSelectedExperiment.getChildren();
93//
94// if (traceMgrs != null && traceMgrs.length > 0) {
95// IStateTraceManager traceManager;
96// // Trigger one request per trace
97// for (LTTngTreeNode traceNode : traceMgrs) {
98// traceManager = (IStateTraceManager) traceNode;
99// request = traceManager.executeDataRequest(trange, source,
100// listener,
101// processor);
102// }
103// }
104// } else {
105// if (fSelectedExperiment == null) {
106// TraceDebug.debug("No experiment selected");
107// }
108// }
109//
110// return request;
111// }
5d10d135 112
550d787e
FC
113// /* (non-Javadoc)
114// * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperiment(java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
115// */
116// @SuppressWarnings("unchecked")
117// public void readExperiment(Object source, IRequestStatusListener listener,
118// ITransEventProcessor processor) {
119// // validate
120// if (fSelectedExperiment != null) {
121// TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) fSelectedExperiment
122// .getValue();
123// TmfTimeRange trange = experiment.getTimeRange();
124// readExperimentTimeWindow(trange, source, listener, processor);
125// } else {
126// TraceDebug.debug("No selected experiment available");
127// }
128// }
88144d4a 129
8827c197
FC
130
131
5d10d135
ASL
132 /*
133 * (non-Javadoc)
134 *
88144d4a 135 * @see
8827c197
FC
136 * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
137 * #experimentSelected_prep
138 * (org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
5d10d135 139 */
d4011df2 140 @Override
8827c197 141 public void experimentSelected_prep(TmfExperiment<LttngEvent> experiment) {
6b4cd5bf
FC
142
143 if (fSelectedExperiment != null) {
144 clearExperimentNode(fSelectedExperiment);
145 fSelectedExperiment = null;
146 }
147
8827c197
FC
148 LTTngTreeNode experimentNode = null;
149 if (experiment != null) {
150 experimentNode = getChildByName(experiment.getName());
151 // keep experiment if already loaded with the same value
152 if (experimentNode != null
153 && experimentNode.getValue() != experiment) {
6b4cd5bf 154 clearExperimentNode(experimentNode);
8827c197
FC
155 experimentNode = null;
156 }
157
158 // Make sure all traces involved have a corresponding state manager
159 // and
160 // state system to request its initial data
161 if (experimentNode == null) {
162 // Create the new experiment tree node
163 experimentNode = new LTTngTreeNode(getNextUniqueId(), this,
164 experiment.getName(), experiment);
165 // add the new experiment to this children list
166 addChild(experimentNode);
167 }
168
169 // Make sure the traces exists in the tree
170 ITmfTrace[] rtraces = experiment.getTraces();
171 String traceName;
172 LTTngTreeNode traceStateManagerNode;
173 // StateStacksHandler
174 for (ITmfTrace rtrace : rtraces) {
175 traceName = rtrace.getName();
176 traceStateManagerNode = experimentNode.getChildByName(traceName);
177 // Node does not exist for this experiment, so needs to be
178 // created
179 if (traceStateManagerNode == null) {
180 traceStateManagerNode = StateManagerFactory.getManager(
181 rtrace, experimentNode);
182 experimentNode.addChild(traceStateManagerNode);
183 }
184 }
185
186 // Reset event provider to handle requests for the new experiment
c1c69938 187 LttngCoreProviderFactory.reset(experimentNode);
8827c197
FC
188
189 // preserve the selected experiment
190 fSelectedExperiment = experimentNode;
88144d4a 191 }
5d10d135
ASL
192 }
193
6b4cd5bf
FC
194
195 private void clearExperimentNode(LTTngTreeNode experimentNode) {
196 // Remove checkpoints
197 LTTngTreeNode[] traceNodes = experimentNode.getChildren();
198
199 for (LTTngTreeNode traceStateManagerNode : traceNodes) {
200 IStateTraceManager traceManager = null;
201 try {
202 traceManager = (IStateTraceManager) traceStateManagerNode;
203 // Clear all previously created check points as preparation to
204 // re-build
205 traceManager.clearCheckPoints();
206 experimentNode.removeChild(traceStateManagerNode);
207 } catch (ClassCastException e) {
208 // Nothing to do
209 }
210
211 // rebuild the experiment nodes from scratch
212 removeChild(experimentNode);
213 }
214 }
215
8827c197
FC
216 /*
217 * (non-Javadoc)
88144d4a 218 *
8827c197
FC
219 * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
220 * experimentSelected(java.lang.Object,
221 * org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
5d10d135 222 */
d4011df2 223 @Override
8827c197
FC
224 public void experimentSelected(Object source,
225 TmfExperiment<LttngEvent> experiment) {
226 // validate
550d787e 227 if (experiment == null) {
a79913eb 228 TraceDebug.debug("Received experiment is null"); //$NON-NLS-1$
8827c197
FC
229 return;
230 }
231
550d787e
FC
232 // If previous request is ongoing, cancel it before requesting a new
233 // one.
234 if (fStateCheckPointRequest != null && !fStateCheckPointRequest.isCompleted()) {
235 fStateCheckPointRequest.cancel();
8827c197 236 }
550d787e 237
a79913eb
FC
238 synchronized (fCheckPointUpdateSyncObj) {
239 fCheckPointUpdateBusy = true;
240 fCheckPointUpdatePending = false;
241 fCheckPointUpdateIndex = 0;
242 }
243
550d787e 244 // trigger data request to build the state system check points
a79913eb
FC
245 fStateCheckPointRequest = buildCheckPoints(experiment, experiment.getTimeRange(), true);
246
247 if (fStateCheckPointRequest == null) {
248 synchronized (fCheckPointUpdateSyncObj) {
249 fCheckPointUpdateBusy = false;
250 }
251 }
5d10d135
ASL
252 }
253
8827c197
FC
254 /*
255 * (non-Javadoc)
256 *
257 * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
258 * experimentUpdated
259 * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean)
260 */
a79913eb 261 @SuppressWarnings("unchecked")
d4011df2 262 @Override
a79913eb
FC
263 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
264 TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
265 // validate
266 if (experiment != fSelectedExperiment.getValue()) {
267 return;
268 }
269
270 synchronized (fCheckPointUpdateSyncObj) {
271 if (fCheckPointUpdateBusy) {
272 fCheckPointUpdatePending = true;
273 fCheckPointUpdateRange = signal.getRange();
274 return;
275 } else {
276 fCheckPointUpdateBusy = true;
277 }
278 }
279
280 // If previous request is ongoing, cancel it before requesting a new
281 // one.
282 if (fStateCheckPointRequest != null && !fStateCheckPointRequest.isCompleted()) {
283 fStateCheckPointRequest.cancel();
284 }
285
286 // trigger data request to build the state system check points
287 fStateCheckPointRequest = buildCheckPoints(experiment, signal.getRange(), false);
288
289 if (fStateCheckPointRequest == null) {
290 synchronized (fCheckPointUpdateSyncObj) {
291 fCheckPointUpdateBusy = false;
292 }
293 }
8827c197
FC
294 }
295
296
88144d4a 297 /**
8827c197
FC
298 * @return the SelectedExperiment tree node
299 */
d4011df2 300 @Override
8827c197
FC
301 public LTTngTreeNode getSelectedExperiment() {
302 return fSelectedExperiment;
303 }
304
305 /* (non-Javadoc)
306 * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange()
5d10d135 307 */
d4011df2 308 @Override
8827c197 309 @SuppressWarnings("unchecked")
5d10d135
ASL
310 public TmfTimeRange getExperimentTimeRange() {
311 TmfTimeRange timeRangeResult = null;
8827c197
FC
312 if (fSelectedExperiment != null) {
313 timeRangeResult = ((TmfExperiment<LttngEvent>) fSelectedExperiment
314 .getValue()).getTimeRange();
5d10d135
ASL
315 }
316 return timeRangeResult;
317 }
318
8827c197
FC
319 /*
320 * (non-Javadoc)
321 *
322 * @see java.lang.Object#finalize()
323 */
550d787e 324 @Override
8827c197
FC
325 protected void finalize() {
326 fexperimentListener.dispose();
327 }
328
329
330 /*
331 * (non-Javadoc)
332 *
333 * @see
334 * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
335 * #waitForComplete(boolean)
336 */
d4011df2 337 @Override
8827c197
FC
338 public void waitForCompletion(boolean wait) {
339 fwaitForCompletion = wait;
340 }
341
a79913eb 342 private ITmfDataRequest<LttngEvent> buildCheckPoints(final TmfExperiment<LttngEvent> experiment, final TmfTimeRange range, boolean initial) {
550d787e
FC
343 // validate
344 if (experiment == null) {
a79913eb 345 TraceDebug.debug("Received experiment is null"); //$NON-NLS-1$
550d787e
FC
346 return null;
347 }
348
349 LTTngTreeNode experimentNode = getChildByName(experiment.getName());
350 if (experimentNode == null) {
a79913eb 351 TraceDebug.debug("Experiment Node " + experiment.getName() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$
550d787e
FC
352 return null;
353 }
354
a79913eb
FC
355 final boolean waitForCompletion = fwaitForCompletion;
356
550d787e
FC
357 // get the trace manager nodes associated to the experiment
358 LTTngTreeNode[] traceNodes = experimentNode.getChildren();
550d787e 359
a79913eb 360 if (initial) {
550d787e 361 synchronized (this) {
a79913eb
FC
362 ftraceToManagerMap.clear();
363 }
364
365 ITmfTrace trace;
366 for (LTTngTreeNode traceStateManagerNode : traceNodes) {
367 IStateTraceManager traceManager;
368 try {
369 traceManager = (IStateTraceManager) traceStateManagerNode;
370 } catch (ClassCastException e) {
371 System.out.println(e.getStackTrace().toString());
372 return null;
373 }
374
375 // Clear all previously created check points as preparation to
376 // re-build
377 traceManager.clearCheckPoints();
378
379 // build the trace to manager mapping for event dispatching
380 trace = traceManager.getTrace();
381 synchronized (this) {
382 ftraceToManagerMap.put(trace, new StateTraceHelper(traceManager));
383 }
550d787e
FC
384 }
385 }
c1c69938 386
550d787e
FC
387 // if no trace mapping
388 if (ftraceToManagerMap.size() < 1) {
9c4eb5f7 389 TraceDebug.debug("No traces associated to experiment " + experiment.getName()); //$NON-NLS-1$
550d787e
FC
390 return null;
391 }
392
a79913eb
FC
393 fCheckPointNbEventsHandled = 0;
394
550d787e
FC
395 // Prepare event data request to build state model
396 ITmfEventRequest<LttngEvent> request = new TmfEventRequest<LttngEvent>(
a79913eb
FC
397 LttngEvent.class, range, fCheckPointUpdateIndex,
398 TmfEventRequest.ALL_DATA, LttngConstants.DEFAULT_BLOCK_SIZE, ITmfDataRequest.ExecutionType.BACKGROUND) {
550d787e 399
550d787e
FC
400 /*
401 * (non-Javadoc)
402 *
403 * @see
404 * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData()
405 */
406 @Override
f9673903
FC
407 public void handleData(LttngEvent event) {
408 super.handleData(event);
409 if (event != null) {
9b635e61 410// Tracer.trace("Chk: " + event.getTimestamp());
a79913eb 411 fCheckPointNbEventsHandled++;
550d787e 412 ITmfTrace trace = event.getParentTrace();
c1c69938
FC
413
414 StateTraceHelper helper = ftraceToManagerMap.get(trace);
415
416 if (helper != null) {
417 helper.incrementNumberRead();
418
550d787e 419 // obtain synthetic event
c1c69938
FC
420 LttngSyntheticEvent synEvent = updateSynEvent(event, helper.getTraceModel());
421
550d787e 422 // update state system, and save check points as needed
c1c69938 423 helper.getStateManager().handleEvent(synEvent, helper.getNumberRead());
550d787e 424 } else {
9c4eb5f7 425 TraceDebug.debug("StateTraceManager not found for trace" //$NON-NLS-1$
c1c69938 426 + trace.getName());
550d787e
FC
427 }
428 }
429 }
c1c69938 430
550d787e
FC
431 /*
432 * (non-Javadoc)
433 *
434 * @see
a79913eb 435 * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCompleted()
550d787e 436 */
cb866e08 437 @Override
a79913eb
FC
438 public void handleCompleted() {
439 super.handleCompleted();
550d787e 440 printCompletedMessage();
a79913eb
FC
441
442 if (!waitForCompletion) {
443 synchronized (fCheckPointUpdateSyncObj) {
444 fCheckPointUpdateBusy = false;
445 fCheckPointUpdateIndex += fCheckPointNbEventsHandled;
446 if (fCheckPointUpdatePending) {
447 fCheckPointUpdatePending = false;
448 fCheckPointUpdateBusy = true;
449 buildCheckPoints(experiment, fCheckPointUpdateRange, false);
450 }
451 }
452 }
550d787e 453 }
c1c69938 454
550d787e 455 /*
550d787e
FC
456 /**
457 * @param header
458 */
459 private void printCompletedMessage() {
550d787e 460 if (TraceDebug.isDEBUG()) {
a79913eb 461 TraceDebug.debug("Trace check point building completed, number of events handled: " + fCheckPointNbEventsHandled + "\n\t\t"); //$NON-NLS-1$ //$NON-NLS-2$
c1c69938 462 for (StateTraceHelper helper : ftraceToManagerMap.values()) {
9c4eb5f7 463 TraceDebug.debug(helper.getStateManager().toString() + "\n\t\t"); //$NON-NLS-1$
550d787e
FC
464 }
465 }
466 }
467 };
c1c69938 468
550d787e
FC
469 // Execute event data request
470 experiment.sendRequest(request);
471
a79913eb 472 if (waitForCompletion) {
550d787e
FC
473 try {
474 request.waitForCompletion();
a79913eb
FC
475 synchronized (fCheckPointUpdateSyncObj) {
476 fCheckPointUpdateBusy = false;
477 fCheckPointUpdateIndex += fCheckPointNbEventsHandled;
478 if (fCheckPointUpdatePending) {
479 fCheckPointUpdatePending = false;
480 fCheckPointUpdateBusy = true;
481 buildCheckPoints(experiment, fCheckPointUpdateRange, false);
482 }
483 }
550d787e
FC
484 } catch (InterruptedException e) {
485 e.printStackTrace();
486 }
487 }
488
489 return request;
490 }
491
c1c69938 492 private LttngSyntheticEvent updateSynEvent(LttngEvent e, LttngTraceState stateModel) {
550d787e
FC
493 if (syntheticEvent == null || syntheticEvent.getBaseEvent() != e) {
494 syntheticEvent = new LttngSyntheticEvent(e);
495 }
496
497 // Trace model needed by application handlers
c1c69938 498 syntheticEvent.setTraceModel(stateModel);
550d787e
FC
499 syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
500
501 return syntheticEvent;
502 }
503
c1c69938
FC
504 /**
505 * Helper class that wraps the StateTraceManager, the current
506 * LTTngTraceState and the number of read events
507 *
508 * @author bHufmann
509 *
510 */
511 private class StateTraceHelper {
512
513 IStateTraceManager stateTraceManager = null;
514 long numberEventsRead = 0;
515 LttngTraceState stateTraceModel = null;
516
517 /**
518 * Constructor
519 *
520 * @param stateManager
521 * The StateTraceManager the helper is for
522 */
523 public StateTraceHelper(IStateTraceManager stateManager) {
524 this.stateTraceManager = stateManager;
525 // Get the TraceState at the beginning of the trace
526 this.stateTraceManager.restoreCheckPointByTimestamp(stateManager
527 .getTrace().getStartTime());
528 this.stateTraceModel = this.stateTraceManager.getStateModel();
529 }
530
531 /**
532 * Returns the StateTraceManager
533 *
534 * @return IStateTraceManager
535 */
536 public IStateTraceManager getStateManager() {
537 return stateTraceManager;
538 }
539
540 /**
541 * Returns the number of read events
542 *
543 * @return long
544 */
545 public long getNumberRead() {
546 return numberEventsRead;
547 }
548
549 /**
550 * Increments the number of read events
551 */
552 public void incrementNumberRead() {
553 ++numberEventsRead;
554 }
555
556 /**
557 * Returns the current LTTngTraceState
558 *
559 * @return LttngTraceState
560 */
561 public LttngTraceState getTraceModel() {
562 return stateTraceModel;
563 }
564 }
e31e01e8 565}
This page took 0.058462 seconds and 5 git commands to generate.