blob: d7a871f8d54c02021f09beb3ffcf1848322d0c1f [file] [log] [blame]
/*******************************************************************************
* 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);
}
}