*
* Contributors:
* Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ * Bernd Hufmann - Bug fixes
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.common;
import java.util.Arrays;
-import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory;
-import org.eclipse.linuxtools.lttng.control.LttngSyntheticEventProvider;
-import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
-import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
-import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
-import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
-import org.eclipse.linuxtools.lttng.request.IRequestStatusListener;
-import org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest;
-import org.eclipse.linuxtools.lttng.request.RequestCompletedSignal;
-import org.eclipse.linuxtools.lttng.request.RequestStartedSignal;
-import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor;
+import org.eclipse.linuxtools.lttng.core.LttngConstants;
+import org.eclipse.linuxtools.lttng.core.control.LttngCoreProviderFactory;
+import org.eclipse.linuxtools.lttng.core.control.LttngSyntheticEventProvider;
+import org.eclipse.linuxtools.lttng.core.event.LttngSyntheticEvent;
+import org.eclipse.linuxtools.lttng.core.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.core.request.ILttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.core.request.IRequestStatusListener;
+import org.eclipse.linuxtools.lttng.core.request.LttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.core.request.RequestCompletedSignal;
+import org.eclipse.linuxtools.lttng.core.request.RequestStartedSignal;
+import org.eclipse.linuxtools.lttng.core.state.evProcessor.ITransEventProcessor;
import org.eclipse.linuxtools.lttng.ui.TraceDebug;
import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
-import org.eclipse.linuxtools.lttng.ui.views.resources.model.ResourceModelFactory;
-import org.eclipse.linuxtools.tmf.event.TmfEvent;
-import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
-import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
-import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal;
-import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
-import org.eclipse.linuxtools.tmf.signal.TmfSignalManager;
-import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment;
+import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
+import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITimeAnalysisViewer;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;
* @author alvaro
*
*/
-public abstract class AbsTimeUpdateView extends TmfView implements
- IRequestStatusListener {
+public abstract class AbsTimeUpdateView extends TmfView implements IRequestStatusListener {
// ========================================================================
// Data
// ========================================================================
- /**
- * One second in nanoseconds
- */
- private static final long INITIAL_WINDOW_OFFSET = 1000000000L; /*
- * 1 sec //
- * in ns //
- */
- // private static final long INITIAL_WINDOW_OFFSET = 100000000L; /* 100 ms
- // in ns */
+
+// private static final long INITIAL_WINDOW_OFFSET = (1L * 1 * 1000 * 1000); // .001sec
+// private static final long INITIAL_WINDOW_OFFSET = (1L * 10 * 1000 * 1000); // .01sec
+ private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec
+// private static final long INITIAL_WINDOW_OFFSET = (1L * 1000 * 1000 * 1000); // 1sec
+
/**
* Number of events before a GUI refresh
*/
- private static final Long INPUT_CHANGED_REFRESH = 3000L;
- private static final long DEFAULT_OFFSET = 0L;
- private static final int DEFAULT_CHUNK = 1;
+ protected static final Long INPUT_CHANGED_REFRESH = 75000L;
+ private static final long DEFAULT_OFFSET = 0;
- protected boolean synch = true; // time synchronisation, used to be an
- // option
+ protected boolean synch = true; // time synchronization, used to be an option
protected ITimeAnalysisViewer tsfviewer = null;
+ private LttngSyntEventRequest fCurrentRequest = null;
+
+ protected LttngSyntheticEventProvider fProvider = LttngCoreProviderFactory.getEventProvider(getProviderId());
+
// ========================================================================
// Constructor
// ========================================================================
// ========================================================================
// Methods
// ========================================================================
+
+ /**
+ * Returns the number of events after which the relevant display will
+ * be refreshed
+ *
+ * @return
+ */
+ protected Long getInputChangedRefresh() {
+ return INPUT_CHANGED_REFRESH;
+ }
+
+ /**
+ * Cancel the ongoing request if another experiment is being selected
+ * @param experimentDisposedSignal
+ */
+ @TmfSignalHandler
+ public void experimentDisposed(TmfExperimentDisposedSignal<? extends TmfEvent> experimentDisposedSignal) {
+ fProvider.conditionallyCancelRequests();
+ }
+
/*
* (non-Javadoc)
*
* @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener#
* processingStarted(org.eclipse.linuxtools.lttng.state.StateDataRequest)
*/
+ @Override
@TmfSignalHandler
public synchronized void processingStarted(RequestStartedSignal signal) {
LttngSyntEventRequest request = signal.getRequest();
* @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener#
* processingCompleted(org.eclipse.linuxtools.lttng.state.StateDataRequest)
*/
+ @Override
@TmfSignalHandler
public void processingCompleted(RequestCompletedSignal signal) {
ILttngSyntEventRequest request = signal.getRequest();
if (TraceDebug.isDEBUG()) {
TmfTimeRange trange = request.getRange();
if (request.isCancelled()) {
- TraceDebug.debug("Request cancelled "
- + trange.getStartTime() + "-" + trange.getEndTime()
- + " Handled Events: " + request.getSynEventCount()
- + " " + request.toString(), 15);
+ TraceDebug.debug("Request cancelled " //$NON-NLS-1$
+ + trange.getStartTime() + "-" + trange.getEndTime() //$NON-NLS-1$
+ + " Handled Events: " + request.getSynEventCount() //$NON-NLS-1$
+ + " " + request.toString(), 15); //$NON-NLS-1$
} else if (request.isFailed()) {
- TraceDebug.debug("Request Failed " + trange.getStartTime()
- + "-" + trange.getEndTime() + " Handled Events: "
- + request.getSynEventCount() + " "
+ TraceDebug.debug("Request Failed " + trange.getStartTime() //$NON-NLS-1$
+ + "-" + trange.getEndTime() + " Handled Events: " //$NON-NLS-1$ //$NON-NLS-2$
+ + request.getSynEventCount() + " " //$NON-NLS-1$
+ request.toString());
}
}
if (synch) {
Object source = signal.getSource();
if (signal != null && source != null && source != this) {
- // Internal value is expected in nano seconds.
- long selectedTime = signal.getCurrentTime().getValue();
- if (tsfviewer != null) {
- tsfviewer.setSelectedTime(selectedTime, true, source);
+
+ if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) {
+
+ // Check for GUI thread
+ if (Display.getCurrent() != null) {
+ // GUI thread - execute update right away.
+
+ // Internal value is expected in nano seconds.
+ long selectedTime = signal.getCurrentTime().getValue();
+ if (tsfviewer != null) {
+ tsfviewer.setSelectedTime(selectedTime, true, source);
+
+ ParamsUpdater paramUpdater = getParamsUpdater();
+ Long savedSelTime = paramUpdater.getSelectedTime();
+ if ((savedSelTime == null) || (savedSelTime != selectedTime)) {
+ // Update the parameter updater to save the selected time
+ paramUpdater.setSelectedTime(selectedTime);
+ }
+ }
+ } else {
+ // Perform the updates on the UI thread
+
+ // We need to clone the timestamp in the signal so that it won't be overwritten duo to multipe thread access
+ final TmfTimeSynchSignal savedSignal = new TmfTimeSynchSignal(signal.getSource(), signal.getCurrentTime().clone());
+ tsfviewer.getControl().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) {
+ synchToTime(savedSignal);
+ }
+ }
+ });
+ }
}
}
}
TmfTimeRange trange = signal.getCurrentRange();
TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
if (experiment == null) {
- TraceDebug.debug("Current selected experiment is null");
+ TraceDebug.debug("Current selected experiment is null"); //$NON-NLS-1$
return;
}
// Clearing of process data is configurable
- dataRequest(trange, experiment.getTimeRange(), clearingData);
+ eventRequest(trange, experiment.getTimeRange(), clearingData, ExecutionType.FOREGROUND);
}
}
}
paramUpdater.setSelectedTime(selTimens);
if (TraceDebug.isDEBUG()) {
- TraceDebug.debug("Selected Time: " + new LttngTimestamp(selTimens) + "\n\t\t" + getName());
+ TraceDebug.debug("Selected Time: " + new LttngTimestamp(selTimens) + "\n\t\t" + getName()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
*
* @param event
*/
- protected synchronized void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) {
- // source needed to keep track of source values
- Object source = event.getSource();
-
- if (source != null) {
- // Update the parameter updater before carrying out a read request
- ParamsUpdater paramUpdater = getParamsUpdater();
- boolean newParams = paramUpdater.processTimeScaleEvent(event);
-
- if (newParams) {
- // Read the updated time window
- TmfTimeRange trange = paramUpdater.getTrange();
- if (trange != null) {
-
- // Notify listener views. to perform data requests
- // upon this notification
- synchTimeRangeNotification(trange, paramUpdater.getSelectedTime(), source);
- }
- }
+ protected void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) {
+ // source needed to keep track of source values
+ Object source = event.getSource();
+
+ boolean newParams = false;
+ TmfTimeRange trange = null;
+ Long selectedTime = null;
+
+ // update all information and get relevant data
+ synchronized (this) {
+ if (source != null) {
+ // Update the parameter updater before carrying out a read request
+ ParamsUpdater paramUpdater = getParamsUpdater();
+ newParams = paramUpdater.processTimeScaleEvent(event);
+
+ if (newParams) {
+ // Read the updated time window
+ trange = paramUpdater.getTrange();
+ if (trange != null) {
+ selectedTime = paramUpdater.getSelectedTime();
+ }
+ }
+ }
+ }
+
+ // Check for selectedTime is sufficient since it is only set if
+ // newParams is true and trange is not null
+ if (selectedTime != null) {
+ // Notify listener views. to perform data requests
+ // upon this notification
+
+ // Note that this has to be done outside the synchronized statement
+ // because otherwise we could end-up in a deadlock if a ongoing
+ // request needs to be canceled.
+ synchTimeRangeNotification(trange, selectedTime, source);
}
}
/**
* @param zoomedTRange
* @param experimentTRange
+ * @param clearingData
+ * @param execType
+ */
+ public void eventRequest(TmfTimeRange zoomedTRange, TmfTimeRange experimentTRange, boolean clearingData, ExecutionType execType) {
+
+ // timeRange is the Experiment time range
+ boolean sent = processDataRequest(zoomedTRange, experimentTRange, DEFAULT_OFFSET, TmfDataRequest.ALL_DATA, clearingData, execType);
+
+ if (sent) {
+ waitCursor(true);
+ }
+ }
+
+ /**
+ * @param offset
+ * @param nbRequested
+ * @param startTime
+ * @param clearingData
+ * @param execType
*/
- public void dataRequest(TmfTimeRange zoomedTRange,
- TmfTimeRange experimentTRange, boolean clearingData) {
+ public void eventRequest(long offset, TmfTimeRange range, boolean clearingData, ExecutionType execType) {
// timeRange is the Experiment time range
- boolean sent = processDataRequest(zoomedTRange, experimentTRange, clearingData);
+ boolean sent = processDataRequest(range, null, offset, TmfDataRequest.ALL_DATA, clearingData, execType);
if (sent) {
waitCursor(true);
}
}
+// /**
+// * @param zoomedTRange
+// * @param experimentTRange
+// * @param execType
+// */
+// public void dataRequest(TmfTimeRange zoomedTRange,
+// TmfTimeRange experimentTRange, boolean clearingData) {
+//
+// // timeRange is the Experiment time range
+// boolean sent = processDataRequest(zoomedTRange, experimentTRange, clearingData);
+//
+// if (sent) {
+// waitCursor(true);
+// }
+// }
+
/**
* send data request directly e.g. doesn't use a queue
*
* @param requestTrange
* @param listener
* @param experimentTRange
+ * @param execType
* @param processor
* @return
*/
private boolean processDataRequest(TmfTimeRange requestTrange,
- TmfTimeRange experimentTRange, boolean clearingData) {
+ TmfTimeRange experimentTRange, long offset, int nbRequested, boolean clearingData, ExecutionType execType) {
// Validate input
- if (requestTrange == null || experimentTRange == null) {
- TraceDebug.debug("Invalid input");
+ if (requestTrange == null) {
+ TraceDebug.debug("Invalid input"); //$NON-NLS-1$
return false;
}
- LttngSyntEventRequest request = new LttngSyntEventRequest(
- requestTrange, DEFAULT_OFFSET, TmfDataRequest.ALL_DATA,
- DEFAULT_CHUNK, this, experimentTRange, getEventProcessor()) {
+ // Cancel the currently executing request before starting a new one
+ fProvider.conditionallyCancelRequests();
+ fCurrentRequest = new LttngSyntEventRequest(
+ requestTrange, offset, nbRequested,
+ LttngConstants.DEFAULT_BLOCK_SIZE, this, experimentTRange, getEventProcessor(),
+ TmfExperiment.getCurrentExperiment().getName(), execType) {
Long fCount = getSynEventCount();
ITransEventProcessor processor = getProcessor();
* org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
* ()
*/
- int handleDataCount = 0;
- int handleDataValidCount = 0;
+//// int handleDataCount = 0;
+//// int handleDataValidCount = 0;
+// @Override
+// public void handleData() {
+// LttngSyntheticEvent[] result = getData();
+//
+// TmfEvent evt = (result.length > 0) ? result[0] : null;
+//// handleDataCount++;
+
@Override
- public void handleData() {
- TmfEvent[] result = getData();
-
- TmfEvent evt = (result.length > 0) ? result[0] : null;
- handleDataCount++;
- if (evt != null) {
- handleDataValidCount++;
- LttngSyntheticEvent synEvent = (LttngSyntheticEvent) evt;
+ public void handleData(LttngSyntheticEvent event) {
+ super.handleData(event);
+ if (event != null) {
+// handleDataValidCount++;
+ LttngSyntheticEvent synEvent = (LttngSyntheticEvent) event;
// process event
- SequenceInd indicator = synEvent.getSynType();
- if (indicator == SequenceInd.BEFORE
- || indicator == SequenceInd.AFTER) {
- processor.process(evt, synEvent.getTraceModel());
- } else if (indicator == SequenceInd.STARTREQ) {
- handleRequestStarted();
- } else if (indicator == SequenceInd.ENDREQ) {
- processor.process(evt, synEvent.getTraceModel());
- // handleCompleted();
- }
-
- if (indicator == SequenceInd.BEFORE) {
- fCount++;
- if (fCount != 0 && fCount % INPUT_CHANGED_REFRESH == 0) {
- // send partial update
- modelInputChanged(this, false);
-
- if (TraceDebug.isDEBUG()) {
- frunningTimeStamp = evt.getTimestamp();
- TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType());
- }
-
- }
- }
+ switch (synEvent.getSynType()) {
+
+ case STARTREQ: {
+ handleRequestStarted();
+ break;
+ }
+
+ case BEFORE: {
+ processor.process(event, synEvent.getTraceModel());
+ fCount++;
+ if ((fCount != 0) && (fCount % getInputChangedRefresh() == 0)) {
+ // send partial update
+ modelInputChanged(this, false);
+
+ if (TraceDebug.isDEBUG()) {
+ frunningTimeStamp = event.getTimestamp();
+ TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ break;
+ }
+
+ case AFTER:
+ // fall-through
+ case ENDREQ:{
+ processor.process(event, synEvent.getTraceModel());
+ break;
+ }
+
+ default:
+ // nothing to do
+ break;
+ }
}
}
@Override
public void done() {
- if (TraceDebug.isDEBUG()) {
- TraceDebug.debug("AbsTimeUpdateView: Received=" + handleDataCount + ", Valid=" + handleDataCount + ", fCount=" + fCount);
- }
+// if (TraceDebug.isDEBUG()) {
+// TraceDebug.debug("AbsTimeUpdateView: Received=" + handleDataCount + ", Valid=" + handleDataCount + ", fCount=" + fCount);
+// }
super.done();
}
if (TraceDebug.isDEBUG()) {
if (frunningTimeStamp != null) {
- TraceDebug.debug("Last event time stamp: "
- + frunningTimeStamp.getValue());
+ TraceDebug.debug("Last event time stamp: " + frunningTimeStamp.getValue()); //$NON-NLS-1$
}
}
}
};
- // obtain singleton core provider
- LttngSyntheticEventProvider provider = LttngCoreProviderFactory
- .getEventProvider();
-
// send the request to TMF
- request.startRequestInd(provider);
- request.setclearDataInd(clearingData);
+ fCurrentRequest.startRequestInd(fProvider);
+ fCurrentRequest.setclearDataInd(clearingData);
return true;
}
* @param waitInd
*/
protected void waitCursor(final boolean waitInd) {
- if (tsfviewer != null) {
+ if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) {
Display display = tsfviewer.getControl().getDisplay();
// Perform the updates on the UI thread
display.asyncExec(new Runnable() {
+ @Override
public void run() {
- tsfviewer.waitCursor(waitInd);
+ if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) {
+ tsfviewer.waitCursor(waitInd);
+ }
}
});
}
* @param complete
* true: yes, false: partial update
*/
+ @SuppressWarnings("deprecation")
protected void modelInputChanged(ILttngSyntEventRequest request, boolean complete) {
long experimentStartTime = -1;
long experimentEndTime = -1;
if (complete) {
// reselect to original time
- ParamsUpdater paramUpdater = ResourceModelFactory.getParamsUpdater();
- if (paramUpdater != null && tsfviewer != null) {
+ ParamsUpdater paramUpdater = getParamsUpdater();
+ if ((paramUpdater != null) && (tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) {
final Long selTime = paramUpdater.getSelectedTime();
if (selTime != null) {
- TraceDebug.debug("View: " + getName() + "\n\t\tRestoring the selected time to: " + selTime);
+ TraceDebug.debug("View: " + getName() + "\n\t\tRestoring the selected time to: " + selTime); //$NON-NLS-1$ //$NON-NLS-2$
Display display = tsfviewer.getControl().getDisplay();
display.asyncExec(new Runnable() {
+ @Override
public void run() {
- tsfviewer.setSelectedTime(selTime, false, this);
+ if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) {
+ tsfviewer.setSelectedTime(selTime, false, this);
+ }
}
});
}
+// System.out.println(System.currentTimeMillis() + ": AbsTimeUpdate (" + getName() + ") completed");
+
if (TraceDebug.isDEBUG()) {
int eventCount = 0;
Long count = request.getSynEventCount();
eventCount += itemArr[pos].getTraceEvents().size();
}
- int discarded = getParamsUpdater().getEventsDiscarded();
+ int discarded = paramUpdater.getEventsDiscarded();
int discardedOutofOrder = paramUpdater.getEventsDiscardedWrongOrder();
- TmfTimeRange range = request.getRange();
- StringBuilder sb = new StringBuilder("View: " + getName() + ", Events handled: " + count
- + ", Events loaded in view: " + eventCount + ", Number of events discarded: " + discarded
- + "\n\tNumber of events discarded with start time earlier than next good time: "
- + discardedOutofOrder);
+ int discardedOutofViewRange = paramUpdater.getEventsDiscardedOutOfViewRange();
+ int dicardedNotVisible = paramUpdater.getEventsDiscardedNotVisible();
- sb.append("\n\t\tRequested Time Range: " + range.getStartTime() + "-" + range.getEndTime());
- sb.append("\n\t\tExperiment Time Range: " + experimentStartTime + "-" + experimentEndTime);
+ TmfTimeRange range = request.getRange();
+ StringBuilder sb = new StringBuilder("View: " + getName() + ", Events handled: " + count //$NON-NLS-1$ //$NON-NLS-2$
+ + ", Events loaded in view: " + eventCount + ", Number of events discarded: " + discarded //$NON-NLS-1$ //$NON-NLS-2$
+ + "\n\tNumber of events discarded with start time earlier than next good time: " //$NON-NLS-1$
+ + discardedOutofOrder + "\n\tDiscarded Not visible: " + dicardedNotVisible //$NON-NLS-1$
+ + "\n\tDiscarded out of view Range: " + discardedOutofViewRange); //$NON-NLS-1$
+
+ sb.append("\n\t\tRequested Time Range: " + range.getStartTime() + "-" + range.getEndTime()); //$NON-NLS-1$ //$NON-NLS-2$
+ sb.append("\n\t\tExperiment Time Range: " + experimentStartTime + "-" + experimentEndTime); //$NON-NLS-1$ //$NON-NLS-2$
TraceDebug.debug(sb.toString());
}
}
* @return
*/
protected abstract ItemContainer<?> getItemContainer();
+
+ /**
+ * Returns LTTng Synthetic Provider ID used for current view
+ *
+ * @return
+ */
+ protected abstract int getProviderId();
}