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
.internal
.lttng
.core
.state
.trace
;
14 import java
.util
.Collections
;
15 import java
.util
.HashMap
;
16 import java
.util
.Vector
;
18 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.Activator
;
19 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.TraceDebug
;
20 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.event
.LttngSyntheticEvent
;
21 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.event
.LttngSyntheticEvent
.SequenceInd
;
22 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.event
.LttngTimestamp
;
23 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.model
.LTTngTreeNode
;
24 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.request
.ILttngSyntEventRequest
;
25 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.request
.IRequestStatusListener
;
26 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.request
.LttngSyntEventRequest
;
27 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.LttngStateException
;
28 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.evProcessor
.ITransEventProcessor
;
29 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.evProcessor
.state
.StateEventToHandlerFactory
;
30 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.model
.LttngTraceState
;
31 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.model
.StateModelFactory
;
32 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.state
.resource
.ILttngStateContext
;
33 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.trace
.LTTngTextTrace
;
34 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.trace
.LTTngTrace
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEvent
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimeRange
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.request
.TmfDataRequest
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfCheckpoint
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfContext
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfExperiment
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfLocation
;
47 public class StateTraceManager
extends LTTngTreeNode
implements
48 IStateTraceManager
, ILttngStateContext
{
51 private static final long DEFAULT_OFFSET
= 0L;
52 private static final int DEFAULT_CHUNK
= 1;
54 // configurable check point interval
55 private static final long LTTNG_CHECK_POINT_INTERVAL
= 50000L;
56 private long fcheckPointInterval
= LTTNG_CHECK_POINT_INTERVAL
;
58 private TmfExperiment fExperiment
= null;
61 private final ITmfTrace fTrace
;
62 private int fcpuNumber
= -1;
63 private final ITransEventProcessor fStateUpdateProcessor
;
65 // potentially thread shared
66 private final HashMap
<Long
, LttngTraceState
> stateCheckpointsList
= new HashMap
<Long
, LttngTraceState
>();
67 private final Vector
<TmfCheckpoint
> timestampCheckpointsList
= new Vector
<TmfCheckpoint
>();
68 private LttngTraceState fStateModel
;
69 private LttngTraceState fCheckPointStateModel
;
72 private final Object fCheckPointsLock
= new Object();
73 private final Object fStateModelLock
= new Object();
77 // =======================================================================
79 // =======================================================================
85 * @throws LttngStateException
87 public StateTraceManager(Long id
, LTTngTreeNode parent
, String name
, ITmfTrace trace
) throws LttngStateException
{
88 super(id
, parent
, name
, trace
);
91 throw new LttngStateException("No TmfTrace object available!"); //$NON-NLS-1$
95 fStateUpdateProcessor
= StateEventToHandlerFactory
.getInstance();
99 fStateModel
= StateModelFactory
.getStateEntryInstance(this);
100 fStateModel
.init(this);
102 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
103 fCheckPointStateModel
.init(this);
106 // =======================================================================
108 // =======================================================================
109 @SuppressWarnings("unchecked")
110 private void init() {
111 // resolve the experiment
112 Object obj
= getParent().getValue();
113 if (obj
!= null && obj
instanceof TmfExperiment
) {
114 fExperiment
= (TmfExperiment
) obj
;
117 // initialize the number of cpus
118 if (fTrace
instanceof LTTngTrace
) {
119 fcpuNumber
= ((LTTngTrace
) fTrace
).getCpuNumber();
120 } else if (fTrace
instanceof LTTngTextTrace
) {
121 fcpuNumber
= ((LTTngTextTrace
) fTrace
).getCpuNumber();
132 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
135 public ITmfTrace
getStateTrace() {
140 * Save a checkpoint if it is needed at that point
142 * The function will use "eventCount" internally to determine if a save was
145 * @param eventCounter
146 * The event "count" or event "id" so far
148 * The timestamp of this event
150 * @return boolean True if a checkpoint was saved, false otherwise
152 private void saveCheckPointIfNeeded(Long eventCounter
, ITmfTimestamp eventTime
) {
153 // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
154 if ((eventCounter
.longValue() % fcheckPointInterval
) == 0) {
156 LttngTraceState stateCheckPoint
;
157 synchronized (fCheckPointsLock
) {
158 stateCheckPoint
= fCheckPointStateModel
.clone();
161 TraceDebug
.debug("Check point created here: " + eventCounter
//$NON-NLS-1$
162 + " -> " + eventTime
.toString() + "************" //$NON-NLS-1$ //$NON-NLS-2$
163 + getStateTrace().getName() + " >>>>> Thread: " //$NON-NLS-1$
164 + Thread
.currentThread().getId());
166 synchronized (fCheckPointsLock
) {
167 // Save the checkpoint
168 stateCheckpointsList
.put(eventCounter
, stateCheckPoint
);
169 // Save correlation between timestamp and checkpoint index
171 timestampCheckpointsList
.add(new TmfCheckpoint(new TmfTimestamp(eventTime
), new TmfContext(new TmfLocation
<Long
>(eventCounter
), eventCounter
)));
177 * @return the lttng_check_point_interval
179 public long getCheckPointInterval() {
180 return fcheckPointInterval
;
184 * @param check_point_interval
185 * , the lttng_check_point_interval to set
187 public void setCheckPointInterval(long check_point_interval
) {
188 this.fcheckPointInterval
= check_point_interval
;
194 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
195 * restoreCheckPointByTimestamp
196 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
199 @SuppressWarnings("unchecked")
200 public TmfCheckpoint
restoreCheckPointByTimestamp(ITmfTimestamp eventTime
) {
201 TmfTimeRange experimentRange
= fExperiment
.getTimeRange();
202 TmfCheckpoint checkpoint
= new TmfCheckpoint(fTrace
.getStartTime(), new TmfContext(new TmfLocation
<Long
>(0L), 0));
204 // The GUI can have time limits higher than this log, since GUI can
205 // handle multiple logs. Ignore special null value of experiment time range.
206 if ((eventTime
.getValue() < 0) ||
207 (!experimentRange
.equals(TmfTimeRange
.NULL_RANGE
) && (eventTime
.getValue() > experimentRange
.getEndTime().getValue()))) {
211 // The GUI can have time limits lower than this trace, since experiment
212 // can handle multiple traces
213 if ((eventTime
.getValue() < fTrace
.getStartTime().getValue())) {
214 eventTime
= fTrace
.getStartTime();
217 LttngTraceState traceState
;
218 synchronized (fCheckPointsLock
) {
219 Collections
.sort(timestampCheckpointsList
);
220 // Initiate the compare with a checkpoint containing the target time
222 int index
= Collections
.binarySearch(timestampCheckpointsList
, new TmfCheckpoint(eventTime
, new TmfContext(new TmfLocation
<Long
>(0L), 0)));
223 // adjust index to round down to earlier checkpoint when exact match
226 index
= getPrevIndex(index
);
229 // No checkpoint restore is needed, start with a brand new
231 traceState
= StateModelFactory
.getStateEntryInstance(this);
234 // Useful CheckPoint found
235 checkpoint
= timestampCheckpointsList
.get(index
);
236 // get the location associated with the checkpoint
237 TmfLocation
<Long
> location
= (TmfLocation
<Long
>) checkpoint
.getLocation();
238 // reference a new copy of the checkpoint template
239 traceState
= stateCheckpointsList
.get(location
.getLocation()).clone();
244 // Restore the stored traceState
245 synchronized (fStateModelLock
) {
246 fStateModel
= traceState
;
253 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#restoreCheckPointByIndex(long)
256 public TmfCheckpoint
restoreCheckPointByIndex(long eventIndex
) {
257 TmfCheckpoint checkpoint
= new TmfCheckpoint(fTrace
.getStartTime(), new TmfContext(new TmfLocation
<Long
>(0L), 0));
259 LttngTraceState traceState
;
260 synchronized (fCheckPointsLock
) {
261 Collections
.sort(timestampCheckpointsList
);
262 // Initiate the compare with a checkpoint containing the target time
264 int index
= Collections
.binarySearch(timestampCheckpointsList
, new TmfCheckpoint(null, new TmfContext(new TmfLocation
<Long
>(eventIndex
), eventIndex
)));
265 // adjust index to round down to earlier checkpoint when exact match not found
266 index
= getPrevIndex(index
);
269 // No checkpoint restore is needed, start with a brand new
271 traceState
= StateModelFactory
.getStateEntryInstance(this);
274 // Useful CheckPoint found
275 checkpoint
= timestampCheckpointsList
.get(index
);
276 // get the location associated with the checkpoint
277 @SuppressWarnings("unchecked")
278 TmfLocation
<Long
> location
= (TmfLocation
<Long
>) checkpoint
.getLocation();
279 // reference a new copy of the checkpoint template
280 traceState
= stateCheckpointsList
.get(location
.getLocation()).clone();
285 // Restore the stored traceState
286 synchronized (fStateModelLock
) {
287 fStateModel
= traceState
;
294 * Adjust the result from a binary search to the round down position
297 * if Negative is: (-(insertion point) -1)
298 * @return position or if no match found, earlier than insertion point
300 private int getPrevIndex(int position
) {
301 int roundDownPosition
= position
;
303 roundDownPosition
= -(position
+ 2);
306 roundDownPosition
= roundDownPosition
< 0 ?
0 : roundDownPosition
;
307 return roundDownPosition
;
310 // TODO: Remove this request type when the UI handle their own requests
312 * Request Event data of a specified time range
317 * @return ILttngEventRequest The request made
319 ILttngSyntEventRequest
getDataRequestByTimeRange(TmfTimeRange timeWindow
, IRequestStatusListener listener
,
320 final ITransEventProcessor processor
) {
322 ILttngSyntEventRequest request
= new StateTraceManagerRequest(timeWindow
, DEFAULT_OFFSET
,
323 TmfDataRequest
.ALL_DATA
, DEFAULT_CHUNK
, listener
, getExperimentTimeWindow(), processor
) {
334 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
338 public LttngTraceState
getStateModel() {
339 LttngTraceState stateModel
= null;
340 synchronized (fStateModelLock
) {
341 stateModel
= fStateModel
;
349 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
350 * getCheckPointStateModel()
353 public LttngTraceState
getCheckPointStateModel() {
354 LttngTraceState checkPointStateModel
= null;
355 synchronized (fCheckPointsLock
) {
356 checkPointStateModel
= fCheckPointStateModel
;
358 return checkPointStateModel
;
362 * @return the stateCheckpointsList
364 HashMap
<Long
, LttngTraceState
> getStateCheckpointsList() {
365 return stateCheckpointsList
;
369 * @return the timestampCheckpointsList
371 Vector
<TmfCheckpoint
> getTimestampCheckpointsList() {
372 return timestampCheckpointsList
;
374 // =======================================================================
376 // =======================================================================
377 class StateTraceManagerRequest
extends LttngSyntEventRequest
{
378 // =======================================================================
380 // =======================================================================
381 final TmfEvent
[] evt
= new TmfEvent
[1];
382 final ITransEventProcessor fprocessor
;
383 LttngSyntheticEvent synEvent
;
384 Long fCount
= getSynEventCount();
386 // =======================================================================
388 // =======================================================================
389 public StateTraceManagerRequest(TmfTimeRange range
, long offset
, int nbEvents
, int maxBlockSize
,
390 IRequestStatusListener listener
, TmfTimeRange experimentTimeRange
, ITransEventProcessor processor
) {
392 super(range
, offset
, nbEvents
, maxBlockSize
, listener
, experimentTimeRange
, processor
);
393 fprocessor
= processor
;
394 TraceDebug
.debug("Instance created for range: " + range
.toString()); //$NON-NLS-1$
398 // =======================================================================
400 // =======================================================================
405 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
409 public void handleData(ITmfEvent event
) {
410 super.handleData(event
);
412 synEvent
= (LttngSyntheticEvent
) event
;
413 if (synEvent
.getSynType() == SequenceInd
.AFTER
) {
414 // Note : We call this function before incrementing
415 // eventCount to save a default check point at the "0th"
417 saveCheckPoint(fCount
, synEvent
.getTimestamp());
420 if (TraceDebug
.isDEBUG()) {
421 if (fCount
% 1000 == 0) {
422 TraceDebug
.debug("handled: " + fCount
+ " sequence: " + synEvent
.getSynType()); //$NON-NLS-1$ //$NON-NLS-2$
430 * To be overridden by active save e.g. check points, this no action
431 * default is used for requests which do not require rebuilding of
432 * checkpoints e.g. requiring data of a new time range selection
437 public void saveCheckPoint(Long count
, ITmfTimestamp time
) {
445 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
449 public int getNumberOfCpus() {
456 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
457 * getTraceTimeWindow()
460 public TmfTimeRange
getTraceTimeWindow() {
461 if (fTrace
!= null) {
462 return fTrace
.getTimeRange();
472 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
476 public String
getTraceId() {
477 if (fTrace
!= null) {
478 return fTrace
.getName();
486 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
487 * getExperimentTimeWindow()
490 public TmfTimeRange
getExperimentTimeWindow() {
491 if (fExperiment
!= null) {
492 return fExperiment
.getTimeRange();
501 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
505 public String
getExperimentName() {
506 return fExperiment
.getName();
513 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
517 public ITmfTrace
getTraceIdRef() {
525 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
529 public void clearCheckPoints() {
530 synchronized (fCheckPointsLock
) {
531 stateCheckpointsList
.clear();
532 timestampCheckpointsList
.clear();
534 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
537 fCheckPointStateModel
.init(this);
538 } catch (LttngStateException e
) {
539 Activator
.getDefault().logError("Unexpected Error", e
); //$NON-NLS-1$
548 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
549 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
552 public void handleEvent(LttngSyntheticEvent synEvent
, Long eventCount
) {
553 fStateUpdateProcessor
.process(synEvent
, fCheckPointStateModel
);
555 // Save checkpoint as needed
556 saveCheckPointIfNeeded(eventCount
- 1, synEvent
.getTimestamp());
562 * @see java.lang.Object#toString()
565 @SuppressWarnings("nls")
566 public String
toString() {
567 StringBuilder sb
= new StringBuilder(super.toString());
568 sb
.append("\n\tTotal number of processes in the Shared State model: " + fStateModel
.getProcesses().length
569 + "\n\t" + "Total number of processes in the Check point State model: "
570 + fCheckPointStateModel
.getProcesses().length
);
572 TmfTimeRange traceTRange
= fTrace
.getTimeRange();
573 sb
.append("\n\tTrace time interval for trace " + fTrace
.getName() + "\n\t"
574 + new LttngTimestamp(traceTRange
.getStartTime()));
575 sb
.append(" - " + new LttngTimestamp(traceTRange
.getEndTime()));
576 sb
.append("\n\tCheckPoints available at: ");
577 for (TmfCheckpoint cpoint
: timestampCheckpointsList
) {
578 sb
.append("\n\t" + "Location: " + cpoint
.getLocation() + " - " + cpoint
.getTimestamp());
581 return sb
.toString();
586 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getIdentifier()
589 public long getIdentifier() {
590 return getId().longValue();