| /******************************************************************************* |
| * Copyright (c) 2013, 2015 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Alexandre Montplaisir - Initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.tmf.ctf.core.event; |
| |
| import org.eclipse.jdt.annotation.NonNullByDefault; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.tracecompass.ctf.core.CTFStrings; |
| import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration; |
| import org.eclipse.tracecompass.ctf.core.event.IEventDefinition; |
| import org.eclipse.tracecompass.ctf.core.event.types.IDefinition; |
| import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition; |
| import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; |
| import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; |
| import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; |
| import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace; |
| |
| /** |
| * Factory for CtfTmfEvent's. |
| * |
| * This code was moved out of CtfTmfEvent to provide better separation between |
| * the parsing/instantiation of events, and the usual TMF API implementations. |
| * |
| * @author Alexandre Montplaisir |
| */ |
| @NonNullByDefault |
| public class CtfTmfEventFactory { |
| |
| private static final CtfTmfEventFactory INSTANCE = new CtfTmfEventFactory(); |
| |
| /** |
| * The file name to use when none is specified. |
| * |
| * FIXME Externalize? |
| * |
| * @since 2.0 |
| */ |
| protected static final String NO_STREAM = "No stream"; //$NON-NLS-1$ |
| |
| /** |
| * Protected constructor, only for use by sub-classes. Users should call |
| * the {@link #instance()} method instead. |
| * |
| * @since 2.0 |
| */ |
| protected CtfTmfEventFactory() {} |
| |
| /** |
| * Get the singleton factory instance |
| * |
| * @return The instance |
| * @since 2.0 |
| */ |
| public static CtfTmfEventFactory instance() { |
| return INSTANCE; |
| } |
| |
| /** |
| * Factory method to instantiate new CTF events. |
| * |
| * @param trace |
| * The trace to which the new event will belong |
| * @param eventDef |
| * CTF EventDefinition object corresponding to this trace event |
| * @param fileName |
| * The path to the trace file |
| * @return The newly-built CtfTmfEvent |
| * @since 2.0 |
| */ |
| public CtfTmfEvent createEvent(CtfTmfTrace trace, IEventDefinition eventDef, @Nullable String fileName) { |
| |
| /* Prepare what to pass to CtfTmfEvent's constructor */ |
| final IEventDeclaration eventDecl = eventDef.getDeclaration(); |
| final long ts = eventDef.getTimestamp(); |
| final ITmfTimestamp timestamp = trace.createTimestamp(trace.timestampCyclesToNanos(ts)); |
| |
| int sourceCPU = eventDef.getCPU(); |
| |
| String reference = (fileName == null ? NO_STREAM : fileName); |
| |
| /* Handle the special case of lost events */ |
| if (eventDecl.getName().equals(CTFStrings.LOST_EVENT_NAME)) { |
| return createLostEvent(trace, eventDef, eventDecl, ts, timestamp, sourceCPU, reference); |
| } |
| |
| /* Handle standard event types */ |
| return new CtfTmfEvent(trace, |
| ITmfContext.UNKNOWN_RANK, |
| timestamp, |
| reference, // filename |
| sourceCPU, |
| eventDecl, |
| eventDef); |
| } |
| |
| /** |
| * Create a new CTF lost event. |
| * |
| * @param trace |
| * The trace to which the new event will belong |
| * @param eventDef |
| * The CTF event definition |
| * @param eventDecl |
| * The CTF event declaration |
| * @param ts |
| * The event's timestamp |
| * @param timestamp |
| * The event's timestamp (FIXME again??) |
| * @param sourceCPU |
| * The source CPU |
| * @param fileName |
| * The file name |
| * @return The new lost event |
| * @since 2.0 |
| */ |
| protected static CtfTmfEvent createLostEvent(CtfTmfTrace trace, |
| IEventDefinition eventDef, |
| final IEventDeclaration eventDecl, |
| final long ts, |
| final ITmfTimestamp timestamp, |
| int sourceCPU, |
| String fileName) { |
| |
| IDefinition nbLostEventsDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_FIELD); |
| IDefinition durationDef = eventDef.getFields().getDefinition(CTFStrings.LOST_EVENTS_DURATION); |
| if (!(nbLostEventsDef instanceof IntegerDefinition) || !(durationDef instanceof IntegerDefinition)) { |
| /* |
| * One or both of these fields doesn't exist, or is not of the right |
| * type. The event claims to be a "lost event", but is malformed. |
| * Log it and return a null event instead. |
| */ |
| return getNullEvent(trace); |
| } |
| long nbLostEvents = ((IntegerDefinition) nbLostEventsDef).getValue(); |
| long duration = ((IntegerDefinition) durationDef).getValue(); |
| ITmfTimestamp timestampEnd = trace.createTimestamp( |
| trace.timestampCyclesToNanos(ts) + trace.timestampCyclesToNanos(duration - trace.getOffset())); |
| |
| CtfTmfLostEvent lostEvent = new CtfTmfLostEvent(trace, |
| ITmfContext.UNKNOWN_RANK, |
| fileName, |
| sourceCPU, |
| eventDecl, |
| new TmfTimeRange(timestamp, timestampEnd), |
| nbLostEvents, |
| eventDef); |
| return lostEvent; |
| } |
| |
| /** |
| * Get an instance of a null event. |
| * |
| * @param trace |
| * The trace to which the new null event will belong |
| * @return An empty event |
| * @since 2.0 |
| */ |
| public static CtfTmfEvent getNullEvent(CtfTmfTrace trace) { |
| return new CtfTmfEvent(trace); |
| } |
| |
| |
| } |