1 /*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
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
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.state
.trace
;
14 import java
.util
.Collections
;
15 import java
.util
.HashMap
;
16 import java
.util
.Vector
;
18 import org
.eclipse
.linuxtools
.lttng
.TraceDebug
;
19 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
20 import org
.eclipse
.linuxtools
.lttng
.event
.LttngSyntheticEvent
;
21 import org
.eclipse
.linuxtools
.lttng
.event
.LttngSyntheticEvent
.SequenceInd
;
22 import org
.eclipse
.linuxtools
.lttng
.event
.LttngTimestamp
;
23 import org
.eclipse
.linuxtools
.lttng
.model
.LTTngTreeNode
;
24 import org
.eclipse
.linuxtools
.lttng
.request
.ILttngSyntEventRequest
;
25 import org
.eclipse
.linuxtools
.lttng
.request
.IRequestStatusListener
;
26 import org
.eclipse
.linuxtools
.lttng
.request
.LttngSyntEventRequest
;
27 import org
.eclipse
.linuxtools
.lttng
.state
.LttngStateException
;
28 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.ITransEventProcessor
;
29 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.state
.StateEventToHandlerFactory
;
30 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTraceState
;
31 import org
.eclipse
.linuxtools
.lttng
.state
.model
.StateModelFactory
;
32 import org
.eclipse
.linuxtools
.lttng
.state
.resource
.ILttngStateContext
;
33 import org
.eclipse
.linuxtools
.lttng
.trace
.LTTngTextTrace
;
34 import org
.eclipse
.linuxtools
.lttng
.trace
.LTTngTrace
;
35 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
36 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
37 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
38 import org
.eclipse
.linuxtools
.tmf
.experiment
.TmfExperiment
;
39 import org
.eclipse
.linuxtools
.tmf
.request
.TmfDataRequest
;
40 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfTrace
;
41 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfCheckpoint
;
42 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfLocation
;
44 public class StateTraceManager
extends LTTngTreeNode
implements IStateTraceManager
, ILttngStateContext
{
47 private static final long DEFAULT_OFFSET
= 0L;
48 private static final int DEFAULT_CHUNK
= 1;
50 // configurable check point interval
51 private static final long LTTNG_CHECK_POINT_INTERVAL
= 50000L;
52 private long fcheckPointInterval
= LTTNG_CHECK_POINT_INTERVAL
;
54 private TmfExperiment
<LttngEvent
> fExperiment
= null;
57 private final ITmfTrace fTrace
;
58 private int fcpuNumber
= -1;
59 private final ITransEventProcessor fStateUpdateProcessor
;
61 // potentially thread shared
62 private final HashMap
<Long
, LttngTraceState
> stateCheckpointsList
= new HashMap
<Long
, LttngTraceState
>();
63 private final Vector
<TmfCheckpoint
> timestampCheckpointsList
= new Vector
<TmfCheckpoint
>();
64 private LttngTraceState fStateModel
;
65 private LttngTraceState fCheckPointStateModel
;
68 private Object fCheckPointsLock
= new Object();
69 private Object fStateModelLock
= new Object();
73 // =======================================================================
75 // =======================================================================
81 * @throws LttngStateException
83 public StateTraceManager(Long id
, LTTngTreeNode parent
, String name
, ITmfTrace trace
) throws LttngStateException
{
84 super(id
, parent
, name
, trace
);
87 throw new LttngStateException("No TmfTrace object available!"); //$NON-NLS-1$
91 fStateUpdateProcessor
= StateEventToHandlerFactory
.getInstance();
95 fStateModel
= StateModelFactory
.getStateEntryInstance(this);
96 fStateModel
.init(this);
98 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
99 fCheckPointStateModel
.init(this);
102 // =======================================================================
104 // =======================================================================
105 @SuppressWarnings("unchecked")
106 private void init() {
107 // resolve the experiment
108 Object obj
= getParent().getValue();
109 if (obj
!= null && obj
instanceof TmfExperiment
<?
>) {
110 fExperiment
= (TmfExperiment
<LttngEvent
>) obj
;
113 // initialize the number of cpus
114 if (fTrace
instanceof LTTngTrace
) {
115 fcpuNumber
= ((LTTngTrace
) fTrace
).getCpuNumber();
116 } else if (fTrace
instanceof LTTngTextTrace
) {
117 fcpuNumber
= ((LTTngTextTrace
) fTrace
).getCpuNumber();
128 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
131 public ITmfTrace
getTrace() {
136 * Save a checkpoint if it is needed at that point
138 * The function will use "eventCount" internally to determine if a save was
141 * @param eventCounter
142 * The event "count" or event "id" so far
144 * The timestamp of this event
146 * @return boolean True if a checkpoint was saved, false otherwise
148 private void saveCheckPointIfNeeded(Long eventCounter
, TmfTimestamp eventTime
) {
149 // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
150 if ((eventCounter
.longValue() % fcheckPointInterval
) == 0) {
152 LttngTraceState stateCheckPoint
;
153 synchronized (fCheckPointsLock
) {
154 stateCheckPoint
= fCheckPointStateModel
.clone();
157 TraceDebug
.debug("Check point created here: " + eventCounter
//$NON-NLS-1$
158 + " -> " + eventTime
.toString() + "************" //$NON-NLS-1$ //$NON-NLS-2$
159 + getTrace().getName() + " >>>>> Thread: " //$NON-NLS-1$
160 + Thread
.currentThread().getId());
162 synchronized (fCheckPointsLock
) {
163 // Save the checkpoint
164 stateCheckpointsList
.put(eventCounter
, stateCheckPoint
);
165 // Save correlation between timestamp and checkpoint index
167 timestampCheckpointsList
.add(new TmfCheckpoint(new TmfTimestamp(eventTime
), new TmfLocation
<Long
>(
174 * @return the lttng_check_point_interval
176 public long getCheckPointInterval() {
177 return fcheckPointInterval
;
181 * @param check_point_interval
182 * , the lttng_check_point_interval to set
184 public void setCheckPointInterval(long check_point_interval
) {
185 this.fcheckPointInterval
= check_point_interval
;
191 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
192 * restoreCheckPointByTimestamp
193 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
196 @SuppressWarnings("unchecked")
197 public TmfCheckpoint
restoreCheckPointByTimestamp(TmfTimestamp eventTime
) {
198 TmfTimeRange experimentRange
= fExperiment
.getTimeRange();
199 TmfCheckpoint checkpoint
= new TmfCheckpoint(fTrace
.getStartTime(), new TmfLocation
<Long
>(0L));
201 // The GUI can have time limits higher than this log, since GUI can
202 // handle multiple logs. Ignore special null value of experiment time range.
203 if ((eventTime
.getValue() < 0) ||
204 (!experimentRange
.equals(TmfTimeRange
.Null
) && (eventTime
.getValue() > experimentRange
.getEndTime().getValue()))) {
208 // The GUI can have time limits lower than this trace, since experiment
209 // can handle multiple traces
210 if ((eventTime
.getValue() < fTrace
.getStartTime().getValue())) {
211 eventTime
= fTrace
.getStartTime();
214 LttngTraceState traceState
;
215 synchronized (fCheckPointsLock
) {
216 Collections
.sort(timestampCheckpointsList
);
217 // Initiate the compare with a checkpoint containing the target time
219 int index
= Collections
.binarySearch(timestampCheckpointsList
, new TmfCheckpoint(eventTime
,
220 new TmfLocation
<Long
>(0L)));
221 // adjust index to round down to earlier checkpoint when exact match
224 index
= getPrevIndex(index
);
227 // No checkpoint restore is needed, start with a brand new
229 traceState
= StateModelFactory
.getStateEntryInstance(this);
232 // Useful CheckPoint found
233 checkpoint
= timestampCheckpointsList
.get(index
);
234 // get the location associated with the checkpoint
235 TmfLocation
<Long
> location
= (TmfLocation
<Long
>) checkpoint
.getLocation();
236 // reference a new copy of the checkpoint template
237 traceState
= stateCheckpointsList
.get(location
.getLocation()).clone();
242 // Restore the stored traceState
243 synchronized (fStateModelLock
) {
244 fStateModel
= traceState
;
251 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#restoreCheckPointByIndex(long)
254 public TmfCheckpoint
restoreCheckPointByIndex(long eventIndex
) {
255 TmfCheckpoint checkpoint
= new TmfCheckpoint(fTrace
.getStartTime(), new TmfLocation
<Long
>(0L));
257 LttngTraceState traceState
;
258 synchronized (fCheckPointsLock
) {
259 Collections
.sort(timestampCheckpointsList
);
260 // Initiate the compare with a checkpoint containing the target time
262 int index
= Collections
.binarySearch(timestampCheckpointsList
, new TmfCheckpoint(null,
263 new TmfLocation
<Long
>(eventIndex
)));
264 // adjust index to round down to earlier checkpoint when exact match not found
265 index
= getPrevIndex(index
);
268 // No checkpoint restore is needed, start with a brand new
270 traceState
= StateModelFactory
.getStateEntryInstance(this);
273 // Useful CheckPoint found
274 checkpoint
= timestampCheckpointsList
.get(index
);
275 // get the location associated with the checkpoint
276 @SuppressWarnings("unchecked")
277 TmfLocation
<Long
> location
= (TmfLocation
<Long
>) checkpoint
.getLocation();
278 // reference a new copy of the checkpoint template
279 traceState
= stateCheckpointsList
.get(location
.getLocation()).clone();
284 // Restore the stored traceState
285 synchronized (fStateModelLock
) {
286 fStateModel
= traceState
;
293 * Adjust the result from a binary search to the round down position
296 * if Negative is: (-(insertion point) -1)
297 * @return position or if no match found, earlier than insertion point
299 private int getPrevIndex(int position
) {
300 int roundDownPosition
= position
;
302 roundDownPosition
= -(position
+ 2);
305 roundDownPosition
= roundDownPosition
< 0 ?
0 : roundDownPosition
;
306 return roundDownPosition
;
309 // TODO: Remove this request type when the UI handle their own requests
311 * Request Event data of a specified time range
316 * @return ILttngEventRequest The request made
318 ILttngSyntEventRequest
getDataRequestByTimeRange(TmfTimeRange timeWindow
, IRequestStatusListener listener
,
319 final ITransEventProcessor processor
) {
321 ILttngSyntEventRequest request
= new StateTraceManagerRequest(timeWindow
, DEFAULT_OFFSET
,
322 TmfDataRequest
.ALL_DATA
, DEFAULT_CHUNK
, listener
, getExperimentTimeWindow(), processor
) {
333 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
337 public LttngTraceState
getStateModel() {
338 LttngTraceState stateModel
= null;
339 synchronized (fStateModelLock
) {
340 stateModel
= fStateModel
;
348 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
349 * getCheckPointStateModel()
352 public LttngTraceState
getCheckPointStateModel() {
353 LttngTraceState checkPointStateModel
= null;
354 synchronized (fCheckPointsLock
) {
355 checkPointStateModel
= fCheckPointStateModel
;
357 return checkPointStateModel
;
361 * @return the stateCheckpointsList
363 HashMap
<Long
, LttngTraceState
> getStateCheckpointsList() {
364 return stateCheckpointsList
;
368 * @return the timestampCheckpointsList
370 Vector
<TmfCheckpoint
> getTimestampCheckpointsList() {
371 return timestampCheckpointsList
;
373 // =======================================================================
375 // =======================================================================
376 class StateTraceManagerRequest
extends LttngSyntEventRequest
{
377 // =======================================================================
379 // =======================================================================
380 final TmfEvent
[] evt
= new TmfEvent
[1];
381 final ITransEventProcessor fprocessor
;
382 LttngSyntheticEvent synEvent
;
383 Long fCount
= getSynEventCount();
385 // =======================================================================
387 // =======================================================================
388 public StateTraceManagerRequest(TmfTimeRange range
, long offset
, int nbEvents
, int maxBlockSize
,
389 IRequestStatusListener listener
, TmfTimeRange experimentTimeRange
, ITransEventProcessor processor
) {
391 super(range
, offset
, nbEvents
, maxBlockSize
, listener
, experimentTimeRange
, processor
);
392 fprocessor
= processor
;
393 TraceDebug
.debug("Instance created for range: " + range
.toString()); //$NON-NLS-1$
397 // =======================================================================
399 // =======================================================================
404 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
408 public void handleData(LttngSyntheticEvent event
) {
409 super.handleData(event
);
412 if (synEvent
.getSynType() == SequenceInd
.AFTER
) {
413 // Note : We call this function before incrementing
414 // eventCount to save a default check point at the "0th"
416 saveCheckPoint(fCount
, synEvent
.getTimestamp());
419 if (TraceDebug
.isDEBUG()) {
420 if (fCount
% 1000 == 0) {
421 TraceDebug
.debug("handled: " + fCount
+ " sequence: " + synEvent
.getSynType()); //$NON-NLS-1$ //$NON-NLS-2$
429 * To be overridden by active save e.g. check points, this no action
430 * default is used for requests which do not require rebuilding of
431 * checkpoints e.g. requiring data of a new time range selection
436 public void saveCheckPoint(Long count
, TmfTimestamp time
) {
444 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
448 public int getNumberOfCpus() {
455 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
456 * getTraceTimeWindow()
459 public TmfTimeRange
getTraceTimeWindow() {
460 if (fTrace
!= null) {
461 return fTrace
.getTimeRange();
471 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
475 public String
getTraceId() {
476 if (fTrace
!= null) {
477 return fTrace
.getName();
485 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
486 * getExperimentTimeWindow()
489 public TmfTimeRange
getExperimentTimeWindow() {
490 if (fExperiment
!= null) {
491 return fExperiment
.getTimeRange();
500 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
504 public String
getExperimentName() {
505 return fExperiment
.getName();
512 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
516 public ITmfTrace
getTraceIdRef() {
524 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
528 public void clearCheckPoints() {
529 synchronized (fCheckPointsLock
) {
530 stateCheckpointsList
.clear();
531 timestampCheckpointsList
.clear();
533 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
536 fCheckPointStateModel
.init(this);
537 } catch (LttngStateException e
) {
547 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
548 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
551 public void handleEvent(LttngSyntheticEvent synEvent
, Long eventCount
) {
552 fStateUpdateProcessor
.process(synEvent
, fCheckPointStateModel
);
554 // Save checkpoint as needed
555 saveCheckPointIfNeeded(eventCount
- 1, synEvent
.getTimestamp());
561 * @see java.lang.Object#toString()
564 @SuppressWarnings("nls")
565 public String
toString() {
566 StringBuilder sb
= new StringBuilder(super.toString());
567 sb
.append("\n\tTotal number of processes in the Shared State model: " + fStateModel
.getProcesses().length
568 + "\n\t" + "Total number of processes in the Check point State model: "
569 + fCheckPointStateModel
.getProcesses().length
);
571 TmfTimeRange traceTRange
= fTrace
.getTimeRange();
572 sb
.append("\n\tTrace time interval for trace " + fTrace
.getName() + "\n\t"
573 + new LttngTimestamp(traceTRange
.getStartTime()));
574 sb
.append(" - " + new LttngTimestamp(traceTRange
.getEndTime()));
575 sb
.append("\n\tCheckPoints available at: ");
576 for (TmfCheckpoint cpoint
: timestampCheckpointsList
) {
577 sb
.append("\n\t" + "Location: " + cpoint
.getLocation() + " - " + cpoint
.getTimestamp());
580 return sb
.toString();
585 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getIdentifier()
588 public long getIdentifier() {
589 return getId().longValue();