A marker event source factory for Lost Events is enabled for all traces.
The marker event source can reuse a previously returned marker list if
the requested parameters are identical to the previous request.
The event types statistics state system is updated to add a new
attribute which is used to compute the time ranges that are covered by
at least one lost event time range.
Change-Id: I2479afc3f07deb363f5847f4816940010bae3e9e
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/59389
Reviewed-by: Hudson CI
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2012, 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
public static final String TOTAL = "total"; //$NON-NLS-1$
/** event_types */
- public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$<
+ public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$
+
+ /** lost_events
+ * @since 2.0*/
+ public static final String LOST_EVENTS = "lost_events"; //$NON-NLS-1$
}
}
*
* Contributors:
* Alexandre Montplaisir - Initial API and implementation
+ * Patrick Tasse - Added lost events attribute
******************************************************************************/
package org.eclipse.tracecompass.tmf.core.statistics;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent;
* The state provider for traces statistics that use TmfStateStatistics. It
* should work with any trace type for which we can use the state system.
*
- * It will store number of events seen, per event types. The resulting attribute
- * tree will look like this:
+ * It will store number of events seen, per event types. The resulting
+ * attribute tree will look like this:
*
* <pre>
* (root)
- * \-- event_types
- * |-- (event name 1)
- * |-- (event name 2)
- * |-- (event name 3)
- * ...
+ * |-- event_types
+ * | |-- (event name 1)
+ * | |-- (event name 2)
+ * | |-- (event name 3)
+ * | ...
+ * \-- lost_events
* </pre>
*
- * And each (event name)'s value will be an integer, representing how many times
+ * Each (event name)'s value will be an integer, representing how many times
* this particular event type has been seen in the trace so far.
*
+ * The value of the lost_events attribute will be a long, representing the
+ * latest end time of any current or previous lost event time range, in
+ * nanoseconds. If the value at a specific time 't' is greater than 't',
+ * then there is at least one lost event time range that overlaps time 't'.
+ *
* @author Alexandre Montplaisir
* @version 1.0
*/
* Version number of this input handler. Please bump this if you modify the
* contents of the generated state history in some way.
*/
- private static final int VERSION = 2;
+ private static final int VERSION = 3;
/**
* Constructor
curVal = 0;
}
- TmfStateValue value = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents()));
- ss.modifyAttribute(ts, value, quark);
+ ITmfStateValue value1 = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents()));
+ ss.modifyAttribute(ts, value1, quark);
+
+ long lostEventsStartTime = le.getTimeRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ long lostEventsEndTime = le.getTimeRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ int lostEventsQuark = ss.getQuarkAbsoluteAndAdd(Attributes.LOST_EVENTS);
+ ITmfStateValue currentLostEventsEndTime = ss.queryOngoingState(lostEventsQuark);
+ if (currentLostEventsEndTime.isNull() || currentLostEventsEndTime.unboxLong() < lostEventsStartTime) {
+ ss.modifyAttribute(lostEventsStartTime, TmfStateValue.newValueLong(lostEventsEndTime), lostEventsQuark);
+ } else if (currentLostEventsEndTime.unboxLong() < lostEventsEndTime) {
+ ss.updateOngoingState(TmfStateValue.newValueLong(lostEventsEndTime), lostEventsQuark);
+ }
return;
}
org.eclipse.tracecompass.internal.tmf.ui.dialogs;x-internal:=true,
org.eclipse.tracecompass.internal.tmf.ui.editors;x-internal:=true,
org.eclipse.tracecompass.internal.tmf.ui.editors.handlers;x-internal:=true,
+ org.eclipse.tracecompass.internal.tmf.ui.markers;x-internal:=true,
org.eclipse.tracecompass.internal.tmf.ui.parsers;x-internal:=true,
org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards;x-friends:="org.eclipse.tracecompass.tmf.ui.tests",
org.eclipse.tracecompass.internal.tmf.ui.preferences;x-internal:=true,
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.tracecompass.internal.tmf.ui.markers.LostEventsMarkerEventSourceFactory;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceAdapterManager;
import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
private static Activator plugin;
private TmfEventAdapterFactory fTmfEventAdapterFactory;
+ private LostEventsMarkerEventSourceFactory fLostEventMarkerEventSourceFactory;
private IPreferenceStore fCorePreferenceStore;
// ------------------------------------------------------------------------
fTmfEventAdapterFactory = new TmfEventAdapterFactory();
Platform.getAdapterManager().registerAdapters(fTmfEventAdapterFactory, ITmfEvent.class);
+ fLostEventMarkerEventSourceFactory = new LostEventsMarkerEventSourceFactory();
+ TmfTraceAdapterManager.registerFactory(fLostEventMarkerEventSourceFactory, ITmfTrace.class);
}
@Override
plugin = null;
Platform.getAdapterManager().unregisterAdapters(fTmfEventAdapterFactory);
+ TmfTraceAdapterManager.unregisterFactory(fLostEventMarkerEventSourceFactory);
+ fLostEventMarkerEventSourceFactory.dispose();
super.stop(context);
}
public static String ManageCustomParsersDialog_TextButtonLabel;
public static String MarkerEvent_Bookmarks;
+ public static String MarkerEvent_LostEvents;
public static String TmfEventsTable_AddBookmarkActionText;
public static String TmfEventsTable_ApplyPresetFilterMenuName;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.ui.markers;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGBA;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tracecompass.internal.tmf.ui.Messages;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.statistics.TmfStateStatistics.Attributes;
+import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsEventTypesModule;
+import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
+
+/**
+ * Marker event source for lost events.
+ */
+public class LostEventsMarkerEventSource implements IMarkerEventSource {
+
+ private static final String LOST_EVENTS = Messages.MarkerEvent_LostEvents;
+
+ private static final Color COLOR = new Color(Display.getDefault(), new RGBA(255, 0, 0, 50));
+
+ private final @NonNull ITmfTrace fTrace;
+ private long[] fLastRequest;
+ private @NonNull List<IMarkerEvent> fLastMarkers = Collections.emptyList();
+
+ /**
+ * Constructor.
+ *
+ * @param trace
+ * the trace
+ */
+ public LostEventsMarkerEventSource(@NonNull ITmfTrace trace) {
+ fTrace = trace;
+ }
+
+ @Override
+ public List<String> getMarkerCategories() {
+ return Arrays.asList(LOST_EVENTS);
+ }
+
+ @Override
+ public synchronized List<IMarkerEvent> getMarkerList(String category, long startTime, long endTime, long resolution, IProgressMonitor monitor) {
+ if (!category.equals(LOST_EVENTS)) {
+ return Collections.emptyList();
+ }
+ ITmfStateSystem ss = getStateSystem();
+ if (ss == null) {
+ return Collections.emptyList();
+ }
+ int lostEventsQuark = getLostEventsQuark(ss);
+ if (lostEventsQuark == -1) {
+ return Collections.emptyList();
+ }
+ long[] request = new long[] { startTime, endTime, resolution, ss.getCurrentEndTime() };
+ if (Arrays.equals(request, fLastRequest)) {
+ return fLastMarkers;
+ }
+ List<IMarkerEvent> markers = new ArrayList<>();
+ try {
+ long start = Math.max(startTime, ss.getStartTime());
+ long end = Math.min(endTime, ss.getCurrentEndTime());
+ if (start <= end) {
+ /* Update start to ensure that the previous marker is included. */
+ start = Math.max(start - 1, ss.getStartTime());
+ /* Update end to ensure that the next marker is included. */
+ long nextStartTime = ss.querySingleState(end, lostEventsQuark).getEndTime() + 1;
+ end = Math.min(nextStartTime, ss.getCurrentEndTime());
+ List<ITmfStateInterval> intervals = StateSystemUtils.queryHistoryRange(ss, lostEventsQuark, start, end, resolution, monitor);
+ for (ITmfStateInterval interval : intervals) {
+ if (interval.getStateValue().isNull()) {
+ continue;
+ }
+ long lostEventsStartTime = interval.getStartTime();
+ /*
+ * The end time of the lost events range is the value of the
+ * attribute, not the end time of the interval.
+ */
+ long lostEventsEndTime = interval.getStateValue().unboxLong();
+ long duration = lostEventsEndTime - lostEventsStartTime;
+ IMarkerEvent marker = new MarkerEvent(null, lostEventsStartTime, duration, LOST_EVENTS, COLOR, null, false);
+ markers.add(marker);
+ }
+ }
+ } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+ /* ignored */
+ }
+ fLastRequest = request;
+ fLastMarkers = Collections.unmodifiableList(markers);
+ return fLastMarkers;
+ }
+
+ private ITmfStateSystem getStateSystem() {
+ TmfStatisticsModule module = TmfTraceUtils.getAnalysisModuleOfClass(fTrace, TmfStatisticsModule.class, TmfStatisticsModule.ID);
+ if (module == null) {
+ return null;
+ }
+ return module.getStateSystem(checkNotNull(TmfStatisticsEventTypesModule.ID));
+ }
+
+ private static int getLostEventsQuark(ITmfStateSystem ss) {
+ try {
+ return ss.getQuarkAbsolute(Attributes.LOST_EVENTS);
+ } catch (AttributeNotFoundException e) {
+ return -1;
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.ui.markers;
+
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.AbstractTmfTraceAdapterFactory;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource;
+
+/**
+ * Marker event source factory for lost events.
+ */
+public class LostEventsMarkerEventSourceFactory extends AbstractTmfTraceAdapterFactory {
+
+ @Override
+ protected <T> T getTraceAdapter(ITmfTrace trace, Class<T> adapterType) {
+ if (IMarkerEventSource.class.equals(adapterType)) {
+ IMarkerEventSource adapter = new LostEventsMarkerEventSource(trace);
+ return adapterType.cast(adapter);
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {
+ IMarkerEventSource.class
+ };
+ }
+}
# org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model
MarkerEvent_Bookmarks=Bookmarks
+MarkerEvent_LostEvents=Lost Events
# org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets
TmfTimeTipHandler_DURATION=Duration