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