Bundle-Activator: org.eclipse.linuxtools.lttng.LTTngCorePlugin
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.linuxtools.tmf;bundle-version="0.2.0",
- org.eclipse.linuxtools.lttng.jni;bundle-version="0.2.0"
+ org.eclipse.linuxtools.tmf;bundle-version="0.2.0"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.linuxtools.lttng,
- org.eclipse.linuxtools.lttng.control,
org.eclipse.linuxtools.lttng.event,
- org.eclipse.linuxtools.lttng.model,
- org.eclipse.linuxtools.lttng.request,
- org.eclipse.linuxtools.lttng.signal,
+ org.eclipse.linuxtools.lttng.jni,
org.eclipse.linuxtools.lttng.state,
org.eclipse.linuxtools.lttng.state.evProcessor,
org.eclipse.linuxtools.lttng.state.evProcessor.state,
org.eclipse.linuxtools.lttng.state.experiment,
org.eclipse.linuxtools.lttng.state.model,
- org.eclipse.linuxtools.lttng.state.resource,
- org.eclipse.linuxtools.lttng.state.trace,
org.eclipse.linuxtools.lttng.trace
Bundle-Localization: plugin
#Properties file for org.eclipse.linuxtools.lttng
-Bundle-Vendor = Eclipse Linux Tools
+Bundle-Vendor = Eclipse
Bundle-Name = LTTng - Linux Tracing Toolkit (Incubation)
\ No newline at end of file
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
- LttngFactory.init();
+ TraceDebug.init();
}
/*
int earliestRequested = numOfStackLines > 0 ? stackCalledFromIdx\r
+ numOfStackLines : stackCalledFromIdx;\r
StringBuilder sb = new StringBuilder();\r
- int max = Thread.currentThread().getStackTrace().length - 1;\r
- earliestRequested = earliestRequested > max ? max : earliestRequested;\r
for (int i = earliestRequested; i >= stackCalledFromIdx; i--) {\r
sb.append(trace(Thread.currentThread().getStackTrace(), i) + "\n");\r
}\r
}\r
\r
private static String trace(StackTraceElement e[], int level) {\r
- if (e != null) {\r
- level = level >= e.length ? e.length - 1 : level;\r
+ if (e != null && e.length >= level) {\r
StackTraceElement s = e[level];\r
if (s != null) {\r
String simpleClassName = s.getClassName();\r
import org.eclipse.linuxtools.lttng.jni.JniEvent;
import org.eclipse.linuxtools.tmf.event.TmfEvent;
import org.eclipse.linuxtools.tmf.event.TmfEventSource;
-import org.eclipse.linuxtools.tmf.trace.TmfTrace;
/**
* <b><u>LttngEvent</u></b><p>
// Reference to the JNI JniEvent. Should only be used INTERNALLY
private JniEvent jniEventReference = null;
-
- // Reference to the parent trace that own this event
- private TmfTrace<LttngEvent> parentTrace = null;
-
+
/**
* Constructor with parameters.<p>
*
* @see org.eclipse.linuxtools.lttng.event.LttngEventReference
* @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
*/
- public LttngEvent(TmfTrace<LttngEvent> parent, LttngTimestamp timestamp, TmfEventSource source, LttngEventType type, LttngEventContent content, LttngEventReference reference, JniEvent lttEvent) {
+ public LttngEvent(LttngTimestamp timestamp, TmfEventSource source, LttngEventType type, LttngEventContent content, LttngEventReference reference, JniEvent lttEvent) {
super(timestamp, source, type, reference);
fContent = content;
jniEventReference = lttEvent;
- setParentTrace(parent);
}
/**
* @param oldEvent Event we want to copy from.
*/
public LttngEvent(LttngEvent oldEvent) {
- this(
- oldEvent.getParentTrace(),
- (LttngTimestamp)oldEvent.getTimestamp(),
+ this( (LttngTimestamp)oldEvent.getTimestamp(),
(TmfEventSource)oldEvent.getSource(),
(LttngEventType)oldEvent.getType(),
(LttngEventContent)oldEvent.getContent(),
/**
- * Return the parent trace asoociated with this event
- *
- * @return Parent trace
- */
- public TmfTrace<LttngEvent> getParentTrace() {
- return parentTrace;
- }
-
- /**
- * Set a new parent trace for this event
- *
- * @param parentTrace The new parent
- */
- public void setParentTrace(TmfTrace<LttngEvent> parentTrace) {
- this.parentTrace = parentTrace;
- }
-
-
- /**
* Return the channel name of this event.<p>
*
* @return Channel (tracefile) for this event
return ( (LttngEventType)this.getType() ).getMarkerName();
}
+ /**
+ * Set a new JniReference for this event.<p>
+ *
+ * Note : Reference is used to get back to the Jni during event parsing and need to be consistent.
+ *
+ * @param newJniEventReference New reference
+ *
+ * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ public void updateJniEventReference(JniEvent newJniEventReference) {
+ this.jniEventReference = newJniEventReference;
+ }
+
@Override
public LttngEventContent getContent() {
return (LttngEventContent)fContent;
fType = newType;
}
- /**
- * Set a new JniReference for this event.<p>
- *
- * Note : Reference is used to get back to the Jni during event parsing and need to be consistent.
- *
- * @param newJniEventReference New reference
- *
- * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
- */
- public synchronized void updateJniEventReference(JniEvent newJniEventReference) {
- this.jniEventReference = newJniEventReference;
- }
/**
* Convert this event into a Jni JniEvent.<p>
*
* @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
*/
- public synchronized JniEvent convertEventTmfToJni() {
+ public JniEvent convertEventTmfToJni() {
JniEvent tmpEvent = null;
// ***TODO***
@Override
public String toString() {
- StringBuffer result= new StringBuffer("[LttngEvent(");
- result.append("Timestamp:" + getTimestamp().getValue());
- result.append(",Channel:" + getChannelName());
- result.append(",CPU:" + getCpuId());
- result.append(",Marker:" + getMarkerName());
- result.append(",Content:" + getContent() + ")]");
+ String returnedData="";
+
+ returnedData += "Event timestamp:" + this.getTimestamp().getValue() + " ";
+ returnedData += "Channel:" + getChannelName() + " ";
+ returnedData += "CPU:" + getCpuId() + " ";
+ returnedData += "Marker:" + getMarkerName() + " ";
- return result.toString();
+ return returnedData;
}
}
import java.util.HashMap;
-import org.eclipse.linuxtools.lttng.jni.JniEvent;
import org.eclipse.linuxtools.tmf.event.TmfEventContent;
-import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException;
/**
* <b><u>LttngEventContent</u></b><p>
@Override
public LttngEventType getType() {
return (LttngEventType)fParentEvent.getType();
+// return (LttngEventType)fEventType;
}
public void setType(LttngEventType newType) {
((LttngEvent)fParentEvent).setType(newType);
+// fEventType = newType;
}
}
// ***VERIFY***
- // A bit weird to return the _currently_parsed fields (unlike all fields like getFields() )
+ // A bit weird to return the _currently_parsed fields (unlike all like getFields() )
// Should we keep this?
/**
* Return currently parsed fields in an object array format.<p>
* @see @see org.eclipse.linuxtools.lttng.event.LttngEventField
*/
@Override
- public synchronized LttngEventField[] getFields() {
- if ( fFieldsMap.size() < fParentEvent.getType().getNbFields() ) {
- LttngEventField tmpField = null;
- LttngEventType tmpType = (LttngEventType)fParentEvent.getType();
-
- for ( int pos=0; pos<tmpType.getNbFields(); pos++ ) {
- String name = null;
- JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni();
-
- // tmpEvent == null probably mean there is a discrepancy between Eclipse and C library
- // An error was probably printed in convertEventTmfToJni() already, but keep in mind this is SERIOUS
- if ( tmpEvent != null ) {
- try {
- name = tmpType.getLabel(pos);
-
- Object newValue = tmpEvent.parseFieldByName(name);
- tmpField = new LttngEventField(this, name, newValue );
- fFieldsMap.put(name, tmpField);
- }
- catch (TmfNoSuchFieldException e) {
- System.out.println("Invalid field position requested : " + pos + ", ignoring (getFields).");
- }
- }
- }
+ public LttngEventField[] getFields() {
+ LttngEventField tmpField = null;
+
+ LttngEventType tmpType = (LttngEventType)fParentEvent.getType();
+
+ for ( int pos=0; pos<tmpType.getNbFields(); pos++ ) {
+ String name = tmpType.getLabel(pos);
+ Object newValue = ((LttngEvent)getEvent()).convertEventTmfToJni().parseFieldByName(name);
+
+ tmpField = new LttngEventField(this, name, newValue );
+ fFieldsMap.put(name, tmpField);
}
return fFieldsMap.values().toArray(new LttngEventField[fFieldsMap.size()]);
}
@Override
public LttngEventField getField(int position) {
LttngEventField returnedField = null;
- String label = null;
- try {
- label = fParentEvent.getType().getLabel(position);
-
- returnedField = this.getField(label);
- }
- catch (TmfNoSuchFieldException e) {
- System.out.println("Invalid field position requested : " + position + ", ignoring (getField).");
- }
+ String label = fParentEvent.getType().getLabel(position);
+
+ if ( label != null ) {
+ returnedField = this.getField(label);
+ }
return returnedField;
}
* @see @see org.eclipse.linuxtools.lttng.event.LttngEventField
*/
@Override
- public synchronized LttngEventField getField(String name) {
- // *** VERIFY ***
+ public LttngEventField getField(String name) {
+ // *** VERIFY ***
// Should we check if the field exists in LttngType before parsing?
// It could avoid calling parse for non-existent fields but would waste some cpu cycle on check?
LttngEventField returnedField = fFieldsMap.get(name);
if ( returnedField == null ) {
// *** VERIFY ***
// Should we really make sure we didn't get null before creating/inserting a field?
- JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni();
-
- if ( tmpEvent != null) {
- Object newValue = tmpEvent.parseFieldByName(name);
-
- if ( newValue!= null ) {
- returnedField = new LttngEventField(this, name, newValue);
- fFieldsMap.put(name, returnedField );
- }
- }
+ Object newValue = ((LttngEvent)getEvent()).convertEventTmfToJni().parseFieldByName(name);
+
+ if ( newValue!= null ) {
+ returnedField = new LttngEventField(this, name, newValue);
+ fFieldsMap.put(name, returnedField );
+ }
}
return returnedField;
*/
@Override
public String toString() {
+ String returnedString = "";
+
LttngEventField[] allFields = getFields();
- StringBuffer strBuffer = new StringBuffer();
for ( int pos=0; pos < allFields.length; pos++) {
- if (pos != 0) strBuffer.append(",");
- strBuffer.append(allFields[pos].toString());
+ returnedString += allFields[pos].toString() + " ";
}
- return strBuffer.toString();
+ return returnedString;
}
}
\ No newline at end of file
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+
+/**
+ * <b><u>JniEvent</u></b> <p>
+ *
+ * A JniEvent has the actual content that got traced by Lttng.<br>
+ * Provides access to the LttEvent C structure in java. <p>
+ *
+ * Most important fields in the JniEvent are :
+ * <ul>
+ * <li>an event time, which is a digested timestamp.
+ * </ul>
+ * Note that the JniEvent content is not directly accessibe and should be obtained
+ * using the parseAllFields() or parseFieldBy...() methods.
+ */
+public final class JniEvent extends Jni_C_Common implements Comparable<JniEvent> {
+ // Variables to detect if the event have been filled at least once
+ // this make possible the detection of "uninitialized" struct in Ltt
+ // Can be "EOK", "ERANGE" or "EPERM" (defined in Jaf_C_Common)
+ private int eventState = EPERM; // Start with EPERM to ensure sanity
+
+ // Internal C pointer of the JniEvent used in LTT
+ private Jni_C_Pointer thisEventPtr = new Jni_C_Pointer();
+
+ // Reference to the parent tracefile
+ private JniTracefile parentTracefile = null;
+
+ // This map hold marker relative to the parent tracefile of this event
+ // They are "our" marker in this event
+ private HashMap<Integer, JniMarker> markersMap = null;
+
+ // Data we should populate from ltt
+ // Note that all type have been scaled up as there is no "unsigned" in java
+ // This might be a problem about "unsigned long" as there is no equivalent
+ // in java
+ private Jni_C_Pointer tracefilePtr = new Jni_C_Pointer();
+ private JniTime eventTime = null;
+
+ // These methods need a tracefile pointer, instead of a event pointer
+ private native int ltt_readNextEvent(long tracefilePtr);
+ private native int ltt_seekEvent(long tracefilePtr, JniTime givenTime);
+ private native int ltt_positionToFirstEvent(long tracefilePtr);
+
+ // Native access functions
+ private native long ltt_getTracefilePtr(long eventPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getBlock(long eventPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getOffset(long eventPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getCurrentTimestampCounter(long eventPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getTimestamp(long eventPtr);
+ private native int ltt_getEventMarkerId(long eventPtr);
+ private native long ltt_getNanosencondsTime(long eventPtr);
+ @SuppressWarnings("unused")
+ private native void ltt_feedEventTime(long eventPtr, JniTime eventTime);
+ private native long ltt_getEventDataSize(long eventPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getEventSize(long eventPtr);
+ @SuppressWarnings("unused")
+ private native int ltt_getCount(long eventPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getOverflowNanoSeconds(long eventPtr);
+
+ // This method an event pointer
+ private native void ltt_getDataContent(long eventPtr, long dataSize, byte[] returnedContent);
+
+ // Debug native function, ask LTT to print event structure
+ private native void ltt_printEvent(long eventPtr);
+
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+
+ /**
+ * Default constructor is forbidden
+ */
+ @SuppressWarnings("unused")
+ private JniEvent() {
+ };
+
+ /**
+ * Copy constructor.<p>
+ *
+ * @param oldEvent Reference to the JniEvent you want to copy.
+ */
+ public JniEvent(JniEvent oldEvent) {
+ thisEventPtr = oldEvent.thisEventPtr;
+ markersMap = oldEvent.markersMap;
+ parentTracefile = oldEvent.parentTracefile;
+ eventState = oldEvent.eventState;
+
+ tracefilePtr = oldEvent.tracefilePtr;
+ eventTime = oldEvent.eventTime;
+ }
+
+ /**
+ * Constructor with parameters<p>
+ *
+ * This constructor could throw. It will happen if an event can not be populated on <u>first read</u>.<br>
+ * In that case, the parent tracefile is probably useless and should be deleted.
+ *
+ * @param newEventPtr C pointer (converted in long) of the LttEvent C structure.
+ * @param newMarkersMap Reference an already populated HashMap of JniMarker objects
+ * @param newParentTracefile Reference to the parent JniTracefile of this JniEvent
+ *
+ * @exception JniException
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniMarker
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ */
+ public JniEvent(Jni_C_Pointer newEventPtr, HashMap<Integer, JniMarker> newMarkersMap, JniTracefile newParentTracefile) throws JniException {
+
+ // Basic test to make sure we didn't get null/empty value
+ if ((newEventPtr.getPointer() == NULL)
+ || (newMarkersMap == null)
+ || (newMarkersMap.size() == 0)
+ || (newParentTracefile == null)) {
+ throw new JniEventException("Null or empty value passed to constructor, object is invalid! (JniEvent)");
+ }
+
+ thisEventPtr = newEventPtr;
+ tracefilePtr = newParentTracefile.getTracefilePtr();
+ markersMap = newMarkersMap;
+ parentTracefile = newParentTracefile;
+
+ eventTime = new JniTime();
+
+ // Try to move to the first event
+ // If the event is Out of Range (ERANGE) at the first read,
+ // this event type will never be usable.
+ // In that case, throw JniNoSuchEventException to warn the tracefile.
+ eventState = positionToFirstEvent();
+ if (eventState != EOK) {
+ throw new JniNoSuchEventException("Object not populated, unusable. There is probably no event of that type in the trace. (JniEvent)");
+ }
+ else {
+ populateEventInformation();
+ }
+ }
+
+ /**
+ * Move to the next event and populate the java object with LttEvent structure.<p>
+ *
+ * If the move fails, the event will not get populated and the last event data will still be available.
+ *
+ * @return LTT read status, as defined in Jni_C_Common.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+ */
+ public int readNextEvent() {
+ // Ask Ltt to read the next event for this particular tracefile
+ eventState = ltt_readNextEvent( tracefilePtr.getPointer() );
+ // If the event state is sane populate it
+ if (eventState == EOK) {
+ populateEventInformation();
+ }
+
+ return eventState;
+ }
+
+ /**
+ * Seek to a certain time.<p>
+ *
+ * Seek to a certain time and read event at this exact time or the next one if there is no event there.<p>
+ *
+ * Note that this function can seek in an invalid position if the timestamp is after the last event.<br>
+ * In that case, a seek back would be required to get back to a consistent state.<p>
+ *
+ * If the seek fails, the event will not get populated and the last event data will still be available.<p>
+ *
+ * @return LTT read status, as defined in Jni_C_Common
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+ */
+ public int seekToTime(JniTime seekTime) {
+ // Ask Ltt to read the next event for this particular tracefile
+ eventState = ltt_seekEvent(tracefilePtr.getPointer(), seekTime);
+
+ // If the event state is sane populate it
+ if (eventState == EOK) {
+ populateEventInformation();
+ }
+
+ return eventState;
+ }
+
+ /**
+ * Try to seek to a certain time and seek back if it failed.<p>
+ *
+ * Seek to a certain time and read event at this exact time or the next one if there is no event there.<p>
+ *
+ * If the seek fails, we will seek back to the previous position, so the event will stay in a consistent state.<p>
+ *
+ * @return LTT read status, as defined in Jni_C_Common
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+ */
+ public int seekOrFallBack(JniTime seekTime) {
+ // Save the old time
+ JniTime oldTime = new JniTime(eventTime);
+
+ // Call seek to move ahead
+ // Save the state for the return (eventState will be modified if we seek back)
+ int returnState = seekToTime(seekTime);
+
+ // If the event state is sane populate it
+ if (returnState == EOK) {
+ populateEventInformation();
+ }
+ else {
+ seekToTime(oldTime);
+ }
+
+ return returnState;
+ }
+
+ /**
+ * Position on the first event in the tracefile.<p>
+ *
+ * The function return the read status after the first event.<p>
+ *
+ * A status different of EOK probably means there is no event associated to this tracefile.
+ *
+ * @return LTT read status, as defined in Jni_C_Common
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+ */
+ public int positionToFirstEvent() {
+ eventState = ltt_positionToFirstEvent(tracefilePtr.getPointer());
+
+ return eventState;
+ }
+
+ /**
+ * Obtain a marker associated with this tracefile's event.
+ *
+ * @return Reference to the marker for this tracefile's event or null if none.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniMarker
+ */
+ public JniMarker requestEventMarker() {
+ return markersMap.get(getEventMarkerId());
+ }
+
+ /**
+ * Obtain the raw data of a LttEvent object.<p>
+ *
+ * The data will be in raw C bytes, not java bytes.<br>
+ * Note : This function is mostly untested and provided "as is".
+ *
+ * @return Bytes array of raw data (contain raw C bytes).
+ */
+ public byte[] requestEventContent() {
+ byte dataContent[] = new byte[(int) getEventDataSize()];
+
+ ltt_getDataContent(thisEventPtr.getPointer(), getEventDataSize(), dataContent);
+
+ return dataContent;
+ }
+
+ /**
+ * Obtain an event source.<p>
+ *
+ * This is not implemented yet and will always return "Kernel core" for now.
+ *
+ * @return Reference to the JniMarker object for this event or null if none.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniMarker
+ */
+ public String requestEventSource() {
+ // *** TODO ***
+ // No "Source" of event exists in Ltt so far
+ // It would be a good addition to have a way to detect where an event come
+ // from, like "kernel" or "userspace"
+ //
+ return "Kernel Core";
+ }
+
+ /**
+ * Parse a particular field in the event payload, identified by its id (position).<p>
+ *
+ * Note : Position are relative to an event marker (i.e. requestEventMarker().getMarkerFieldsArrayList() )
+ *
+ * @param fieldId Position of the field to parse.
+ *
+ * @return Object that contain the parsed payload
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniParser
+ */
+ public Object parseFieldById(int fieldId) {
+ return JniParser.parseField(this, fieldId);
+ }
+
+ /**
+ * Parse a particular field in the event payload, identified by its name.<p>
+ *
+ * Note : Name are relative to an event marker (i.e. requestEventMarker().getMarkerFieldsHashMap() )
+ *
+ * @param fieldName Position of the field to parse.
+ *
+ * @return Object that contain the parsed payload
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniParser
+ */
+ public Object parseFieldByName(String fieldName) {
+ return JniParser.parseField(this, fieldName);
+ }
+
+ /**
+ * Method to parse all the event payload.<p>
+ *
+ * @return HashMap<String, Object> which is the parsedContent objects and their name as key.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniParser
+ */
+ public HashMap<String, Object> parseAllFields() {
+ return JniParser.parseAllFields(this);
+ }
+
+ /*
+ * This function populates the event data with data from LTT
+ *
+ * NOTE : To get better performance, we copy very few data into memory here
+ *
+ */
+ private void populateEventInformation() {
+ // We need to save the time, as it is not a primitive (can't be dynamically called in getter)
+ eventTime.setTime(ltt_getNanosencondsTime(thisEventPtr.getPointer() ));
+ }
+
+ public JniTime getEventTime() {
+ return eventTime;
+ }
+
+ // *** To get better performance, all getter belows call LTT directly ****
+ // That way, we can avoid copying data into memory
+ public int getEventMarkerId() {
+ return ltt_getEventMarkerId(thisEventPtr.getPointer());
+ }
+
+ public long getEventDataSize() {
+ return ltt_getEventDataSize(thisEventPtr.getPointer());
+ }
+
+ public HashMap<Integer, JniMarker> getMarkersMap() {
+ return markersMap;
+ }
+
+ /**
+ * Pointer to the parent LTTTracefile C structure.<br>
+ * <br>
+ * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+ * know what you are doing.
+ *
+ * @return The actual (long converted) pointer or NULL.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public Jni_C_Pointer getTracefilePtr() {
+ return new Jni_C_Pointer( ltt_getTracefilePtr(thisEventPtr.getPointer()) );
+ }
+
+ /**
+ * Pointer to the LttEvent C structure.<br>
+ * <br>
+ * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+ * know what you are doing.
+ *
+ * @return The actual (long converted) pointer or NULL.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public Jni_C_Pointer getEventPtr() {
+ return thisEventPtr;
+ }
+
+ public int getEventState() {
+ return eventState;
+ }
+
+ /**
+ * Getter to the parent tracefile for this event.
+ *
+ * @return The parent tracefile
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ */
+ public JniTracefile getParentTracefile() {
+ return parentTracefile;
+ }
+
+ /**
+ * Compare fonction for JNIEvent.<p>
+ * <p>
+ * This will compare the current JNIEvent with a passed one by timestamp AND tracefile ("type").<br>
+ * If both are equal but type differs, current event is considered to be older (-1 returned).
+ *
+ * @return -1 if given event happens before, 0 if equal, 1 if passed event happens after.
+ */
+ public int compareTo(JniEvent rightEvent ){
+
+ // Note : this = left hand operand
+
+ // By default, we consider the current event to be older.
+ int eventComparaison = -1;
+
+ // Test against null before performing anything
+ if ( rightEvent != null ) {
+ // Compare the timestamp first
+ eventComparaison = this.getEventTime().compareTo( rightEvent.getEventTime() );
+
+ // If timestamp is equal, compare the parent tracefile ("event type")
+ if ( (eventComparaison == 0) && ( !this.parentTracefile.equals(rightEvent.parentTracefile)) ) {
+ eventComparaison = 1;
+ }
+ }
+ return eventComparaison;
+ }
+
+ /**
+ * Print information for this event.
+ * <u>Intended to debug</u><br>
+ *
+ * This function will call Ltt to print, so information printed will be
+ * the one from the C structure, not the one populated in java.<p>
+ *
+ * This function will not throw but will complain loudly if pointer is NULL.
+ */
+ public void printEventInformation() {
+
+ // If null pointer, print a warning!
+ if (thisEventPtr.getPointer() == NULL) {
+ printlnC("Pointer is NULL, cannot print. (printEventInformation)");
+ }
+ else {
+ ltt_printEvent(thisEventPtr.getPointer());
+ }
+ }
+
+ /**
+ * toString() method.
+ * <u>Intended to debug.</u><p>
+ *
+ * @return Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "";
+
+ returnData += "tracefilePtr : " + tracefilePtr + "\n";
+ returnData += "eventMarkerId : " + getEventMarkerId() + "\n";
+ returnData += "eventTime : " + eventTime.getReferenceToString() + "\n";
+ returnData += " seconds : " + eventTime.getSeconds() + "\n";
+ returnData += " nanoSeconds : " + eventTime.getNanoSeconds() + "\n";
+ returnData += "eventDataSize : " + getEventDataSize() + "\n";
+ returnData += "markersMap : " + markersMap.keySet() + "\n"; // Hack to avoid ending up with markersMap.toString()
+
+ return returnData;
+ }
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>JniException</u></b>
+ * <p>
+ * Super class for JNI exception.
+ */
+public class JniException extends Exception {
+ private static final long serialVersionUID = -6620784221853154537L;
+
+ JniException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniTraceException</u></b>
+ * <p>
+ * Basic exception class for the JniTrace class
+ */
+class JniTraceException extends JniException {
+ private static final long serialVersionUID = -6873007333085268143L;
+
+ JniTraceException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniOpenTraceFailedException</u></b>
+ * <p>
+ * Sub-exception class type for JniTraceException
+ * This type will get thrown when a trace fail to open
+ * Most likely to be caused by a bad tracepath
+ */
+class JniOpenTraceFailedException extends JniTraceException {
+ private static final long serialVersionUID = 877769692366394895L;
+
+ JniOpenTraceFailedException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniNoNextEventInTraceException</u></b>
+ * <p>
+ * Sub-exception class type for JniTraceException
+ * This type will get thrown when we can't find any "next" event
+ * This should usually mean there is no more event in the trace
+
+ */
+class JniNoNextEventInTraceException extends JniTraceException {
+ private static final long serialVersionUID = -2887528566100063849L;
+
+ JniNoNextEventInTraceException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+//
+/**
+ * <b><u>JniTracefileException</u></b>
+ * <p>
+ * Basic exception class for the JniTracefile class
+ */
+class JniTracefileException extends JniException {
+ private static final long serialVersionUID = 5081317864491800084L;
+
+ JniTracefileException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniTracefileWithoutEventException</u></b>
+ * <p>
+ * Sub-exception class type for JniTracefileException
+ * This type will get thrown when a trace file contain no readable events
+ * The proper course of action would usually be to ignore this useless trace file
+ */
+class JniTracefileWithoutEventException extends JniTracefileException {
+ private static final long serialVersionUID = -8183967479236071261L;
+
+ JniTracefileWithoutEventException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniEventException</u></b>
+ * <p>
+ * Basic exception class for the JniEvent class
+ */
+class JniEventException extends JniException {
+ private static final long serialVersionUID = -5891749130387304519L;
+
+ JniEventException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniNoSuchEventException</u></b>
+ * <p>
+ * Sub-exception type for the JniEventException type
+ * This exception type will get thrown when an event is unavailable
+ * This might happen at construction because some events type are not present in
+ * the trace
+ */
+class JniNoSuchEventException extends JniEventException {
+ private static final long serialVersionUID = -4379712949891538051L;
+
+ JniNoSuchEventException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniEventOutOfRangeException</u></b>
+ * <p>
+ * Sub-exception type for the JniEventException type
+ * This exception type will get thrown when there is no more event of this type
+ * available
+ */
+class JniEventOutOfRangeException extends JniEventException {
+ private static final long serialVersionUID = -4645877232795324541L;
+
+ JniEventOutOfRangeException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniMarkerException</u></b>
+ * <p>
+ * Basic Exception class for the JniMarker class
+ */
+class JniMarkerException extends JniException {
+ private static final long serialVersionUID = -4694173610721983794L;
+
+ JniMarkerException(String errMsg) {
+ super(errMsg);
+ }
+}
+
+/**
+ * <b><u>JniMarkerFieldException</u></b>
+ * <p>
+ * Basic Exception class for the JniMarkerField class
+ */
+class JniMarkerFieldException extends JniException {
+ private static final long serialVersionUID = 6066381741374806879L;
+
+ JniMarkerFieldException(String errMsg) {
+ super(errMsg);
+ }
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * <b><u>JniMarker</u></b><p>
+ *
+ * A JniMarker contain information how to interpret the unparsed content (payload) of an event.<br>
+ * Each JniMarker contains several MarkerFields for each fields in the event's payload.
+ *
+ * Provides access to the marker_info C structure (from LTT) in java.
+ *
+ * Most important fields in the JniMarker are :
+ * <ul>
+ * <li> the name of the marker in String
+ * <li> an overview of the marker format (in C style printf format)
+ * <li> a reference to an ArrayList that contains MarkerFields object of this JniMarker
+ * </ul>
+ */
+public final class JniMarker extends Jni_C_Common
+{
+ // Internal C pointer of the JniEvent used in LTT
+ private Jni_C_Pointer thisMarkerPtr = new Jni_C_Pointer();
+
+ private String name = "";
+ private String formatOverview = "";
+
+ // These two contains hold references to the same MarkerField object
+ // The ArrayList can be used to efficiently find a field by its position
+ // The HashMap can be used to find a field by its name
+ private HashMap<String, JniMarkerField> markerFieldsHashMap = null;
+ private ArrayList<JniMarkerField> markerFieldsArrayList = null;
+
+ // Native access method
+ private native String ltt_getName(long markerPtr);
+ private native String ltt_getFormatOverview(long markerPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getSize(long markerPtr);
+ @SuppressWarnings("unused")
+ private native short ltt_getLargestAlign(long markerPtr);
+ @SuppressWarnings("unused")
+ private native short ltt_getIntSize(long markerPtr);
+ @SuppressWarnings("unused")
+ private native short ltt_getLongSize(long markerPtr);
+ @SuppressWarnings("unused")
+ private native short ltt_getPointerSize(long markerPtr);
+ @SuppressWarnings("unused")
+ private native short ltt_getSize_tSize(long markerPtr);
+ private native void ltt_getAllMarkerFields(long tracePtr);
+ @SuppressWarnings("unused")
+ private native short ltt_getAlignement(long markerPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getNextMarkerPtr(long markerPtr);
+
+ // Debug native function, ask LTT to print marker structure
+ private native void ltt_printMarker(long markerPtr);
+
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+ /*
+ * Default constructor is forbidden
+ */
+ @SuppressWarnings("unused")
+ private JniMarker() {
+ }
+
+ /**
+ * Copy constructor.<p>
+ *
+ * @param oldMarker Reference to the JniMarker you want to copy.
+ */
+ public JniMarker(JniMarker oldMarker) {
+ thisMarkerPtr = oldMarker.thisMarkerPtr;
+ name = oldMarker.name;
+ formatOverview = oldMarker.formatOverview;
+ markerFieldsHashMap = oldMarker.markerFieldsHashMap;
+ markerFieldsArrayList = oldMarker.markerFieldsArrayList;
+
+ }
+
+ /**
+ * Constructor, using pointer.<p>
+ *
+ * @param newMarkerPtr Pointer to a C marker_info structure
+ *
+ * @exception JniException
+ */
+ public JniMarker(Jni_C_Pointer newMarkerPtr) throws JniException {
+ thisMarkerPtr = newMarkerPtr;
+ markerFieldsArrayList = new ArrayList<JniMarkerField>();
+ markerFieldsHashMap = new HashMap<String, JniMarkerField>();
+
+ // Populate the marker
+ populateMarkerInformation();
+ }
+
+
+ /*
+ * This function populates the marker data with data from LTT
+ *
+ */
+ private void populateMarkerInformation() throws JniException {
+ if (thisMarkerPtr.getPointer() == NULL) {
+ throw new JniMarkerException("Pointer is NULL, trace closed? (populateMarkerInformatOverviewion)");
+ } else {
+ name = ltt_getName( thisMarkerPtr.getPointer() );
+ formatOverview = ltt_getFormatOverview( thisMarkerPtr.getPointer() );
+ // To fill the markerFieldArray is a bit different
+ ltt_getAllMarkerFields( thisMarkerPtr.getPointer() );
+ }
+ }
+
+ /*
+ * Fills a map of all the JniMarkerField associated with this JniMarker.
+ *
+ * Note: This function is called from C and there is no way to propagate
+ * exception back to the caller without crashing JNI. Therefore, it MUST
+ * catch all exceptions.
+ *
+ * @param markerName Name of the parent marker
+ * @param markerFieldPtr C Pointer (converted in long) to marker_field C Structure
+ */
+ @SuppressWarnings("unused")
+ private void addMarkerFieldFromC(String markerFieldName, long markerFieldPtr) {
+ // Create a new Jaf_markerField object and insert it in the map
+ // the maker field fill itself with LTT data while being constructed
+ try {
+ JniMarkerField newMarkerField = new JniMarkerField( new Jni_C_Pointer(markerFieldPtr) );
+ markerFieldsArrayList.add(newMarkerField);
+ markerFieldsHashMap.put(markerFieldName, newMarkerField);
+
+ } catch (JniException e) {
+ printlnC("Failed to add marker field " + markerFieldName + " to marker fields list!(addMarkerFieldFromC)\n\tException raised : " + e.toString() );
+ }
+ }
+
+ // Access to class variable. Most of them doesn't have setter
+ public String getName() {
+ return name;
+ }
+
+ public String getFormatOverview() {
+ return formatOverview;
+ }
+
+ public HashMap<String,JniMarkerField> getMarkerFieldsHashMap() {
+ return markerFieldsHashMap;
+ }
+
+ public ArrayList<JniMarkerField> getMarkerFieldsArrayList() {
+ return markerFieldsArrayList;
+ }
+
+ /**
+ * Pointer to the marker_info C structure.<p>
+ *
+ * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+ * know what you are doing.<p>
+ *
+ * @return The actual (long converted) pointer or NULL
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public Jni_C_Pointer getMarkerPtr() {
+ return thisMarkerPtr;
+ }
+
+
+ /**
+ * Print information for this JniMarker.
+ * <u>Intended to debug</u><br>
+ *
+ * This function will call Ltt to print, so information printed will be the one from
+ * the C structure, not the one populated in java.<p>
+ *
+ * This function will not throw but will complain loudly if pointer is NULL
+ */
+ public void printMarkerInformation() {
+
+ // If null pointer, print a warning!
+ if (thisMarkerPtr.getPointer() == NULL) {
+ printlnC("Pointer is NULL, cannot print. (printMarkerInformation)");
+ } else {
+ ltt_printMarker(thisMarkerPtr.getPointer());
+ }
+ }
+
+ /**
+ * Print information for ALL marker fields for this marker.
+ * <u>Intended to debug</u><br>
+ *
+ * This function will call Ltt to print, so information printed will be the one from
+ * the C structure, not the one populated in java.
+ */
+ public void printAllMarkerFieldsInformation() {
+ Object[] allMarkersField = markerFieldsArrayList.toArray();
+
+ for (int pos = 0; pos < allMarkersField.length; pos++) {
+ printlnC(allMarkersField[pos].toString());
+ }
+ }
+
+ /**
+ * toString() method.
+ * <u>Intended to debug</u><br>
+ *
+ * @return Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "";
+
+ returnData += "name : " + name + "\n";
+ returnData += "formatOverview : " + formatOverview + "\n";
+ returnData += "markerFieldArrayList : " + markerFieldsArrayList.toArray() + "\n";
+
+ return returnData;
+ }
+
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>JniMarkerField</u></b> <p>
+ * A JniMarkerField is one of the field of the unparsed content (payload) of an event. <p>
+ *
+ * Provides access to the marker_field C structure (from LTT) in java.<p>
+ *
+ * Most important attributes in the JniMarkerField are :
+ * <ul>
+ * <li> the name (field) of in String
+ * <li> the marker field format (in C style printf format)
+ * </ul>
+ */
+public final class JniMarkerField extends Jni_C_Common
+{
+ // Internal C pointer of the JniEvent used in LTT
+ private Jni_C_Pointer thisMarkerFieldPtr = new Jni_C_Pointer();
+
+ private String field = "";
+ private String format = "";
+
+ // Native access method
+ private native String ltt_getField(long markerFieldPtr);
+ @SuppressWarnings("unused")
+ private native int ltt_getType(long markerFieldPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getOffset(long markerFieldPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getSize(long markerFieldPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getAlignment(long markerFieldPtr);
+ @SuppressWarnings("unused")
+ private native long ltt_getAttributes(long markerFieldPtr);
+ @SuppressWarnings("unused")
+ private native int ltt_getStatic_offset(long markerFieldPtr);
+ private native String ltt_getFormat(long markerFieldPtr);
+
+ // Debug native function, ask LTT to print marker structure
+ private native void ltt_printMarkerField(long markerFieldPtr);
+
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+ /*
+ * Default constructor is forbidden
+ */
+ @SuppressWarnings("unused")
+ private JniMarkerField() {
+ }
+
+ /**
+ * Copy constructor.<p>
+ *
+ * @param oldMarkerField Reference to the JniMarkerField you want to copy.
+ */
+ public JniMarkerField(JniMarkerField oldMarkerField) {
+ thisMarkerFieldPtr = oldMarkerField.getMarkerFieldPtr();
+ field = oldMarkerField.getField();
+ format = oldMarkerField.getFormat();
+ }
+
+ /**
+ * Constructor, using pointer.<p>
+ *
+ * @param newMarkerFieldPtr Pointer to a C marker_field structure
+ *
+ * @exception JniException
+ */
+ public JniMarkerField(Jni_C_Pointer newMarkerFieldPtr) throws JniException {
+ thisMarkerFieldPtr = newMarkerFieldPtr;
+
+ // Populate the marker field
+ populateMarkerFieldInformation();
+ }
+
+ /*
+ * This function populates the marker field data with data from LTT
+ *
+ */
+ private void populateMarkerFieldInformation() throws JniException {
+ if (thisMarkerFieldPtr.getPointer() == NULL) {
+ throw new JniMarkerFieldException(
+ "Pointer is NULL, trace closed? (populateMarkerInformation)");
+ } else {
+ field = ltt_getField(thisMarkerFieldPtr.getPointer());
+ format = ltt_getFormat(thisMarkerFieldPtr.getPointer());
+ }
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Pointer to the marker_field C structure.<p>
+ *
+ * The pointer should only be used <u>INTERNALY</u>, do not use these unless you
+ * know what you are doing.<p>
+ *
+ * @return The actual (long converted) pointer or NULL
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public Jni_C_Pointer getMarkerFieldPtr() {
+ return thisMarkerFieldPtr;
+ }
+
+ /**
+ * Print information for this event. <u>Intended to debug</u><br>
+ *
+ * This function will call Ltt to print, so information printed will be the one from
+ * the C structure, not the one populated in java.<p>
+ *
+ * This function will not throw but will complain loudly if pointer is NULL
+ */
+ public void printMarkerFieldInformation() {
+
+ // If null pointer, print a warning!
+ if (thisMarkerFieldPtr.getPointer() == NULL) {
+ printlnC("Pointer is NULL, cannot print. (printMarkerFieldInformation)");
+ } else {
+ ltt_printMarkerField(thisMarkerFieldPtr.getPointer());
+ }
+ }
+
+ /**
+ * toString() method.
+ * <u>Intended to debug</u><br>
+ *
+ * @return Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "";
+ returnData += "field : " + field + "\n";
+ returnData += "format : " + format + "\n";
+
+ return returnData;
+ }
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * <b><u>JniParser</u></b><p>
+ *
+ * JniParser is used to parse an event payload into something usable.<p>
+ *
+ * All methods are static, the parser shouldn't be instantiated.
+ */
+public class JniParser extends Jni_C_Common
+{
+ private static native void ltt_getParsedData(ParsedObjectContent parseddata, long eventPtr, long markerFieldPtr);
+
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+ // *** HACK ***
+ // We cannot use "Object" directly as java does not support swapping primitive value
+ // We either need to create a new object type or to use a "non-primitive" type that have "Setter()" functions
+ // Another (ugly) hack would be to pass an array to modify the reference's reference.
+ // ***
+ private static ParsedObjectContent parsedData = new ParsedObjectContent();
+
+ /*
+ * Default constructor is forbidden
+ */
+ private JniParser() {
+ }
+
+
+ /**
+ * Method to parse a single field identified by its id.<p>
+ *
+ * All parsing will be done on C side as we need LTT functions.
+ *
+ * @param eventToParse The jni event we want to parse.
+ * @param fieldPosition The position (or id) of the field we want to parse
+ *
+ * @return An Object that contain the JniEvent payload parsed by the C, or null, if if was impossible to parse (i.e., wrong position)
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ static public Object parseField(JniEvent eventToParse, int fieldPosition) {
+
+ // Sanity check
+ if ( (fieldPosition < 0) || ( fieldPosition >= eventToParse.requestEventMarker().getMarkerFieldsArrayList().size() ) ){
+ return null;
+ }
+
+ JniMarkerField tmpField = eventToParse.requestEventMarker().getMarkerFieldsArrayList().get(fieldPosition);
+
+ // Call the parsing function in C. The result will be put in parsedData object
+ ltt_getParsedData(parsedData, eventToParse.getEventPtr().getPointer(), tmpField.getMarkerFieldPtr().getPointer() );
+
+ return parsedData.getData();
+ }
+
+
+ /**
+ * Method to parse a single field identified by its name.<p>
+ *
+ * All parsing will be done on C side as we need LTT functions.
+ *
+ * @param eventToParse The jni event we want to parse.
+ * @param fieldName The name of the field we want to parse.
+ *
+ * @return An Object that contain the JniEvent payload parsed by the C, or null, if if was impossible to parse (i.e., wrong position)
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ static public Object parseField(JniEvent eventToParse, String fieldName) {
+
+ JniMarkerField tmpField = eventToParse.requestEventMarker().getMarkerFieldsHashMap().get(fieldName);
+
+ // return immediately if there is no field by that name
+ if ( tmpField == null ) {
+ return null;
+ }
+
+ ltt_getParsedData(parsedData, eventToParse.getEventPtr().getPointer(), tmpField.getMarkerFieldPtr().getPointer() );
+
+ return parsedData.getData();
+ }
+
+
+
+ /**
+ * Method to parse all fields at once.<p>
+ *
+ * All parsing will be done on C side as we need LTT functions.
+ *
+ * @param eventToParse The jni event we want to parse.
+ * @return An HashMap of Object that contain the is the JniEvent's payload parsed by the C
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ static public HashMap<String, Object> parseAllFields(JniEvent eventToParse) {
+ HashMap<String,JniMarkerField> markerFieldData = eventToParse.requestEventMarker().getMarkerFieldsHashMap();
+
+ // This hashmap will contain the parsed content.
+ // ParsedContent is a local class defined at the end of this file
+
+ // *** HACK ***
+ // We want (need?) the map that contain the parsed data to be in the same order as markerField map
+ // The "instinctive way" would be to use :
+ // HashMap<String, Object> parsedDataMap = new HashMap<String, Object>(nbMarkerField);
+ //
+ // However, we cannot ensure that the newly created hashmap will use the same order.
+ // The hard way would be to override the default hash function for both hashmap
+ // However, this is way easier to abuse the fact that both hashmap are of type <String, something...>
+ // Therefore we can abuse the java-cast with clone() :
+ // HashMap<String, Object> parsedDataMap = (HashMap<String, Object>)markerFieldData.clone();
+ // Or even safer, use HashMap constructor to do so :
+ HashMap<String, Object> parsedDataMap = new HashMap<String, Object>(markerFieldData);
+
+ String newKey = null;
+ JniMarkerField newMarkerField = null;
+ Iterator<String> iterator = markerFieldData.keySet().iterator();
+
+ while ( iterator.hasNext() ) {
+ newKey = iterator.next();
+ newMarkerField = markerFieldData.get(newKey);
+ // Call the C to parse the data
+ ltt_getParsedData(parsedData, eventToParse.getEventPtr().getPointer(), newMarkerField.getMarkerFieldPtr().getPointer() );
+ // Save the result into the HashMap
+ parsedDataMap.put(newMarkerField.getField(), parsedData.getData() );
+ }
+
+ return parsedDataMap;
+ }
+
+
+ /*
+ * Add a parsed String value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param parsedArray Array where to store the value
+ * @param fieldName The name of the parsed field
+ * @param stringToAdd The parsed data to add
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addStringToParsingFromC(Object contentHolder, String stringToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( stringToAdd);
+ }
+
+ /*
+ * Add a parsed 64 bits Pointer value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param pointerToAdd The parsed data to add (in 64 bits long!)
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addLongPointerToParsingFromC(Object contentHolder, long pointerToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Jni_C_Pointer((long) pointerToAdd));
+ }
+
+ /*
+ * Add a parsed 32 bits Pointer value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param pointerToAdd The parsed data to add (converted in 64 bits long!)
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addIntPointerToParsingFromC(Object contentHolder, long pointerToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Jni_C_Pointer((int) pointerToAdd));
+ }
+
+ /*
+ * Add a parsed short value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param shortToAdd The parsed data to add
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addShortToParsingFromC(Object contentHolder, short shortToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Short(shortToAdd));
+ }
+
+ /*
+ * Add a parsed integer value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param intToAdd The parsed data to add
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addIntegerToParsingFromC(Object contentHolder, int intToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Integer(intToAdd));
+ }
+
+ /*
+ * Add a parsed long value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param longToAdd The parsed data to add
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addLongToParsingFromC(Object contentHolder, long longToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Long(longToAdd));
+ }
+
+ /*
+ * Add a parsed float value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param floatToAdd The parsed data to add
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addFloatToParsingFromC(Object contentHolder, float floatToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Float(floatToAdd));
+ }
+
+ /*
+ * Add a parsed double value to the Array<br>
+ * <br>
+ * Note : this function will be called from the C side.
+ * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+ * its goal is to give a generic interface to people that would like to use the JNI library
+ *
+ *
+ * @param contentHolder Object where to store the parsed value
+ * @param fieldName The name of the parsed field
+ * @param doubleToAdd The parsed data to add
+ * @param formatToAdd The format of the raw data
+ */
+ @SuppressWarnings("unused")
+ static private void addDoubleToParsingFromC(Object contentHolder, double doubleToAdd) {
+ ((ParsedObjectContent)contentHolder).setData( new Double(doubleToAdd));
+ }
+
+}
+
+/**
+ * <b><u>ParsedObjectContent</u></b><p>
+ *
+ * ParsedObjectContent class.
+ * Only be used locally in this object to parse event data more efficiently in the C.
+ */
+class ParsedObjectContent {
+ private Object parsedData = null;
+
+ public Object getData() {
+ return parsedData;
+ }
+
+ public void setData(Object newData) {
+ parsedData = newData;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>JniTime</u></b>
+ * <p>
+ * Used to store (event, trace, tracefile, ...) timestamp.
+ *
+ * Mimic the behavior of the LttTime C structure.
+ */
+public final class JniTime extends Jni_C_Common implements Comparable<JniTime>
+{
+ private long time = 0;
+
+ /**
+ * Default constructor.<p>
+ *
+ * Note : Time will be set to 0.
+ *
+ */
+ public JniTime() {
+ time = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param oldTime Reference to the JniTime you want to copy.
+ */
+ public JniTime(JniTime oldTime) {
+ time = oldTime.getTime();
+ }
+
+ /**
+ * Constructor with parameters.<p>
+ *
+ * "LTT style" constructor with Seconds et Nanoseconds
+ *
+ * @param newSec Seconds of the JniTime
+ * @param newNanoSec Nanoseconds of the JniTime
+ */
+ public JniTime(long newSec, long newNanoSec) {
+ time = (newSec * NANO) + newNanoSec;
+ }
+
+ /**
+ * Constructor with parameters.<p>
+ *
+ * Usual "nanosecond only" constructor.
+ *
+ * @param newNanoSecTime Time in nanoseconds
+ */
+ public JniTime(long newNanoSecTime) {
+ time = newNanoSecTime;
+ }
+
+ /**
+ * Second of the time.<p>
+ *
+ * Returns seconds, i.e. multiple of 1 000 000, of the stored nanoseconds time.
+ *
+ * @return Second of this time.
+ */
+ public long getSeconds() {
+ return (time / NANO);
+ }
+
+ /**
+ * Getter for the nanosecond of the time.<p>
+ *
+ * Returns nanoseconds part, i.e. modulo of 1 000 000, of the stored nanoseconds time.
+ *
+ * @return Nanoseconds of this time
+ */
+ public long getNanoSeconds() {
+ return time % NANO;
+ }
+
+ /**
+ * Full time, in nanoseconds.<p>
+ *
+ * @return Complete time in nanoseconds
+ */
+ public long getTime() {
+ return time;
+ }
+
+ /**
+ * Changes the current time for this object<p>
+ *
+ * @param newTime New time to set, in nanoseconds.
+ */
+ public void setTime(long newTime) {
+ time = newTime;
+ }
+
+ /*
+ * Populate this time object
+ *
+ * Note: This function is called from C side.
+ *
+ * @param newTime The time we want to populate
+ */
+ @SuppressWarnings("unused")
+ private void setTimeFromC(long newTime) {
+ time = newTime;
+ }
+
+ /**
+ * Comparaison operator smaller or equal than "<=" .<p>
+ *
+ * @param comparedTime The time we want to compare with this one
+ *
+ * @return true if compared time is smaller or equal, false otherwise
+ */
+ public boolean isSmallerOrEqual(JniTime comparedTime) {
+
+ // NOTE : We check <= instead of just <
+ // This mean the LEFT OPERAND (comparedTime) always prevails
+ if (this.getTime() <= comparedTime.getTime() ) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * compareTo operator.<p>
+ *
+ * @param right The time we want to compare with this one
+ *
+ * @return int of value -1, 0 or 1, as the pased argument is bigger, equal or smaller than this time
+ */
+ public int compareTo(JniTime right) {
+ long leftTime = this.getTime();
+ long rightTime = right.getTime();
+
+ if ( leftTime < rightTime ) {
+ return -1;
+ }
+ else if ( leftTime > rightTime ) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ /**
+ * toString() method.
+ * <u>Intended to debug</u><p>
+ *
+ * NOTE : We output the time in the same format as LTT (seconds and nanosecond separatly)
+ *
+ * @return String Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "";
+
+ returnData += "seconds : " + this.getSeconds() + "\n";
+ returnData += "nanoSeconds : " + this.getNanoSeconds() + "\n";
+
+ return returnData;
+ }
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.PriorityQueue;
+
+/**
+ * <b><u>JniTrace</u></b>
+ * <p>
+ * This is the top level class in the JNI. It provides access to the
+ * LttTrace C structure in java.
+ * <p>
+ * Most important fields in the JniTrace are :
+ * <ul>
+ * <li>a JniTrace path (a trace <b>directory</b>)
+ * <li>a HashMap of tracefiles that exists in this trace
+ * </ul>
+ */
+public class JniTrace extends Jni_C_Common {
+
+ private final static boolean DEFAULT_LTT_DEBUG = false;
+
+ // Internal C pointer of the JniTrace used in LTT
+ private Jni_C_Pointer thisTracePtr = new Jni_C_Pointer();
+
+ // Data we should populate from LTT
+ // Note that all type have been scaled up as there is no "unsigned" in java
+ // This might be a problem about "unsigned long" as there is no equivalent
+ // in java
+
+ private String tracepath = ""; // Path of the trace. Should be a directory (like : /tmp/traceX)
+ private int cpuNumber = 0;
+ private long archType = 0;
+ private long archVariant = 0;
+ private short archSize = 0;
+ private short lttMajorVersion = 0;
+ private short lttMinorVersion = 0;
+ private short flightRecorder = 0;
+ private long freqScale = 0;
+ private long startFreq = 0;
+ private long startTimestampCurrentCounter = 0;
+ private long startMonotonic = 0;
+ private JniTime startTimeNoAdjustement = null;
+ private JniTime startTime = null;
+ private JniTime endTime = null;
+
+ // This Map holds a reference to the tracefiles owned by this trace
+ private HashMap<String, JniTracefile> tracefilesMap = null;
+ // The priority queue (similar to heap) hold events
+ private PriorityQueue<JniEvent> eventsHeap = null;
+
+ // This variable will hold the content of the "last" event we read
+ private JniEvent currentEvent = null;
+
+ // Should we print debug in the C library or not?
+ private boolean printLttDebug = DEFAULT_LTT_DEBUG;
+
+ // Open/close native functions
+ private native long ltt_openTrace(String pathname, boolean printDebug);
+ private native void ltt_closeTrace(long tracePtr);
+
+ // Native access functions
+ private native String ltt_getTracepath(long tracePtr);
+ private native int ltt_getCpuNumber(long tracePtr);
+ private native long ltt_getArchType(long tracePtr);
+ private native long ltt_getArchVariant(long tracePtr);
+ private native short ltt_getArchSize(long tracePtr);
+ private native short ltt_getLttMajorVersion(long tracePtr);
+ private native short ltt_getLttMinorVersion(long tracePtr);
+ private native short ltt_getFlightRecorder(long tracePtr);
+ private native long ltt_getFreqScale(long tracePtr);
+ private native long ltt_getStartFreq(long tracePtr);
+ private native long ltt_getStartTimestampCurrentCounter(long tracePtr);
+ private native long ltt_getStartMonotonic(long tracePtr);
+
+ // Native function to fill out startTime
+ private native void ltt_feedStartTime(long tracePtr, JniTime startTime);
+
+ // Native function to fill out startTimeFromTimestampCurrentCounter
+ private native void ltt_feedStartTimeFromTimestampCurrentCounter(long tracePtr, JniTime startTime);
+
+ // Native function to fill out tracefilesMap
+ private native void ltt_feedAllTracefiles(long tracePtr);
+
+ // Native function to fill out the start and end time of the trace
+ private native void ltt_feedTracefileTimeRange(long tracePtr, JniTime startTime, JniTime endTime);
+
+ // Debug native function, ask LTT to print trace structure
+ private native void ltt_printTrace(long tracePtr);
+
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+ /*
+ * Default constructor is forbidden
+ */
+ @SuppressWarnings("unused")
+ private JniTrace() {
+ }
+
+ /**
+ * Constructor that takes a tracepath parameter.<p>
+ *
+ * This constructor also opens the trace.
+ *
+ * @param newpath The <b>directory</b> of the trace to be opened
+ * @param newPrintDebug Should the debug information be printed in the LTT C library
+ *
+ * @exception JniException
+ */
+ public JniTrace(String newpath, boolean newPrintDebug) throws JniException {
+ tracepath = newpath;
+ thisTracePtr = new Jni_C_Pointer();
+ printLttDebug = newPrintDebug;
+
+ openTrace(newpath);
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param oldTrace A reference to the JniTrace to copy.
+ */
+ public JniTrace(JniTrace oldTrace) {
+ thisTracePtr = oldTrace.thisTracePtr;
+
+ tracepath = oldTrace.tracepath;
+ cpuNumber = oldTrace.cpuNumber;
+ archType = oldTrace.archType;
+ archVariant = oldTrace.archVariant;
+ archSize = oldTrace.archSize;
+ lttMajorVersion = oldTrace.lttMajorVersion;
+ lttMinorVersion = oldTrace.lttMinorVersion;
+ flightRecorder = oldTrace.flightRecorder;
+ freqScale = oldTrace.freqScale;
+ startFreq = oldTrace.startFreq;
+ startTimestampCurrentCounter = oldTrace.startTimestampCurrentCounter;
+ startMonotonic = oldTrace.startMonotonic;
+ startTimeNoAdjustement = oldTrace.startTimeNoAdjustement;
+ startTime = oldTrace.startTime;
+ endTime = oldTrace.endTime;
+
+ tracefilesMap = new HashMap<String, JniTracefile>(oldTrace.tracefilesMap.size());
+ tracefilesMap = oldTrace.tracefilesMap;
+
+ eventsHeap = new PriorityQueue<JniEvent>( oldTrace.eventsHeap.size());
+ eventsHeap = oldTrace.eventsHeap;
+
+ printLttDebug = oldTrace.printLttDebug;
+ }
+
+ /**
+ * Constructor, using C pointer.<p>
+ *
+ * @param newPtr The pointer to an already opened LttTrace C structure.
+ * @param newPrintDebug Should the debug information be printed in the LTT C library
+ *
+ * @exception JniException
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public JniTrace(Jni_C_Pointer newPtr, boolean newPrintDebug) throws JniException {
+ thisTracePtr = newPtr;
+ printLttDebug = newPrintDebug;
+
+ // Populate our trace
+ populateTraceInformation();
+ }
+
+ /**
+ * Open an existing trace.<p>
+ *
+ * The tracepath is a directory and needs to exist, otherwise
+ * a JafOpenTraceFailedException is throwed.
+ *
+ * @param newPath The <b>directory</b> of the trace to be opened
+ *
+ * @exception JniOpenTraceFailedException Thrown if the open failed
+ */
+ public void openTrace(String newPath) throws JniException {
+ // If open is called while a trace is already opened, we will try to close it first
+ if (thisTracePtr.getPointer() != NULL) {
+ closeTrace();
+ }
+
+ // Set the tracepath and open it
+ tracepath = newPath;
+ openTrace();
+ }
+
+ /**
+ * Open an existing trace.<p>
+ *
+ * The tracepath should have been set already,
+ *
+ * @exception JniOpenTraceFailedException Thrown if the open failed
+ */
+ public void openTrace() throws JniException {
+
+ // Raise an exception if the tracepath is empty, otherwise open the trace
+ if (tracepath == "") {
+ throw new JniTraceException("Tracepath is not set. (openTrace)");
+ }
+
+ // If the file is already opened, close it first
+ if (thisTracePtr.getPointer() != NULL) {
+ closeTrace();
+ }
+
+ // Call the LTT to open the trace
+ long newPtr = ltt_openTrace(tracepath, printLttDebug);
+ if (newPtr == NULL) {
+ throw new JniOpenTraceFailedException("Error while opening trace. Is the tracepath correct? (openTrace)");
+ }
+
+ // This is OUR pointer
+ thisTracePtr = new Jni_C_Pointer(newPtr);
+
+ // Populate the trace with LTT information
+ populateTraceInformation();
+ }
+
+ /**
+ * Close a trace.<p>
+ *
+ * If the trace is already closed, will silently do nothing.
+ */
+ public void closeTrace() {
+ if (thisTracePtr.getPointer() != NULL) {
+ ltt_closeTrace(thisTracePtr.getPointer());
+ thisTracePtr = new Jni_C_Pointer(NULL);
+
+ // Clear the tracefile map
+ tracefilesMap.clear();
+ tracefilesMap = null;
+
+ // Clear the eventsHeap and make it points to null
+ eventsHeap.clear();
+ eventsHeap = null;
+
+ // Ask the garbage collector to make a little pass here, as we could
+ // be left with 100's of unreferenced objects
+ System.gc();
+ }
+ }
+
+ /*
+ * This function populates the trace data with data from LTT
+ *
+ * @throws JniException
+ */
+ private void populateTraceInformation() throws JniException {
+ if (thisTracePtr.getPointer() == NULL) {
+ throw new JniTraceException("Pointer is NULL, trace not opened/already closed? (populateTraceInformation)");
+ }
+
+ // Populate from the LTT library
+ tracepath = ltt_getTracepath( thisTracePtr.getPointer() );
+ cpuNumber = ltt_getCpuNumber( thisTracePtr.getPointer() );
+ archType = ltt_getArchType( thisTracePtr.getPointer() );
+ archVariant = ltt_getArchVariant( thisTracePtr.getPointer() );
+ archSize = ltt_getArchSize( thisTracePtr.getPointer() );
+ lttMajorVersion = ltt_getLttMajorVersion( thisTracePtr.getPointer() );
+ lttMinorVersion = ltt_getLttMinorVersion( thisTracePtr.getPointer() );
+ flightRecorder = ltt_getFlightRecorder( thisTracePtr.getPointer() );
+ freqScale = ltt_getFreqScale( thisTracePtr.getPointer() );
+ startFreq = ltt_getStartFreq( thisTracePtr.getPointer() );
+ startTimestampCurrentCounter = ltt_getStartTimestampCurrentCounter( thisTracePtr.getPointer() );
+ startMonotonic = ltt_getStartMonotonic( thisTracePtr.getPointer() );
+
+ // Creation of time is a bit different, we need to pass the object reference to C
+ //
+ // *** NOTE : LTTv consider "raw startTime" (time without any frequency adjustement) to be default startTime
+ // So "startTimeNoAdjustement" is obtain throught "ltt_feedStartTime()" and
+ // "startTime" is obtained from ltt_feedStartTimeFromTimestampCurrentCounter()
+ startTimeNoAdjustement = new JniTime();
+ ltt_feedStartTime( thisTracePtr.getPointer(), startTimeNoAdjustement );
+
+ startTime = new JniTime();
+ ltt_feedStartTimeFromTimestampCurrentCounter( thisTracePtr.getPointer(), startTime );
+
+ // Call the fill up function for the tracefiles map
+ if ( tracefilesMap== null ) {
+ tracefilesMap = new HashMap<String, JniTracefile>();
+ }
+ ltt_feedAllTracefiles( thisTracePtr.getPointer() );
+
+ // Now, obtain the trace "endTime"
+ // Note that we discard "startTime" right away, as we already have it
+ endTime = new JniTime();
+ ltt_feedTracefileTimeRange(thisTracePtr.getPointer(), new JniTime(), endTime);
+
+ if (eventsHeap == null) {
+ eventsHeap = new PriorityQueue<JniEvent>(tracefilesMap.size());
+ }
+
+ // Populate the heap with events
+ populateEventHeap();
+ }
+
+ /*
+ * This function populates the event heap with one event from each tracefile
+ * It should be called after each seek or when the object is constructed
+ */
+ private void populateEventHeap() {
+ currentEvent = null;
+ eventsHeap.clear();
+
+ Object new_key = null;
+ JniTracefile tmpTracefile = null;
+
+ Iterator<String> iterator = tracefilesMap.keySet().iterator();
+ while( iterator.hasNext() ) {
+ new_key = iterator.next();
+
+ tmpTracefile = tracefilesMap.get(new_key);
+ if ( tmpTracefile.getCurrentEvent().getEventState() == EOK ) {
+ eventsHeap.add( tmpTracefile.getCurrentEvent() );
+ }
+ }
+ }
+
+ /*
+ * Fills a map of all the trace files.
+ *
+ * Note: This function is called from C and there is no way to propagate
+ * exception back to the caller without crashing JNI. Therefore, it MUST
+ * catch all exceptions.
+ *
+ * @param tracefileName
+ * @param tracefilePtr
+ */
+ @SuppressWarnings("unused")
+ private void addTracefileFromC(String tracefileName, long tracefilePtr) {
+
+ JniTracefile newTracefile = null;
+
+ // Create a new tracefile object and insert it in the map
+ // the tracefile fill itself with LTT data while being constructed
+ try {
+ newTracefile = new JniTracefile( new Jni_C_Pointer(tracefilePtr), this );
+ tracefilesMap.put( (tracefileName + newTracefile.getCpuNumber()), newTracefile);
+ }
+ catch(JniTracefileWithoutEventException e) {
+ printlnC("JniTracefile " + tracefileName + " has no event (addTracefileFromC). Ignoring.");
+ }
+ catch(Exception e) {
+ printlnC("Failed to add tracefile " + tracefileName + " to tracefilesMap!(addTracefileFromC)\n\tException raised : " + e.toString() );
+ }
+ }
+
+ /**
+ * Return the top event in the events stack, determined by timestamp, in the trace (all the tracefiles).<p>
+ *
+ * Note : If the events were read before, the top event and the event currently loaded (currentEvent) are most likely the same.
+ *
+ * @return The top event in the stack or null if no event is available.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ public JniEvent findNextEvent() {
+ return eventsHeap.peek();
+ }
+
+ /**
+ * Return the next event in the events stack, determined by timestamp, in the trace (all the tracefiles).<p>
+ *
+ * @return The next event in the trace or null if no event is available.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ public JniEvent readNextEvent() {
+ // Get the "next" event on the top of the heap but DO NOT remove it
+ JniEvent tmpEvent = eventsHeap.peek();
+
+ // If the event is null, it was the last one in the trace we can leave the function
+ if (tmpEvent == null) {
+ return null;
+ }
+
+ // Otherwise, we need to make sure the timestamp of the event we got is not the same as the last "NextEvent" we requested
+ // NOTE : JniEvent.compareTo() compare by timestamp AND type, as 2 events of different type could have the same timestamp.
+ if ( tmpEvent.compareTo(currentEvent) == 0 ) {
+ // Remove the event on top as it is the same currentEventTimestamp
+ eventsHeap.poll();
+
+ // Read the next event for this particular event type
+ tmpEvent.readNextEvent();
+
+ // If the event state is sane (not Out of Range), put it back in the heap
+ if ( tmpEvent.getEventState() == EOK ) {
+ eventsHeap.add(tmpEvent);
+ }
+
+ // Pick the top event again
+ tmpEvent = eventsHeap.peek();
+
+ // Save the event we just read as the "current event"
+ currentEvent = tmpEvent;
+ }
+ // If the event on top has different timestamp than the currentTimestamp, just save this timestamp as current
+ else {
+ currentEvent = tmpEvent;
+ }
+
+ return tmpEvent;
+ }
+
+ /**
+ * Read the next event on a certain tracefile.<p>
+ *
+ * By calling this function make sure the "global" readNextEvent() stay synchronised.
+ * Calling readNextEvent() after this function will consider this tracefile moved and is then consistent.
+ *
+ * @param targetTracefile The tracefile object to read from
+ *
+ * @return The next event in the tracefile or null if no event is available.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ public JniEvent readNextEvent(JniTracefile targetTracefile) {
+ JniEvent returnedEvent = null;
+
+ // There is 2 special cases where we should read the CURRENT event, not the next one
+ // 1- The currentEvent is null --> We never read or we just seeked
+ // 2- The currentEvent is of another type --> We last read on a DIFFERENT tracefile
+ if ( (currentEvent == null) ||
+ (currentEvent.getParentTracefile().equals(targetTracefile) == false)
+ ) {
+ returnedEvent = targetTracefile.getCurrentEvent();
+ // Save the event we read
+ currentEvent = returnedEvent;
+ }
+ else {
+ // Remove from the event related to this tracefile from the event heap, if it exists.
+ // WARNING : This only safe as long getCurrentEvent() never return "null" in any case.
+ eventsHeap.remove(targetTracefile.getCurrentEvent() );
+
+ // If status EOK, we can return the event, otherwise something wrong happen (out of range, read error, etc...)
+ if ( targetTracefile.readNextEvent() == EOK) {
+ returnedEvent = targetTracefile.getCurrentEvent();
+ // Add back to the heap the read event
+ eventsHeap.add(returnedEvent);
+ }
+ // Save the event we read...
+ // Note : might be null if the read failed and it's ok
+ currentEvent = targetTracefile.getCurrentEvent();
+ }
+
+ return returnedEvent;
+ }
+
+ /**
+ * Seek to a certain time but <b>do not</b> read the next event.<p>
+ *
+ * This only position the trace, it will not return anything.<p>
+ *
+ * @param seekTime The time where we want to seek to
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+ */
+ public void seekToTime(JniTime seekTime) {
+
+ // Invalidate the last read event
+ currentEvent = null;
+
+ Object tracefile_name = null;
+ Iterator<String> iterator = tracefilesMap.keySet().iterator();
+
+ while (iterator.hasNext() ) {
+ // We seek to the given event for ALL tracefiles
+ tracefile_name = iterator.next();
+ seekToTime(seekTime, tracefilesMap.get(tracefile_name));
+ }
+
+ populateEventHeap();
+ }
+
+ /**
+ * Seek to a certain time on a certain tracefile but <b>do not</b> read the next event.<p>
+ *
+ * This only position the trace, it will not return anything.<p>
+ *
+ * @param targetTracefile The tracefile object to read from
+ * @param seekTime The time where we want to seek to
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+ */
+ public void seekToTime(JniTime seekTime, JniTracefile targetTracefile) {
+ // Invalidate the current read event
+ currentEvent = null;
+
+ // Remove from the event related to this tracefile from the event heap, if it exists.
+ // WARNING : This is only safe as long getCurrentEvent() never return "null" in any case.
+ eventsHeap.remove(targetTracefile.getCurrentEvent() );
+
+ // Perform the actual seek on the tracefile
+ // Add the event to the heap if it succeed
+ if ( targetTracefile.seekToTime(seekTime) == EOK) {
+ // Add back to the heap the read event
+ eventsHeap.add(targetTracefile.getCurrentEvent());
+ }
+ }
+
+ /**
+ * Seek to a certain timestamp and read the next event.
+ * <p>
+ * If no more events are available or an error happen, null will be returned.
+ *
+ * @param seekTime The time where we want to seek to.
+ *
+ * @return The event just after the seeked time or null if none available.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+ */
+ public JniEvent seekAndRead(JniTime seekTime) {
+ JniEvent returnedEvent = null;
+ seekToTime(seekTime);
+
+ // The trace should be correctly positionned, let's get the event
+ returnedEvent = readNextEvent();
+
+ return returnedEvent;
+ }
+
+ /**
+ * Seek to a certain timestamp on a certain tracefile and read the next event.<p>
+ *
+ * If no more events are available or an error happen, null will be returned.
+ *
+ * Calling readNextEvent() after this function will consider this tracefile moved and is then consistent.<br>
+ *
+ * @param tracefileName The tracefile object to read from
+ * @param seekTime The time where we want to seek to
+ *
+ * @return The event just after the seeked time or null if none available.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ public JniEvent seekAndRead(JniTime seekTime, JniTracefile targetTracefile) {
+ seekToTime(seekTime, targetTracefile);
+ return readNextEvent(targetTracefile);
+ }
+
+ /**
+ * Get a certain tracefile from its given name.<p>
+ *
+ * @param tracefileName The name of the tracefile.
+ *
+ * @return The tracefile found or null if none.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ */
+ public JniTracefile requestTracefileByName(String tracefileName) {
+ return tracefilesMap.get(tracefileName);
+ }
+
+ /**
+ * Get a certain event associated to a tracefile from the tracefile name.<p>
+ *
+ * @param tracefileName The name of the trace file.
+ *
+ * @return Event of the tracefile or null if none found.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+ */
+ public JniEvent requestEventByName(String tracefileName) {
+ JniEvent returnValue = null;
+
+ JniTracefile tmpTracefile = tracefilesMap.get(tracefileName);
+
+ // If the tracefile is found, return the current event
+ // There should always be an event linked to a tracefile
+ if (tmpTracefile != null) {
+ returnValue = tmpTracefile.getCurrentEvent();
+ }
+
+ return returnValue;
+ }
+
+ // Access to class variable. Most of them doesn't have setter
+ public String getTracepath() {
+ return tracepath;
+ }
+
+ public int getCpuNumber() {
+ return cpuNumber;
+ }
+
+ public long getArchType() {
+ return archType;
+ }
+
+ public long getArchVariant() {
+ return archVariant;
+ }
+
+ public short getArchSize() {
+ return archSize;
+ }
+
+ public short getLttMajorVersion() {
+ return lttMajorVersion;
+ }
+
+ public short getLttMinorVersion() {
+ return lttMinorVersion;
+ }
+
+ public short getFlightRecorder() {
+ return flightRecorder;
+ }
+
+ public long getFreqScale() {
+ return freqScale;
+ }
+
+ public long getStartFreq() {
+ return startFreq;
+ }
+
+ public long getStartTimestampCurrentCounter() {
+ return startTimestampCurrentCounter;
+ }
+
+ public long getStartMonotonic() {
+ return startMonotonic;
+ }
+
+ public JniTime getStartTime() {
+ return startTime;
+ }
+
+ public JniTime getEndTime() {
+ return endTime;
+ }
+
+ public JniTime getStartTimeNoAdjustement() {
+ return startTimeNoAdjustement;
+ }
+
+ public HashMap<String, JniTracefile> getTracefilesMap() {
+ return tracefilesMap;
+ }
+
+ /**
+ * The timestamp of the last read event.<p>
+ *
+ * Note : If no event is available, Long.MAX_VALUE is returned.
+ *
+ * @return Time of the last event read
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+ */
+ public JniTime getCurrentEventTimestamp() {
+ JniTime returnedTime = null;
+
+ // If no event were read or we reach the last event in the trace,
+ // currentEvent will be null
+ if ( currentEvent != null ) {
+ returnedTime = currentEvent.getEventTime();
+ }
+ else {
+ returnedTime = new JniTime(Long.MAX_VALUE);
+ }
+ return returnedTime;
+ }
+
+ /**
+ * Pointer to the LttTrace C structure.<p>
+ *
+ * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+ * know what you are doing.
+ *
+ * @return The actual (long converted) pointer or NULL.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public Jni_C_Pointer getTracePtr() {
+ return thisTracePtr;
+ }
+
+ /**
+ * Return boolean value saying if the debug is enabled in LTT or not.<p>
+ *
+ * Note : this need to be set at construction.
+ *
+ * @return If the debug is set or not
+ */
+ public boolean isPrintingLttDebug() {
+ return printLttDebug;
+ }
+
+ /**
+ * Print information for all the tracefiles associated with this trace.
+ * <u>Intended to debug</u><p>
+ *
+ * This function will call Ltt to print, so information printed will be the
+ * one from the C structure, not the one populated in java.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+ */
+ public void printAllTracefilesInformation() {
+ JniTracefile tracefile = null;
+
+ Iterator<String> iterator = tracefilesMap.keySet().iterator();
+ while (iterator.hasNext()) {
+ tracefile = tracefilesMap.get(iterator.next());
+ tracefile.printTracefileInformation();
+ }
+ }
+
+ /**
+ * Print information for this trace.
+ * <u>Intended to debug</u><p>
+ *
+ * This function will call Ltt to print, so information printed will be the
+ * one from the C structure, not the one populated in java.<p>
+ * <br>
+ * This function will not throw but will complain loudly if pointer is NULL
+ */
+ public void printTraceInformation() {
+
+ // If null pointer, print a warning!
+ if (thisTracePtr.getPointer() == NULL) {
+ printlnC("Pointer is NULL, cannot print. (printTraceInformation)");
+ }
+ else {
+ ltt_printTrace( thisTracePtr.getPointer() );
+ }
+ }
+
+ /**
+ * toString() method.
+ * <u>Intended to debug</u><br>
+ *
+ * @return Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "";
+ returnData += "tracepath : " + tracepath + "\n";
+ returnData += "cpuNumber : " + cpuNumber + "\n";
+ returnData += "archType : " + archType + "\n";
+ returnData += "archVariant : " + archVariant + "\n";
+ returnData += "archSize : " + archSize + "\n";
+ returnData += "lttMajorVersion : " + lttMajorVersion + "\n";
+ returnData += "lttMinorVersion : " + lttMinorVersion + "\n";
+ returnData += "flightRecorder : " + flightRecorder + "\n";
+ returnData += "freqScale : " + freqScale + "\n";
+ returnData += "startFreq : " + startFreq + "\n";
+ returnData += "startTimestampCurrentCounter : " + startTimestampCurrentCounter + "\n";
+ returnData += "startMonotonic : " + startMonotonic + "\n";
+ returnData += "startTimeNoAdjustement : " + startTimeNoAdjustement.getReferenceToString() + "\n";
+ returnData += " seconds : " + startTimeNoAdjustement.getSeconds() + "\n";
+ returnData += " nanoSeconds : " + startTimeNoAdjustement.getNanoSeconds() + "\n";
+ returnData += "startTime : " + startTime.getReferenceToString() + "\n";
+ returnData += " seconds : " + startTime.getSeconds() + "\n";
+ returnData += " nanoSeconds : " + startTime.getNanoSeconds() + "\n";
+ returnData += "endTime : " + endTime.getReferenceToString() + "\n";
+ returnData += " seconds : " + endTime.getSeconds() + "\n";
+ returnData += " nanoSeconds : " + endTime.getNanoSeconds() + "\n";
+ returnData += "tracefilesMap : " + tracefilesMap.keySet() + "\n"; // Hack to avoid ending up with tracefilesMap.toString()
+
+ return returnData;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+
+/**
+ * <b><u>JniTracefile</u></b>
+ * <p>
+ * A tracefile own an event of a certain type.<br>
+ * Provides access to the LttTracefile C structure in java.
+ * <p>
+ * Most important fields in the JniTracefile are :
+ * <ul>
+ * <li> a JniTracefile path (a tracefile <b>file</b> within a JniTrace directory)
+ * <li> a name (basically the name without the directory part)
+ * <li> a reference to a single event object
+ * <li> a HashMap of marker associated with this tracefile
+ * </ul>
+ */
+public final class JniTracefile extends Jni_C_Common {
+
+ // Internal C pointer of the JniTracefile used in LTT
+ private Jni_C_Pointer thisTracefilePtr = new Jni_C_Pointer();
+
+ // Reference to the parent trace
+ private JniTrace parentTrace = null;
+
+ // Data we should populate from LTT
+ // Note that all type have been scaled up as there is no "unsigned" in java
+ // This might be a problem about "unsigned long" as there is no equivalent in java
+ private boolean isCpuOnline = false;
+ private String tracefilePath = "";
+ private String tracefileName = "";
+ private long cpuNumber = 0;
+ private long tid = 0;
+ private long pgid = 0;
+ private long creation = 0;
+
+ // Internal C pointer for trace and marker
+ private Jni_C_Pointer tracePtr = null;
+ private Jni_C_Pointer markerDataPtr = null;
+
+ private int CFileDescriptor = 0;
+ private long fileSize = 0;
+ private long blocksNumber = 0;
+ private boolean isBytesOrderReversed = false;
+ private boolean isFloatWordOrdered = false;
+ private long alignement = 0;
+ private long bufferHeaderSize = 0;
+ private int bitsOfCurrentTimestampCounter = 0;
+ private int bitsOfEvent = 0;
+ private long currentTimestampCounterMask = 0;
+ private long currentTimestampCounterMaskNextBit = 0;
+ private long eventsLost = 0;
+ private long subBufferCorrupt = 0;
+ private JniEvent currentEvent = null;
+
+ // Internal C pointer for trace and marker
+ private Jni_C_Pointer bufferPtr = null;
+
+ private long bufferSize = 0;
+
+ // This map will hold markers_info owned by this tracefile
+ private HashMap<Integer, JniMarker> tracefileMarkersMap = null;
+
+ // Native access functions
+ private native boolean ltt_getIsCpuOnline(long tracefilePtr);
+ private native String ltt_getTracefilepath(long tracefilePtr);
+ private native String ltt_getTracefilename(long tracefilePtr);
+ private native long ltt_getCpuNumber(long tracefilePtr);
+ private native long ltt_getTid(long tracefilePtr);
+ private native long ltt_getPgid(long tracefilePtr);
+ private native long ltt_getCreation(long tracefilePtr);
+ private native long ltt_getTracePtr(long tracefilePtr);
+ private native long ltt_getMarkerDataPtr(long tracefilePtr);
+ private native int ltt_getCFileDescriptor(long tracefilePtr);
+ private native long ltt_getFileSize(long tracefilePtr);
+ private native long ltt_getBlockNumber(long tracefilePtr);
+ private native boolean ltt_getIsBytesOrderReversed(long tracefilePtr);
+ private native boolean ltt_getIsFloatWordOrdered(long tracefilePtr);
+ private native long ltt_getAlignement(long tracefilePtr);
+ private native long ltt_getBufferHeaderSize(long tracefilePtr);
+ private native int ltt_getBitsOfCurrentTimestampCounter(long tracefilePtr);
+ private native int ltt_getBitsOfEvent(long tracefilePtr);
+ private native long ltt_getCurrentTimestampCounterMask(long tracefilePtr);
+ private native long ltt_getCurrentTimestampCounterMaskNextBit(long tracefilePtr);
+ private native long ltt_getEventsLost(long tracefilePtr);
+ private native long ltt_getSubBufferCorrupt(long tracefilePtr);
+ private native long ltt_getEventPtr(long tracefilePtr);
+ private native long ltt_getBufferPtr(long tracefilePtr);
+ private native long ltt_getBufferSize(long tracefilePtr);
+
+ // Method to fill a map with marker object
+ private native void ltt_feedAllMarkers(long tracefilePtr);
+
+ // Debug native function, ask LTT to print tracefile structure
+ private native void ltt_printTracefile(long tracefilePtr);
+
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+ /*
+ * Default constructor is forbidden
+ */
+ @SuppressWarnings("unused")
+ private JniTracefile() {
+ };
+
+ /**
+ * Copy constructor.<p>
+ *
+ * @param oldTracefile Reference to the JniTracefile you want to copy.
+ */
+ public JniTracefile(JniTracefile oldTracefile) {
+ thisTracefilePtr = oldTracefile.thisTracefilePtr;
+ parentTrace = oldTracefile.parentTrace;
+ tracefileMarkersMap = oldTracefile.tracefileMarkersMap;
+ isCpuOnline = oldTracefile.isCpuOnline;
+ tracefilePath = oldTracefile.tracefilePath;
+ tracefileName = oldTracefile.tracefileName;
+ cpuNumber = oldTracefile.cpuNumber;
+ tid = oldTracefile.tid;
+ pgid = oldTracefile.pgid;
+ creation = oldTracefile.creation;
+ tracePtr = oldTracefile.tracePtr;
+ markerDataPtr = oldTracefile.markerDataPtr;
+ CFileDescriptor = oldTracefile.CFileDescriptor;
+ fileSize = oldTracefile.fileSize;
+ blocksNumber = oldTracefile.blocksNumber;
+ isBytesOrderReversed = oldTracefile.isBytesOrderReversed;
+ isFloatWordOrdered = oldTracefile.isFloatWordOrdered;
+ alignement = oldTracefile.alignement;
+ bufferHeaderSize = oldTracefile.bufferHeaderSize;
+ bitsOfCurrentTimestampCounter = oldTracefile.bitsOfCurrentTimestampCounter;
+ bitsOfEvent = oldTracefile.bitsOfEvent;
+ currentTimestampCounterMask = oldTracefile.currentTimestampCounterMask;
+ currentTimestampCounterMaskNextBit = oldTracefile.currentTimestampCounterMaskNextBit;
+ eventsLost = oldTracefile.eventsLost;
+ subBufferCorrupt = oldTracefile.subBufferCorrupt;
+ currentEvent = oldTracefile.currentEvent;
+ bufferPtr = oldTracefile.bufferPtr;
+ bufferSize = oldTracefile.bufferSize;
+ }
+
+ /**
+ * Constructor, using C pointer.<p>
+ *
+ * @param newPtr The pointer of an already opened LttTracefile C Structure
+ *
+ * @exception JniException
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTrace
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public JniTracefile(Jni_C_Pointer newPtr, JniTrace newParentTrace) throws JniException {
+ thisTracefilePtr = newPtr;
+ parentTrace = newParentTrace;
+ tracefileMarkersMap = new HashMap<Integer, JniMarker>();
+
+ // Retrieve the trace file information and load the first event.
+ try {
+ populateTracefileInformation();
+ } catch (JniNoSuchEventException e) {
+ throw new JniTracefileWithoutEventException(
+ "JniEvent constructor reported that no event of this type are usable. (Jaf_Tracefile)");
+ }
+ }
+
+ /**
+ * Read the next event of this tracefile.<p>
+ *
+ * Note : If the read succeed, the event will be populated.<p>
+ *
+ * @return LTT read status, as defined in Jni_C_Common
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+ */
+ public int readNextEvent() {
+ return currentEvent.readNextEvent();
+ }
+
+ /**
+ * Seek to the given time.<p>
+ *
+ * Note : If the seek succeed, the event will be populated.
+ *
+ * @param seekTime The timestamp where to seek.
+ *
+ * @return LTT read status, as defined in Jni_C_Common
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+ */
+ public int seekToTime(JniTime seekTime) {
+ return currentEvent.seekToTime(seekTime);
+ }
+
+ /*
+ * This function populates the tracefile data with data from LTT
+ *
+ * @throws JniException
+ */
+ private void populateTracefileInformation() throws JniException {
+ if (thisTracefilePtr.getPointer() == NULL) {
+ throw new JniTracefileException(
+ "Pointer is NULL, trace closed? (populateTracefileInformation)");
+ }
+
+ isCpuOnline = ltt_getIsCpuOnline( thisTracefilePtr.getPointer() );
+ tracefilePath = ltt_getTracefilepath( thisTracefilePtr.getPointer() );
+ tracefileName = ltt_getTracefilename( thisTracefilePtr.getPointer() );
+ cpuNumber = ltt_getCpuNumber( thisTracefilePtr.getPointer() );
+ tid = ltt_getTid( thisTracefilePtr.getPointer() );
+ pgid = ltt_getPgid( thisTracefilePtr.getPointer() );
+ creation = ltt_getCreation( thisTracefilePtr.getPointer() );
+ tracePtr = new Jni_C_Pointer(ltt_getTracePtr( thisTracefilePtr.getPointer()) );
+ markerDataPtr = new Jni_C_Pointer(ltt_getMarkerDataPtr( thisTracefilePtr.getPointer()) );
+ CFileDescriptor = ltt_getCFileDescriptor( thisTracefilePtr.getPointer() );
+ fileSize = ltt_getFileSize( thisTracefilePtr.getPointer() );
+ blocksNumber = ltt_getBlockNumber( thisTracefilePtr.getPointer() );
+ isBytesOrderReversed = ltt_getIsBytesOrderReversed( thisTracefilePtr.getPointer() );
+ isFloatWordOrdered = ltt_getIsFloatWordOrdered( thisTracefilePtr.getPointer() );
+ alignement = ltt_getAlignement( thisTracefilePtr.getPointer() );
+ bufferHeaderSize = ltt_getBufferHeaderSize( thisTracefilePtr.getPointer() );
+ bitsOfCurrentTimestampCounter = ltt_getBitsOfCurrentTimestampCounter( thisTracefilePtr.getPointer() );
+ bitsOfEvent = ltt_getBitsOfEvent( thisTracefilePtr.getPointer() );
+ currentTimestampCounterMask = ltt_getCurrentTimestampCounterMask( thisTracefilePtr.getPointer() );
+ currentTimestampCounterMaskNextBit = ltt_getCurrentTimestampCounterMaskNextBit( thisTracefilePtr.getPointer() );
+ eventsLost = ltt_getEventsLost( thisTracefilePtr.getPointer() );
+ subBufferCorrupt = ltt_getSubBufferCorrupt( thisTracefilePtr.getPointer() );
+ bufferPtr = new Jni_C_Pointer(ltt_getBufferPtr( thisTracefilePtr.getPointer()) );
+ bufferSize = ltt_getBufferSize( thisTracefilePtr.getPointer() );
+
+ // To fill the map is a bit different
+ ltt_feedAllMarkers( thisTracefilePtr.getPointer() );
+
+ Jni_C_Pointer tmpEventPointer = new Jni_C_Pointer(ltt_getEventPtr(thisTracefilePtr.getPointer()));
+ currentEvent = new JniEvent(tmpEventPointer , tracefileMarkersMap, this);
+ }
+
+ /*
+ * Fills a map of all the markers associated with this tracefile.
+ *
+ * Note: This function is called from C and there is no way to propagate
+ * exception back to the caller without crashing JNI. Therefore, it MUST
+ * catch all exceptions.
+ *
+ * @param markerId Id of the marker (int)
+ * @param markerInfoPtr C Pointer to a marker_info C structure
+ */
+ @SuppressWarnings("unused")
+ private void addMarkersFromC(int markerId, long markerInfoPtr) {
+ // Create a new tracefile object and insert it in the map
+ // the tracefile fill itself with LTT data while being constructed
+ try {
+ JniMarker newMarker = new JniMarker( new Jni_C_Pointer(markerInfoPtr) );
+
+ tracefileMarkersMap.put(markerId, newMarker);
+ } catch (Exception e) {
+ printlnC("Failed to add marker to tracefileMarkersMap!(addMarkersFromC)\n\tException raised : " + e.toString());
+ }
+ }
+
+ // Access to class variable. Most of them doesn't have setter
+ public boolean getIsCpuOnline() {
+ return isCpuOnline;
+ }
+
+ public String getTracefilePath() {
+ return tracefilePath;
+ }
+
+ public String getTracefileName() {
+ return tracefileName;
+ }
+
+ public long getCpuNumber() {
+ return cpuNumber;
+ }
+
+ public long getTid() {
+ return tid;
+ }
+
+ public long getPgid() {
+ return pgid;
+ }
+
+ public long getCreation() {
+ return creation;
+ }
+
+ public Jni_C_Pointer getTracePtr() {
+ return tracePtr;
+ }
+
+ public Jni_C_Pointer getMarkerDataPtr() {
+ return markerDataPtr;
+ }
+
+ public int getCFileDescriptor() {
+ return CFileDescriptor;
+ }
+
+ public long getFileSize() {
+ return fileSize;
+ }
+
+ public long getBlocksNumber() {
+ return blocksNumber;
+ }
+
+ public boolean getIsBytesOrderReversed() {
+ return isBytesOrderReversed;
+ }
+
+ public boolean getIsFloatWordOrdered() {
+ return isFloatWordOrdered;
+ }
+
+ public long getAlignement() {
+ return alignement;
+ }
+
+ public long getBufferHeaderSize() {
+ return bufferHeaderSize;
+ }
+
+ public int getBitsOfCurrentTimestampCounter() {
+ return bitsOfCurrentTimestampCounter;
+ }
+
+ public int getBitsOfEvent() {
+ return bitsOfEvent;
+ }
+
+ public long getCurrentTimestampCounterMask() {
+ return currentTimestampCounterMask;
+ }
+
+ public long getCurrentTimestampCounterMaskNextBit() {
+ return currentTimestampCounterMaskNextBit;
+ }
+
+ public long getEventsLost() {
+ return eventsLost;
+ }
+
+ public long getSubBufferCorrupt() {
+ return subBufferCorrupt;
+ }
+
+ public JniEvent getCurrentEvent() {
+ return currentEvent;
+ }
+
+ public Jni_C_Pointer getBufferPtr() {
+ return bufferPtr;
+ }
+
+ public long getBufferSize() {
+ return bufferSize;
+ }
+
+ public HashMap<Integer, JniMarker> getTracefileMarkersMap() {
+ return tracefileMarkersMap;
+ }
+
+ /**
+ * Parent trace of this tracefile.<p>
+ *
+ * @return The parent trace
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTrace
+ */
+ public JniTrace getParentTrace() {
+ return parentTrace;
+ }
+
+ /**
+ * Pointer to the LttTracefile C structure<p>
+ *
+ * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+ * know what you are doing.<p>
+ *
+ * @return The actual (long converted) pointer or NULL.
+ *
+ * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+ */
+ public Jni_C_Pointer getTracefilePtr() {
+ return thisTracefilePtr;
+ }
+
+ /**
+ * Print information for this tracefile.
+ * <u>Intended to debug</u><p>
+ *
+ * This function will call Ltt to print, so information printed will be the
+ * one from the C structure, not the one populated in java.<p>
+ *
+ * This function will not throw but will complain loudly if pointer is NULL.
+ */
+ public void printTracefileInformation() {
+
+ // If null pointer, print a warning!
+ if (thisTracefilePtr.getPointer() == NULL) {
+ printlnC("Pointer is NULL, cannot print. (printTracefileInformation)");
+ }
+ else {
+ ltt_printTracefile( thisTracefilePtr.getPointer() );
+ }
+ }
+
+ /**
+ * toString() method.
+ * <u>Intended to debug</u><p>
+ *
+ * @return Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "";
+
+ returnData += "isCpuOnline : " + isCpuOnline + "\n";
+ returnData += "tracefilePath : " + tracefilePath + "\n";
+ returnData += "tracefileName : " + tracefileName + "\n";
+ returnData += "cpuNumber : " + cpuNumber + "\n";
+ returnData += "tid : " + tid + "\n";
+ returnData += "pgid : " + pgid + "\n";
+ returnData += "creation : " + creation + "\n";
+ returnData += "tracePtr : " + tracePtr + "\n";
+ returnData += "markerDataPtr : " + markerDataPtr + "\n";
+ returnData += "CFileDescriptor : " + CFileDescriptor + "\n";
+ returnData += "fileSize : " + fileSize + "\n";
+ returnData += "blocksNumber : " + blocksNumber + "\n";
+ returnData += "isBytesOrderReversed : " + isBytesOrderReversed + "\n";
+ returnData += "isFloatWordOrdered : " + isFloatWordOrdered + "\n";
+ returnData += "alignement : " + alignement + "\n";
+ returnData += "bufferHeaderSize : " + bufferHeaderSize + "\n";
+ returnData += "bitsOfCurrentTimestampCounter : " + bitsOfCurrentTimestampCounter + "\n";
+ returnData += "bitsOfEvent : " + bitsOfEvent + "\n";
+ returnData += "currentTimestampCounterMask : " + currentTimestampCounterMask + "\n";
+ returnData += "currentTimestampCounterMaskNextBit : " + currentTimestampCounterMaskNextBit + "\n";
+ returnData += "eventsLost : " + eventsLost + "\n";
+ returnData += "subBufferCorrupt : " + subBufferCorrupt + "\n";
+ returnData += "currentEvent : " + currentEvent.getReferenceToString() + "\n"; // Hack to avoid ending up with event.toString()
+ returnData += "bufferPtr : " + bufferPtr + "\n";
+ returnData += "bufferSize : " + bufferSize + "\n";
+ returnData += "tracefileMarkersMap : " + tracefileMarkersMap.keySet() + "\n"; // Hack to avoid ending up with tracefileMarkersMap.toString()
+
+ return returnData;
+ }
+}
+
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>Jni_C_Common</u></b>
+ * <p>
+ * Common constants and methods that should be shared between JNI objects
+ */
+public abstract class Jni_C_Common {
+
+ // Needed for native types
+ public static final int NULL = 0;
+
+ // C errno correspondance. Used to interpret LTT return value
+ public static final int EOK = 0;
+ public static final int EPERM = 1;
+ public static final int ERANGE = 34;
+
+ // Timestamps are in nanoseconds, this const ease up the math
+ public static final long NANO = 1000000000;
+
+ // Native console printing function
+ private native void ltt_printC(String string_to_print);
+
+ // Load LTTV library (order is important)
+ static {
+ System.loadLibrary("lttvtraceread");
+ }
+
+ /**
+ * Java-side console printing function.<p>
+ *
+ * Call the C printing function to make sure all printing happen on the same side.
+ *
+ * @param msg The string to print in C.
+ */
+ public void printC(String msg) {
+ // Need to escape "%" for C printf
+ msg = msg.replaceAll("%", "%%");
+ ltt_printC(msg);
+ }
+
+ /**
+ * Java-side console printing function that add carriage return. <p>
+ *
+ * Call the C printing function to make sure all printing happen on the same side.
+ *
+ * @param msg The string to print in C.
+ */
+ public void printlnC(String msg) {
+ printC(msg + "\n");
+ }
+
+ /**
+ * "Alternate" .toString()<p>
+ *
+ * Simulates the way Java Object implements "toString()"
+ *
+ * @return The Java hashed UID of the object (i.e. : NAME@HASH)
+ */
+ public String getReferenceToString() {
+ return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.eclipse.linuxtools.lttng.jni;
+
+
+/**
+ * <b><u>Jni_C_Pointer</u></b>
+ * <p>
+ * Class pointer to handle properly "C pointer" <p>
+ *
+ * Can transparently handle pointer of 32 or 64 bits.
+ */
+public class Jni_C_Pointer extends Jni_C_Common {
+
+ private long ptr = NULL;
+ private boolean isLong = true;
+
+ /**
+ * Default constructor.<p>
+ *
+ * Note : Pointer will be set to a 64bits "NULL".
+ */
+ public Jni_C_Pointer() {
+ ptr = NULL;
+ }
+
+ /**
+ * Constructor with parameters for 64bits pointers.
+ *
+ * @param newPtr long-converted (64 bits) C pointer.
+ */
+ public Jni_C_Pointer(long newPtr) {
+ ptr = newPtr;
+ isLong = true;
+ }
+
+ /**
+ * Constructor with parameters for 32bits pointers.
+ *
+ * @param newPtr int-converted (32 bits) C pointer.
+ */
+ public Jni_C_Pointer(int newPtr) {
+ ptr = (long)newPtr;
+ isLong = false;
+ }
+
+ /**
+ * Get the current pointer.
+ *
+ * @return The current pointer, in long.
+ */
+ public long getPointer() {
+ return ptr;
+ }
+
+ /**
+ * Set the pointer, as a 64bits pointer.
+ *
+ * @param newPtr long-converted (64 bits) C pointer.
+ */
+ public void setPointer(long newPtr) {
+ ptr = newPtr;
+ isLong = true;
+ }
+
+ /**
+ * Set the pointer, as a 64bits pointer.
+ *
+ * @param newPtr int-converted (32 bits) C pointer.
+ */
+ public void setPointer(int newPtr) {
+ ptr = newPtr;
+ isLong = false;
+ }
+
+ /**
+ * toString() method. <p>
+ *
+ * Convert the pointer to a nice looking int/long hexadecimal format.
+ *
+ * @return Attributes of the object concatenated in String
+ */
+ @Override
+ public String toString() {
+ String returnData = "0x";
+
+ if (isLong == true) {
+ returnData += Long.toHexString(ptr);
+ }
+ else {
+ returnData += Integer.toHexString((int) ptr);
+ }
+
+ return returnData;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state;
+
+
+/**
+ * Interface to be used to receive notification of Processing start and
+ * completed
+ *
+ * @author alvaro
+ *
+ */
+public interface IStateDataRequestListener {
+ // ========================================================================
+ // Methods
+ // ========================================================================
+
+ /**
+ *
+ * @param request
+ * @return
+ */
+ public void processingStarted(RequestStartedSignal request);
+
+ /**
+ * @param signal
+ */
+ public void processingCompleted(RequestCompletedSignal signal);
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state;
+
+import org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef;
+import org.eclipse.linuxtools.lttng.trace.LTTngTextTrace;
+import org.eclipse.linuxtools.lttng.trace.LTTngTrace;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+
+/**
+ * Interface data provider to the state.model package
+ *
+ * @author alvaro
+ *
+ */
+public class LttngStateInputRef implements ILttngStateInputRef {
+
+ private int cpuNumber = -1;
+
+ // ========================================================================
+ // Table data
+ // =======================================================================
+ TmfTrace log = null;
+
+ // ========================================================================
+ // Constructor
+ // ========================================================================
+ LttngStateInputRef(TmfTrace log) {
+ this.log = log;
+
+ if ( log instanceof LTTngTrace) {
+ cpuNumber = ((LTTngTrace)log).getCpuNumber();
+ }
+ else if ( log instanceof LTTngTextTrace) {
+ cpuNumber = ((LTTngTextTrace)log).getCpuNumber();
+ }
+ }
+
+ // ========================================================================
+ // Methods
+ // =======================================================================
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.linuxtools.lttng.ui.state.model.ILttngStateInputRef#
+ * getNumberOfCpus()
+ */
+ // @Override
+ public int getNumberOfCpus() {
+ return cpuNumber;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.linuxtools.lttng.ui.state.model.ILttngStateInputRef#
+ * getTraceTimeWindow()
+ */
+ // @Override
+ public TmfTimeRange getTraceTimeWindow() {
+ if (log != null) {
+ return log.getTimeRange();
+
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef#getTraceId()
+ */
+ public String getTraceId() {
+ if (log != null) {
+ return log.getName();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef#
+ * getExperimentTimeWindow()
+ */
+ public TmfTimeRange getExperimentTimeWindow() {
+ // TODO Using the Trace time window temporarily, we need to replace with
+ // the Experiment level
+ if (log != null) {
+ return log.getTimeRange();
+ }
+ return null;
+ }
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.state;
+
+import org.eclipse.linuxtools.tmf.signal.TmfSignal;
+
+public class RequestCompletedSignal extends TmfSignal {
+
+ StateDataRequest request;
+
+ public RequestCompletedSignal(StateDataRequest request) {
+ super(request);
+ this.request = request;
+ }
+
+ public StateDataRequest getRequest() {
+ return request;
+ }
+
+}
--- /dev/null
+package org.eclipse.linuxtools.lttng.state;
+
+import org.eclipse.linuxtools.tmf.signal.TmfSignal;
+
+public class RequestStartedSignal extends TmfSignal {
+
+ StateDataRequest request;
+
+ public RequestStartedSignal(StateDataRequest request) {
+ super(request);
+ this.request = request;
+ }
+
+ public StateDataRequest getRequest() {
+ return request;
+ }
+
+}
*******************************************************************************/
package org.eclipse.linuxtools.lttng.state;
+import java.util.Vector;
+
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalManager;
+import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
/**
* This class is an extension of Data Request which includes specific references
* @author alvaro
*
*/
-public class StateDataRequest {
- // //
+public class StateDataRequest extends TmfDataRequest<TmfEvent> {
// ========================================================================
- // // Data
- // //
+ // Data
// =======================================================================
- // private Vector<IStateDataRequestListener> listeners = new
- // Vector<IStateDataRequestListener>();
- // private String transactionId = ""; /* optional user's attribute */
- // private StateManager manager = null;
- // private long numOfEvents = 0;
- // private boolean broadcast = false;
- // private boolean clearDataInd = false;
- // //
+ private Vector<IStateDataRequestListener> listeners = new Vector<IStateDataRequestListener>();
+ private String transactionId = ""; /* optional user's attribute */
+ private StateManager manager = null;
+ private long numOfEvents = 0;
+ private boolean broadcast = false;
+ private boolean clearDataInd = false;
// ========================================================================
- // // Constructors
- // //
+ // Constructors
// =======================================================================
- // /**
- // * @param range
- // * @param offset
- // * @param nbEvents
- // * @param maxBlockSize
- // * @param listener
- // */
- // public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
- // int maxBlockSize, IStateDataRequestListener listener,
- // StateManager manager) {
- //
- // super(range, nbEvents, maxBlockSize);
- // //super(0, nbEvents, maxBlockSize);
- // this.manager = manager;
- // if (listener != null && !listeners.contains(listener)) {
- // listeners.add(listener);
- // }
- // }
- //
- // /**
- // * @param range
- // * @param offset
- // * @param nbEvents
- // * @param maxBlockSize
- // * @param listener
- // * @param transactionID
- // * optional use by user application
- // */
- // public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
- // int maxBlockSize, IStateDataRequestListener listener,
- // String transactionID, StateManager manager) {
- //
- // this(range, offset, nbEvents, maxBlockSize, listener, manager);
- // this.transactionId = transactionID;
- // }
- //
- // //
+ /**
+ * @param range
+ * @param offset
+ * @param nbEvents
+ * @param maxBlockSize
+ * @param listener
+ */
+ public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
+ int maxBlockSize, IStateDataRequestListener listener,
+ StateManager manager) {
+
+ super(range, nbEvents, maxBlockSize);
+ //super(0, nbEvents, maxBlockSize);
+ this.manager = manager;
+ if (listener != null && !listeners.contains(listener)) {
+ listeners.add(listener);
+ }
+ }
+
+ /**
+ * @param range
+ * @param offset
+ * @param nbEvents
+ * @param maxBlockSize
+ * @param listener
+ * @param transactionID
+ * optional use by user application
+ */
+ public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
+ int maxBlockSize, IStateDataRequestListener listener,
+ String transactionID, StateManager manager) {
+
+ this(range, offset, nbEvents, maxBlockSize, listener, manager);
+ this.transactionId = transactionID;
+ }
+
// ========================================================================
- // // Methods
- // //
+ // Methods
// =======================================================================
- //
- // /**
- // * Trigger the start to process this request right after the notification
- // to
- // * the interested listeners
- // *
- // * @param experiment
- // * @param broadcast
- // * true: All views, false: only to registered listeners
- // */
- // public void startRequestInd(TmfExperiment experiment, boolean broadcast,
- // boolean waitForCompletion) {
- // if (broadcast) {
- // // Notify all state views.
- // this.broadcast = broadcast;
- // // TmfSignalManager.dispatchSignal(new RequestStartedSignal(this));
- // }
- // // else {
- // // // Notify specific state views
- // // for (IStateDataRequestListener listener : listeners) {
- // // listener.processingStarted(new RequestStartedSignal(this));
- // // }
- // // }
- //
- // // trigger the start to process this request
- // experiment.processRequest(this, waitForCompletion);
- // }
- //
- // /**
- // * to be called by the handleCompletion in superclass method, notifies the
- // * interested listeners. i.e. if the request start indicated broadcast,
- // the
- // * completion will also be broadcasted otherwise only registered listeners
- // * will be notified.
- // */
- // public void notifyCompletion() {
- // if (broadcast) {
- // // Notify all state views.
- // TraceDebug.debug("request completed" + this.toString());
- // TmfSignalManager.dispatchSignal(new RequestCompletedSignal(this));
- // } else {
- // // Notify specific state views
- // for (IStateDataRequestListener listener : listeners) {
- // listener.processingCompleted(new RequestCompletedSignal(this));
- // }
- // }
- // }
- //
- // public void notifyStarting() {
- // if (broadcast) {
- // // Notify all state views.
- // TraceDebug.debug("request started" + this.toString());
- // TmfSignalManager.dispatchSignal(new RequestStartedSignal(this));
- // } else {
- // for (IStateDataRequestListener listener : listeners) {
- // listener.processingStarted(new RequestStartedSignal(this));
- // }
- // }
- // }
- //
- // public String getTransactionId() {
- // return transactionId;
- // }
- //
- // public StateManager getStateManager() {
- // return this.manager;
- // }
- //
- // // public IStateDataRequestListener getListener() {
- // // return listener;
- // // }
- //
- // public void addListener(IStateDataRequestListener listener) {
- // if (!listeners.contains(listener)) {
- // listeners.add(listener);
- // }
- // }
- //
- // public void removeListener(IStateDataRequestListener listener) {
- // if (listener != null) {
- // listeners.remove(listener);
- // }
- // }
- //
- // /**
- // * @param numOfEvents
- // * the numOfEvents to set
- // */
- // public void setNumOfEvents(long numOfEvents) {
- // this.numOfEvents = numOfEvents;
- // }
- //
- // /**
- // * @return the numOfEvents
- // */
- // public long getNumOfEvents() {
- // return numOfEvents;
- // }
- //
- // /**
- // * @param clearAllData
- // * indicates the need to clear all previous data e.g. a new
- // * experiment selection
- // */
- // public void setclearDataInd(boolean clearAllData) {
- // this.clearDataInd = clearAllData;
- // }
- //
- // /**
- // * Returns indication - clearing of all existing data model is required
- // e.g
- // * from the selection of a new experiment
- // *
- // * @return
- // */
- // public boolean isclearDataInd() {
- // return clearDataInd;
- // }
- //
- // /**
- // * Compare the time range with a Data Request.
- // *
- // * @param trange
- // * @return
- // */
- // public boolean equalTime(StateDataRequest otherRequest) {
- // TmfTimeRange trange = otherRequest.getRange();
- // TmfTimeRange myTimeRange = getRange();
- // TmfTimestamp myStartTime = myTimeRange.getStartTime();
- // TmfTimestamp myEndTime = myTimeRange.getEndTime();
- //
- // if (myStartTime.equals(trange.getStartTime())) {
- // if (myEndTime.equals(trange.getEndTime())) {
- // return true;
- // }
- // }
- //
- // return false;
+
+ /**
+ * Trigger the start to process this request right after the notification to
+ * the interested listeners
+ *
+ * @param experiment
+ * @param broadcast
+ * true: All views, false: only to registered listeners
+ */
+ public void startRequestInd(TmfExperiment experiment, boolean broadcast,
+ boolean waitForCompletion) {
+ if (broadcast) {
+ // Notify all state views.
+ this.broadcast = broadcast;
+ TmfSignalManager.dispatchSignal(new RequestStartedSignal(this));
+ } else {
+ // Notify specific state views
+ for (IStateDataRequestListener listener : listeners) {
+ listener.processingStarted(new RequestStartedSignal(this));
+ }
+ }
+
+ // trigger the start to process this request
+ experiment.processRequest(this, waitForCompletion);
+ }
+
+ /**
+ * to be called by the handleCompletion in superclass method, notifies the
+ * interested listeners. i.e. if the request start indicated broadcast, the
+ * completion will also be broadcasted otherwise only registered listeners
+ * will be notified.
+ */
+ public void notifyCompletion() {
+ if (broadcast) {
+ // Notify all state views.
+ TmfSignalManager.dispatchSignal(new RequestCompletedSignal(this));
+ } else {
+ // Notify specific state views
+ for (IStateDataRequestListener listener : listeners) {
+ listener.processingCompleted(new RequestCompletedSignal(this));
+ }
+ }
+ }
+
+ public void notifyStarting() {
+ for (IStateDataRequestListener listener : listeners) {
+ listener.processingStarted(new RequestStartedSignal(this));
+ }
+ }
+
+ public String getTransactionId() {
+ return transactionId;
+ }
+
+ public StateManager getStateManager() {
+ return this.manager;
+ }
+
+ // public IStateDataRequestListener getListener() {
+ // return listener;
// }
+
+ public void addListener(IStateDataRequestListener listener) {
+ if (!listeners.contains(listener)) {
+ listeners.add(listener);
+ }
+ }
+
+ public void removeListener(IStateDataRequestListener listener) {
+ if (listener != null) {
+ listeners.remove(listener);
+ }
+ }
+
+ /**
+ * @param numOfEvents
+ * the numOfEvents to set
+ */
+ public void setNumOfEvents(long numOfEvents) {
+ this.numOfEvents = numOfEvents;
+ }
+
+ /**
+ * @return the numOfEvents
+ */
+ public long getNumOfEvents() {
+ return numOfEvents;
+ }
+
+ /**
+ * @param clearAllData
+ * indicates the need to clear all previous data e.g. a new
+ * experiment selection
+ */
+ public void setclearDataInd(boolean clearAllData) {
+ this.clearDataInd = clearAllData;
+ }
+
+ /**
+ * Returns indication - clearing of all existing data model is required e.g
+ * from the selection of a new experiment
+ *
+ * @return
+ */
+ public boolean isclearDataInd() {
+ return clearDataInd;
+ }
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.state;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.TraceDebug;
+import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.EventProcessorProxy;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
+import org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.state.model.StateModelFactory;
+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.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceCheckpoint;
+
+/**
+ *
+ * @author alvaro
+ *
+ */
+public class StateManager extends Observable {
+
+ private static final long LTTNG_STATE_SAVE_INTERVAL = 5000000L;
+
+ // These are used in the building of the data request.
+ private static final long DEFAULT_OFFSET = 0L;
+ private static final int DEFAULT_CHUNK = 1;
+
+ // ========================================================================
+ // Data
+ // =======================================================================
+ private TmfExperiment fExperiment = null;
+ private TmfTrace fEventLog = null;
+ private StateStacksHandler stateIn = null;
+ private Long eventCount = 0L;
+
+ private HashMap<Long, LttngTraceState> stateCheckpointsList = new HashMap<Long, LttngTraceState>();
+ private Vector<TmfTraceCheckpoint> timestampCheckpointsList = new Vector<TmfTraceCheckpoint>();
+
+ // ========================================================================
+ // Constructor
+ // =======================================================================
+
+ // /**
+ // * Default constructor
+ // * <p>
+ // * Instanciate its own StateStacksHandler.
+ // *
+ // */
+ // public StateManager() {
+ // this.stateIn = new StateStacksHandler();
+ // }
+
+ /**
+ * Constructor with parameter
+ * <p>
+ *
+ * @param stateInputHandler
+ * A valid StateStacksHandler
+ *
+ */
+ public StateManager(StateStacksHandler stateInputHandler) {
+ this.stateIn = stateInputHandler;
+ }
+
+ // /**
+ // * Copy constructor
+ // * <p>
+ // *
+ // * @param oldStateManager
+ // * the StateManager we want to copy
+ // *
+ // */
+ // public StateManager(StateManager oldStateManager) {
+ // fEventLog = oldStateManager.fEventLog;
+ // stateIn = oldStateManager.stateIn;
+ // trace = oldStateManager.trace;
+ // eventCount = oldStateManager.eventCount;
+ //
+ // stateCheckpointsList = oldStateManager.stateCheckpointsList;
+ // timestampCheckpointsList = oldStateManager.timestampCheckpointsList;
+ // }
+
+ // ========================================================================
+ // Methods
+ // =======================================================================
+ /**
+ * A new Experiment or trace selected
+ * @param experiment
+ * @param clearPreviousData
+ */
+ public void setTraceSelection(TmfExperiment experiment,
+ boolean clearPreviousData) {
+ // New log in use, read all events and build state transition stack
+ if (experiment != null) {
+ if (fExperiment != null && fExperiment != experiment) {
+ this.fExperiment.dispose();
+ }
+
+ this.fExperiment = experiment;
+
+ // if (fEventLog != null) {
+ // this.fEventLog.dispose();
+ // }
+
+ this.fEventLog = (TmfTrace)experiment.getTraces()[0];
+ try {
+ stateIn.init(fEventLog);
+ } catch (LttngStateException e) {
+ e.printStackTrace();
+ }
+
+ // Restart count and collections
+ eventCount = 0L;
+ stateCheckpointsList.clear();
+ timestampCheckpointsList.clear();
+
+ // Obtain a dataRequest to pass to the processRequest function
+ TmfTimeRange allTraceWindow = fEventLog.getTimeRange();
+ StateDataRequest request = getDataRequestStateSave(allTraceWindow,
+ null);
+ request.setclearDataInd(clearPreviousData);
+
+ // Wait for completion
+ request.startRequestInd(fExperiment, true, true);
+
+ if (TraceDebug.isDEBUG()) {
+ StringBuilder sb = new StringBuilder(
+ "Total number of processes in the State provider: "
+ + stateIn.getTraceStateModel().getProcesses().length);
+
+ TmfTimeRange logTimes = fEventLog.getTimeRange();
+ sb.append("\n\tLog file times "
+ + new LttngTimestamp(logTimes.getStartTime()));
+ sb.append(" - " + new LttngTimestamp(logTimes.getEndTime()));
+
+ sb.append("\n\tCheckPoints available at: ");
+ for (TmfTraceCheckpoint cpoint : timestampCheckpointsList) {
+ sb.append("\n\t" + cpoint.getTimestamp());
+ }
+ TraceDebug.debug(sb.toString());
+ }
+ }
+
+ }
+
+ /**
+ * TODO: Not ready for threading
+ * <p>
+ * Read events within specific time window
+ * </p>
+ *
+ * @param trange
+ * @param obs
+ * @param transactionID
+ */
+ public void executeDataRequest(TmfTimeRange trange, String transactionID,
+ IStateDataRequestListener listener) {
+ TmfTimestamp restoredStartTime = restoreCheckPointByTimestamp(trange
+ .getStartTime());
+ // Adjust the time range to consider rewinding to the start time
+ trange = new TmfTimeRange(restoredStartTime, trange.getEndTime());
+ // Get a data request for the time range we want (nearest checkpoint
+ // to timestamp wanted)
+ eventCount = 0L;
+
+ // Process request to that point
+ StateDataRequest request = getDataRequestByTimeRange(trange, listener);
+ // don't wait for completion i.e. allow cancellations
+ request.startRequestInd(fExperiment, false, false);
+
+ if (TraceDebug.isDEBUG()) {
+ TraceDebug
+ .debug(" Time Window requested, (start adjusted to checkpoint): "
+ + trange.getStartTime()
+ + "-" + trange.getEndTime()
+ + " Total number of processes in the State provider: "
+ + stateIn.getTraceStateModel().getProcesses().length + " Completed");
+ }
+ }
+
+ /**
+ * Current value of event counter
+ *
+ * @return Long The number of events, if it is known
+ */
+ public Long getEventCount() {
+ return eventCount;
+ }
+
+ /**
+ * used to obtain details on the log associated with this manager e.g.
+ * logid.
+ *
+ * @return
+ */
+ public TmfTrace getEventLog() {
+ return fEventLog;
+ }
+
+ /**
+ * Used for troubleshooting when debug mode is on
+ *
+ * @return Set<String> Set of event that were not handled
+ */
+ public Set<String> getEventsNotHandled() {
+ return stateIn.getEventsNotHandled();
+ }
+
+ /**
+ * Needed for verification purposes
+ *
+ * @param listener
+ * The IEventProcessing we want to register
+ */
+ void registerListener(IEventProcessing listener) {
+ stateIn.registerListener(listener);
+ }
+
+ /**
+ * Needed for verification purposes
+ *
+ * @param listener
+ * The IEventProcessing we want to unregister
+ */
+ void deregisterListener(IEventProcessing listener) {
+ stateIn.deregisterListener(listener);
+ }
+
+ /**
+ * Save a checkpoint if it is needed at that point
+ * <p>
+ * The function will use "eventCount" internally to determine if a save was
+ * needed
+ *
+ * @param eventCounter
+ * The event "count" or event "id" so far
+ * @param eventTime
+ * The timestamp of this event
+ *
+ * @return boolean True if a checkpoint was saved, false otherwise
+ */
+ private boolean saveCheckPointIfNeeded(Long eventCounter,
+ TmfTimestamp eventTime) {
+ boolean saveHappened = false;
+ // Crate new location to store checkpoint reference
+ Long location = new Long(eventCounter.longValue());
+ // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
+ if ((location % LTTNG_STATE_SAVE_INTERVAL) == 0) {
+ // Save the checkpoint
+ stateCheckpointsList.put(location, stateIn.traceStateModel.clone());
+ // Save correlation between timestamp and checkpoint index
+
+ timestampCheckpointsList.add(new TmfTraceCheckpoint(eventTime,
+ location));
+
+ saveHappened = true;
+ }
+
+ return saveHappened;
+ }
+
+ /**
+ * Restore to the closest checkpoint from TmfTimestamp
+ * <p>
+ * Note : it is heavier to restore by timestamp than by event position,
+ * restore by event position whichever possible.
+ *
+ * @param eventTime
+ * The timestamp of the event to restore to
+ *
+ * @return TmfTimestamp indicates the nearest time used to restore the
+ * state, null sent if input is invalid
+ */
+ public TmfTimestamp restoreCheckPointByTimestamp(TmfTimestamp eventTime) {
+ TmfTimeRange logRange = fExperiment.getTimeRange();
+ TmfTimestamp nearestTimeStamp = logRange.getStartTime();
+
+ // The GUI can have time limits higher than this log, since GUI can
+ // handle multiple logs
+ if ((eventTime.getValue() < 0)
+ || (eventTime.getValue() > logRange.getEndTime().getValue())) {
+ return null;
+ }
+
+ // The GUI can have time limits lower than this log, since GUI can
+ // handle multiple logs
+ if ((eventTime.getValue() < logRange.getStartTime().getValue())) {
+ eventTime = logRange.getStartTime();
+ }
+
+ // Sort the checkpoints, required before the binary search
+ Collections.sort(timestampCheckpointsList);
+ // Initiate the compare with a checkpoint containing the target time
+ // stamp to find
+ int index = Collections.binarySearch(timestampCheckpointsList,
+ new TmfTraceCheckpoint(eventTime, 0));
+ // adjust index to round down to earlier checkpoint when exact match not
+ // found
+ index = getPrevIndex(index);
+
+ LttngTraceState traceState;
+ Long location = 0L;
+ if (index == 0) {
+ // No checkpoint restore is needed, start with a brand new
+ // TraceState
+ ILttngStateInputRef inputDataRef = new LttngStateInputRef(fEventLog);
+ traceState = StateModelFactory.getStateEntryInstance(inputDataRef);
+ } else {
+ // Useful CheckPoint found
+ TmfTraceCheckpoint checkpoint = timestampCheckpointsList.get(index);
+ nearestTimeStamp = checkpoint.getTimestamp();
+ // get the location associated with the checkpoint
+ location = (Long) (checkpoint.getLocation());
+ // reference a new copy of the checkpoint template
+ traceState = stateCheckpointsList.get(location).clone();
+ }
+
+ // Make sure eventCount stay consistent!
+ eventCount = new Long(location);
+
+ // Restore the stored traceState
+ stateIn.setTraceStateModel(traceState);
+
+ return nearestTimeStamp;
+ }
+
+ /**
+ * Adjust the result from a binary search to the round down position
+ *
+ * @param position
+ * if Negative is: (-(insertion point) -1)
+ * @return position or if no match found, earlier than insertion point
+ */
+ private int getPrevIndex(int position) {
+ int roundDownPosition = position;
+ if (position < 0) {
+ roundDownPosition = -(position + 2);
+ }
+
+ roundDownPosition = roundDownPosition < 0 ? 0 : roundDownPosition;
+ return roundDownPosition;
+ }
+
+ // /**
+ // * Restore to the closest checkpoint from position
+ // * <p>
+ // *
+ // * @param position
+ // * The position of the event to restore to
+ // *
+ // * @return boolean True if a checkpoint was restored, false otherwise
+ // */
+ // private boolean restoreCheckPointByPosition(long position) {
+ // long nearestCheckPoint = (position - (position %
+ // LTTNG_STATE_SAVE_INTERVAL));
+ //
+ // // Some sanity check :
+ // // Not under 0
+ // // Not over eventCount
+ // // A checkpoint exist
+ // if ((nearestCheckPoint < 0) || (nearestCheckPoint > eventCount)
+ // || (stateCheckpointsList.get(nearestCheckPoint) == null)) {
+ // return false;
+ // } else {
+ // // Restore the stored traceState
+ // stateIn.setTraceStateModel(stateCheckpointsList
+ // .get(nearestCheckPoint));
+ //
+ // // Make sure eventCount stay consistent!
+ // eventCount = new Long(nearestCheckPoint);
+ //
+ // // * Rewind to the correct position
+ // // To do so, we need a request to the correct window
+ // // We will seek to nearestCheckPoint and read next events until
+ // // position
+ // TmfDataRequest<TmfEvent> request = getDataRequestByPosition(
+ // (int) nearestCheckPoint, (int) position);
+ //
+ // // Process request to that point
+ // fExperiment.processRequest(request, true);
+ //
+ // return true;
+ // }
+ // }
+
+ /**
+ * Get a Tmf data request for the current eventlog
+ * <p>
+ *
+ * @param TmfTimeRange
+ * The time range we want events from.
+ *
+ * @return TmfDataRequest<TmfEvent> The request made
+ */
+ StateDataRequest getDataRequestByTimeRange(TmfTimeRange timeWindow,
+ IStateDataRequestListener listener) {
+
+ final TmfEvent[] evt = new TmfEvent[1];
+
+ // ***TODO***
+ // The override of handlePartialResult is similar to the one in
+ // getDataRequestByPosition()
+ // ***
+
+ // Create the new request and override the handlePartialResult function
+ StateDataRequest request = new StateDataRequest(timeWindow,
+ DEFAULT_OFFSET, TmfDataRequest.ALL_EVENTS, DEFAULT_CHUNK,
+ listener, this) {
+ @Override
+ public void handleData() {
+ TmfEvent[] result = getData();
+
+ evt[0] = (result.length > 0) ? result[0] : null;
+ // Dispatch information for Event processing
+ stateIn.processEvent(evt[0]);
+
+ // increment internal and external number of events
+ setNumOfEvents(getNumOfEvents() + 1);
+ eventCount++;
+ }
+
+ @Override
+ public void handleCompleted() {
+ if (isCancelled() || isFailed()) {
+ // No notification to end request handlers
+ } else {
+ // notify the associated end request handlers
+ requestCompleted();
+ }
+
+ // notify listeners
+ notifyCompletion();
+ }
+ };
+
+ return request;
+ }
+
+ private StateDataRequest getDataRequestStateSave(TmfTimeRange timeWindow,
+ IStateDataRequestListener requestListener) {
+
+ final TmfEvent[] evt = new TmfEvent[1];
+
+ // ***TODO***
+ // The override of handlePartialResult is similar to the one in
+ // getDataRequestByPosition()
+ // ***
+
+ // Create the new request and override the handlePartialResult function
+ StateDataRequest request = new StateDataRequest(timeWindow,
+ DEFAULT_OFFSET, TmfDataRequest.ALL_EVENTS, DEFAULT_CHUNK,
+ requestListener, this) {
+
+ @Override
+ public void handleData() {
+ TmfEvent[] result = getData();
+
+ evt[0] = (result.length > 0) ? result[0] : null;
+ // Dispatch information for Event processing
+ stateIn.processEvent(evt[0]);
+
+ // Call the function that will save a checkpoint if needed at
+ // that point
+ // Note : We call this function before incrementing eventCount
+ // to avoid skipping the "0th" event
+ if (evt[0] != null) {
+ saveCheckPointIfNeeded(getNumOfEvents(), evt[0]
+ .getTimestamp());
+ }
+
+ // increment internal and external counters
+ setNumOfEvents(getNumOfEvents() + 1);
+ eventCount++;
+ }
+
+ @Override
+ public void handleCompleted() {
+ if (isCancelled() || isFailed()) {
+ // No notification to end request handlers
+ } else {
+ // notify the associated end request handlers
+ requestCompleted();
+ }
+
+ // notify listeners
+ notifyCompletion();
+ TraceDebug.debug("number of events processed on file opening"
+ + getNumOfEvents());
+ }
+ };
+
+ return request;
+ }
+
+ // /**
+ // * Get a Tmf data request for the current eventlog
+ // * <p>
+ // *
+ // * @param startPosition
+ // * The position to start the get request from
+ // * @param endPosition
+ // * The position to ed the get request at
+ // *
+ // * @return TmfDataRequest<TmfEvent> The request made
+ // */
+ // private TmfDataRequest<TmfEvent> getDataRequestByPosition(
+ // long startPosition, long endPosition) {
+ // final TmfEvent[] evt = new TmfEvent[1];
+ //
+ // // ***FIXME***
+ // // The override of handlePartialResult is exactly the same as the one in
+ // // getDataRequestByPosition()
+ // // However, there is no way to override it in only one place to avoid
+ // // code duplication!
+ // // ***
+ //
+ // // Create the new request and override the handlePartialResult function
+ // TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(
+ // (int) startPosition, DEFAULT_OFFSET,
+ // (int) (endPosition - startPosition), DEFAULT_CHUNK) {
+ // //@Override
+ // public void handlePartialResult() {
+ // TmfEvent[] result = getData();
+ //
+ // evt[0] = (result.length > 0) ? result[0] : null;
+ // // Dispatch information for Event processing
+ // stateIn.processEvent(evt[0]);
+ // }
+ // };
+ //
+ // return request;
+ // }
+
+ /**
+ * @return
+ */
+ public TmfTimeRange getExperimentTimeWindow() {
+ if (fExperiment != null) {
+ return fExperiment.getTimeRange();
+ }
+ return null;
+ }
+
+ /**
+ * This method has to be called once all events of the associated Trace have
+ * been processed, this method then triggers the drawing of the final state
+ * which is necessary e.g when zooming.
+ */
+ public synchronized void requestCompleted() {
+ Set<AbsEventProcessorFactory> handlerRegister = EventProcessorProxy
+ .getInstance().getProcessingFactories();
+ // Notify the FINISH handlers
+ for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+ .iterator(); iterator.hasNext();) {
+ AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+ .next();
+ IEventProcessing handler = handlerRegistry.getfinishProcessor();
+ if (handler != null) {
+ // process State Update
+ handler.process(null, stateIn.traceStateModel);
+ }
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.TraceDebug;
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.EventProcessorProxy;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
+import org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+
+/**
+ * @author Alvaro
+ *
+ */
+public class StateStacksHandler {
+ // ========================================================================
+ // Table data
+ // =======================================================================
+ protected LttngTraceState traceStateModel = null;
+ protected Set<String> eventsNotHandled = null;
+ protected Vector<IEventProcessing> listeners = new Vector<IEventProcessing>();
+
+ // ========================================================================
+ // Constructors
+ // ========================================================================
+ public StateStacksHandler(LttngTraceState model) {
+ // It's assumed to have one instance of this class per Trace
+ this.traceStateModel = model;
+ }
+
+ // ========================================================================
+ // Methods
+ // =======================================================================
+ /**
+ * Initialised by manager, any time a JniTrace selection is updated
+ *
+ * @param trace
+ * @param log
+ *
+ */
+ void init(TmfTrace log) throws LttngStateException {
+ if (log == null) {
+ throw new LttngStateException("No TmfTrace object available!");
+ }
+
+ // this.trace = trace;
+ ILttngStateInputRef ref = new LttngStateInputRef(log);
+ this.traceStateModel.init(ref);
+ }
+
+
+ protected void processEvent(TmfEvent tmfEvent) /* throws LttngStateException */{
+ if (tmfEvent == null) {
+ return;
+ }
+
+ if (!(tmfEvent instanceof LttngEvent)) {
+ TraceDebug
+ .debug("The event received is not an instance of LttngEvent and can not be processed");
+ }
+
+ LttngEvent trcEvent = (LttngEvent) tmfEvent;
+// LttngEventField[] fields = ((LttngEventContent)trcEvent.getContent()).getFields();
+
+ if (trcEvent != null) {
+ String inEventName = trcEvent.getMarkerName();
+ // String inChannel = trcEvent.getChannelName();
+ // TraceDebug.debug("Event: " + inEventName);
+
+ // Check if the received event is a transition state event
+ // TODO: Remove temporarily to allow other events to go to the
+ // statistics view.
+ // Needs restructuring.
+ // Events eventStruct = StateStrings.getInstance()
+ // .getStateTransEventMap().get(inEventName);
+ // if (eventStruct != null) {
+ // String expectedChannel = eventStruct.getParent().getInName();
+ // check that received channel is the expected channel in the
+ // structure
+ // if (inChannel.equals(expectedChannel)) {
+ // Notify the before Handlers
+ Set<AbsEventProcessorFactory> handlerRegister = EventProcessorProxy
+ .getInstance().getProcessingFactories();
+
+ // Notify the state BEFORE update handlers
+ for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+ .iterator(); iterator.hasNext();) {
+ AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+ .next();
+ IEventProcessing handler = handlerRegistry
+ .getBeforeProcessor(inEventName);
+ if (handler != null) {
+ // process State Update
+ handler.process(trcEvent, traceStateModel);
+ }
+
+ }
+
+ // Notify the STATE UPDATE handlers
+ // Only one state update expected
+ for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+ .iterator(); iterator.hasNext();) {
+ AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+ .next();
+ IEventProcessing handler = handlerRegistry
+ .getStateUpdaterProcessor(inEventName);
+ if (handler != null) {
+ // process State Update
+ handler.process(trcEvent, traceStateModel);
+ }
+
+ }
+
+ // Notify the AFTER update handlers
+ for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+ .iterator(); iterator.hasNext();) {
+ AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+ .next();
+ IEventProcessing handler = handlerRegistry
+ .getAfterProcessor(inEventName);
+ if (handler != null) {
+ // process State Update
+ handler.process(trcEvent, traceStateModel);
+ }
+ }
+
+ // } else {
+ // StringBuilder sb = new StringBuilder(
+ // "Unexpected channel received for: " + inEventName
+ // + ", channel rec: " + inChannel
+ // + " chanel expected: " + expectedChannel);
+ // TraceDebug.debug(sb.toString());
+ // }
+ // }
+ }
+ }
+
+ /**
+ * Used for troubleshooting when debug mode is on
+ *
+ * @return
+ */
+ Set<String> getEventsNotHandled() {
+ return eventsNotHandled;
+ }
+
+ /**
+ * Needed for checkpoint
+ *
+ * @param LttngTraceState
+ */
+ public LttngTraceState getTraceStateModel() {
+ return traceStateModel;
+ }
+
+ /**
+ * Needed for checkpoint
+ *
+ * @param LttngTraceState
+ */
+ public void setTraceStateModel(LttngTraceState newTraceState) {
+ traceStateModel = newTraceState;
+ }
+
+ /**
+ * Needed for verification purposes
+ *
+ * @param listener
+ */
+ void registerListener(IEventProcessing listener) {
+ this.listeners.add(listener);
+ }
+
+ /**
+ * Needed for verification purposes
+ *
+ * @param listener
+ */
+ void deregisterListener(IEventProcessing listener) {
+ this.listeners.remove(listener);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.state.evProcessor;
+
+/**
+ * @author alvaro
+ *
+ */
+public abstract class AbsEventProcessorFactory {
+ /**
+ *
+ * @return The Event Handler for received event before the State data model
+ * is updated.
+ */
+ public abstract IEventProcessing getBeforeProcessor(String eventType);
+
+ /**
+ *
+ * @return The Event Handler for received event after the State data model
+ * is updated.
+ */
+ public abstract IEventProcessing getAfterProcessor(String eventType);
+
+ /**
+ *
+ * @return The Event Handler after the complete read request is completed,
+ * needed e.g. to draw the last state
+ */
+ public abstract IEventProcessing getfinishProcessor();
+
+ /**
+ *
+ * @return The Event Handler for received event in charge to update the
+ * state. Only one handler is expected so other factories must not
+ * override this method.
+ */
+ public IEventProcessing getStateUpdaterProcessor(String eventType) {
+ return null;
+ }
+
+}
import java.util.Set;
import org.eclipse.linuxtools.lttng.TraceDebug;
-import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateUpdateFactory;
/**
* @author alvaro
// Data
// =======================================================================
private static EventProcessorProxy instance = null;
- private final Set<AbsEventToHandlerResolver> processingFactories = new HashSet<AbsEventToHandlerResolver>();
+ private final Set<AbsEventProcessorFactory> processingFactories = new HashSet<AbsEventProcessorFactory>();
// ========================================================================
// =======================================================================
public EventProcessorProxy() {
// Manual creation of State update factory
- addEventProcessorFactory(StateEventToHandlerFactory.getInstance());
+ addEventProcessorFactory(StateUpdateFactory.getInstance());
}
// ========================================================================
/**
* @return the processingFactories
*/
- public Set<AbsEventToHandlerResolver> getProcessingFactories() {
+ public Set<AbsEventProcessorFactory> getProcessingFactories() {
return processingFactories;
}
* @param handlersFactory
*/
public void addEventProcessorFactory(
- AbsEventToHandlerResolver handlersFactory) {
+ AbsEventProcessorFactory handlersFactory) {
if (handlersFactory != null) {
//only add the listener if not already included
if (!processingFactories.contains(handlersFactory)) {
* @param handlersFactory
*/
public void removeEventProcessorFactory(
- IEventToHandlerResolver handlersFactory) {
+ AbsEventProcessorFactory handlersFactory) {
if (handlersFactory != null) {
processingFactories.remove(handlersFactory);
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+
+/**
+ * @author alvaro
+ *
+ */
+public interface IEventProcessing {
+
+ // ========================================================================
+ // Abstract methods
+ // =======================================================================
+ public abstract boolean process(LttngEvent trcEvent, LttngTraceState traceSt);
+ public abstract StateStrings.Events getEventHandleType();
+}
import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;
import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
-import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState;
import org.eclipse.linuxtools.lttng.state.model.LttngBdevState;
import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState;
import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
public abstract class AbsStateUpdate extends AbsStateProcessing implements
- ILttngEventProcessor {
+ IEventProcessing {
// ========================================================================
// Data
exe_state.setEntry_Time(eventTime.getValue());
exe_state.setChange_Time(eventTime.getValue());
exe_state.setCum_cpu_time(0L);
-// if (process != null)
- exe_state.setProc_status(process.getState().getProc_status());
+ exe_state.setProc_status(process.getState().getProc_status());
process.pushToExecutionStack(exe_state);
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state.evProcessor.state;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
+
+/**
+ * Builds a Map from string event name to a processing handler object, the
+ * processors implement the same interface to facilitate transparent methods
+ * call,
+ *
+ * The map key STring is the entry point of the raw events, using a hash speeds
+ * up the resolution of the appropriate processor
+ *
+ * @author alvaro
+ *
+ */
+public class StateUpdateFactory extends AbsEventProcessorFactory {
+ // ========================================================================
+ // Data
+ // =======================================================================
+ private final Map<String, IEventProcessing> eventNametoProcessor = new HashMap<String, IEventProcessing>();
+ private static StateUpdateFactory instance = new StateUpdateFactory();
+ private StateUpdateHandlers instantiateHandler = new StateUpdateHandlers();
+
+ // ========================================================================
+ // Constructors
+ // =======================================================================
+ private StateUpdateFactory() {
+ //create one instance of each individual event handler and add the instance to the map
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_ENTRY
+ .getInName(), instantiateHandler.getSyscallEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_EXIT
+ .getInName(), instantiateHandler.getsySyscallExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_ENTRY
+ .getInName(), instantiateHandler.getTrapEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_EXIT
+ .getInName(), instantiateHandler.getTrapExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_ENTRY
+ .getInName(), instantiateHandler.getTrapEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_EXIT
+ .getInName(), instantiateHandler.getTrapExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY
+ .getInName(), instantiateHandler.getTrapEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+ .getInName(), instantiateHandler.getTrapExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_ENTRY
+ .getInName(), instantiateHandler.getIrqEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_EXIT
+ .getInName(), instantiateHandler.getIrqExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_RAISE
+ .getInName(), instantiateHandler.getSoftIrqRaiseHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_ENTRY
+ .getInName(), instantiateHandler.getSoftIrqEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_EXIT
+ .getInName(), instantiateHandler.getSoftIrqExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_LIST_INTERRUPT
+ .getInName(), instantiateHandler.getEnumInterruptHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_REQUEST_ISSUE
+ .getInName(), instantiateHandler.getBdevRequestIssueHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_REQUEST_COMPLETE
+ .getInName(), instantiateHandler.getBdevRequestCompleteHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_ENTRY
+ .getInName(), instantiateHandler.getFunctionEntryHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_EXIT
+ .getInName(), instantiateHandler.getFunctionExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SYS_CALL_TABLE
+ .getInName(), instantiateHandler.getDumpSyscallHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_KPROBE_TABLE
+ .getInName(), instantiateHandler.getDumpKprobeHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFTIRQ_VEC
+ .getInName(), instantiateHandler.getDumpSoftIrqHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE
+ .getInName(), instantiateHandler.getSchedChangeHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_FORK
+ .getInName(), instantiateHandler.getProcessForkHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_KTHREAD_CREATE
+ .getInName(), instantiateHandler.getProcessKernelThreadHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_EXIT
+ .getInName(), instantiateHandler.getProcessExitHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_FREE
+ .getInName(), instantiateHandler.getProcessFreeHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_EXEC
+ .getInName(), instantiateHandler.getProcessExecHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_THREAD_BRAND
+ .getInName(), instantiateHandler.GetThreadBrandHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_STATEDUMP_END
+ .getInName(), instantiateHandler.getStateDumpEndHandler());
+
+ eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_STATE
+ .getInName(), instantiateHandler.getEnumProcessStateHandler());
+
+
+ }
+
+ // ========================================================================
+ // Public methods
+ // =======================================================================
+ /**
+ * The event processors are common to all traces an multiple instances will
+ * use more memory unnecessarily
+ *
+ * @return
+ */
+ public static AbsEventProcessorFactory getInstance() {
+ if (instance == null) {
+ instance = new StateUpdateFactory();
+ }
+ return instance;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory#getAfterProcessor(java.lang.String)
+ */
+ @Override
+ public IEventProcessing getAfterProcessor(String eventType) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory#getBeforeProcessor(java.lang.String)
+ */
+ @Override
+ public IEventProcessing getBeforeProcessor(String eventType) {
+ return null;
+ }
+
+ /**
+ * This is the only event handler to update the State provider
+ * @return
+ *
+ */
+ @Override
+ public IEventProcessing getStateUpdaterProcessor(String eventType) {
+ return eventNametoProcessor.get(eventType);
+ }
+
+ @Override
+ public IEventProcessing getfinishProcessor() {
+ // No finishing processor used
+ return null;
+ }
+}
import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessType;
-import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState;
import org.eclipse.linuxtools.lttng.state.model.LttngBdevState;
import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState;
*/
class StateUpdateHandlers {
- final ILttngEventProcessor getSyscallEntryHandler() {
+ final IEventProcessing getSyscallEntryHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SYSCALL_ENTRY;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
submode, trcEvent.getTimestamp(), traceSt);
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
- final ILttngEventProcessor getsySyscallExitHandler() {
+ final IEventProcessing getsySyscallExitHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SYSCALL_EXIT;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getTrapEntryHandler() {
+ final IEventProcessing getTrapEntryHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_TRAP_ENTRY;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
Long cpu = trcEvent.getCpuId();
LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
cpu_push_mode(cpust, StateStrings.CpuMode.LTTV_CPU_TRAP);
cpust.pushToTrapStack(trap); /* update trap status */
-
+
// update Trap State
- LttngTrapState trap_state = null;
- trap_state = traceSt.getTrap_states().get(trap);
-
- // If the trape_state exists, just increment it's counter,
- // otherwise, create it
- if ( trap_state == null ) {
- trap_state = new LttngTrapState();
- trap_state.incrementRunning();
- traceSt.getTrap_states().put(trap, trap_state);
- }
- else {
- trap_state.incrementRunning();
- }
-
+ LttngTrapState trap_state = traceSt.getTrap_states().get(trap);
+ trap_state.incrementRunning();
+
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getTrapExitHandler() {
+ final IEventProcessing getTrapExitHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_TRAP_EXIT;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getIrqEntryHandler() {
+ final IEventProcessing getIrqEntryHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_IRQ_ENTRY;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
Long irq = getAFieldLong(trcEvent, traceSt,
Fields.LTT_FIELD_IRQ_ID);
- if (irq == null || traceSt.getIrq_states().get(irq) == null) {
- if (irq != null) {
- System.out.println("Invalid irq (" + irq + "), ts = " + trcEvent.getOriginalTimestamp());
- }
+ if (irq == null) {
return true;
}
return false;
}
+
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getSoftIrqExitHandler() {
+ final IEventProcessing getSoftIrqExitHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SOFT_IRQ_EXIT;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
if (softirq != -1) {
LttngSoftIRQState softIrqstate = traceSt
.getSoft_irq_states().get(softirq);
- if (softIrqstate != null) {
- softIrqstate.decrementRunning();
- }
+ softIrqstate.decrementRunning();
}
/* update cpu status */
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getIrqExitHandler() {
+ final IEventProcessing getIrqExitHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_IRQ_EXIT;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getSoftIrqRaiseHandler() {
+ final IEventProcessing getSoftIrqRaiseHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
private Events eventType = Events.LTT_EVENT_SOFT_IRQ_RAISE;
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getSoftIrqEntryHandler() {
+ final IEventProcessing getSoftIrqEntryHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SOFT_IRQ_ENTRY;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getEnumInterruptHandler() {
+ final IEventProcessing getEnumInterruptHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
private Events eventType = Events.LTT_EVENT_LIST_INTERRUPT;
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getBdevRequestIssueHandler() {
+ final IEventProcessing getBdevRequestIssueHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_REQUEST_ISSUE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getBdevRequestCompleteHandler() {
+ final IEventProcessing getBdevRequestCompleteHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_REQUEST_COMPLETE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getFunctionEntryHandler() {
+ final IEventProcessing getFunctionEntryHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_FUNCTION_ENTRY;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
Long cpu = trcEvent.getCpuId();
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getFunctionExitHandler() {
+ final IEventProcessing getFunctionExitHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_FUNCTION_EXIT;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getDumpSyscallHandler() {
+ final IEventProcessing getDumpSyscallHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SYS_CALL_TABLE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
// obtain the syscall id
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getDumpKprobeHandler() {
+ final IEventProcessing getDumpKprobeHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_KPROBE_TABLE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getDumpSoftIrqHandler() {
+ final IEventProcessing getDumpSoftIrqHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SOFTIRQ_VEC;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getSchedChangeHandler() {
+ final IEventProcessing getSchedChangeHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_SCHED_SCHEDULE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getProcessForkHandler() {
+ final IEventProcessing getProcessForkHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_PROCESS_FORK;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getProcessKernelThreadHandler() {
+ final IEventProcessing getProcessKernelThreadHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_KTHREAD_CREATE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
/*
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getProcessExitHandler() {
+ final IEventProcessing getProcessExitHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_PROCESS_EXIT;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getProcessFreeHandler() {
+ final IEventProcessing getProcessFreeHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_PROCESS_FREE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
// return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor getProcessExecHandler() {
+ final IEventProcessing getProcessExecHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_EXEC;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
*
* @return
*/
- final ILttngEventProcessor GetThreadBrandHandler() {
+ final IEventProcessing GetThreadBrandHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_THREAD_BRAND;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
/**
* @return
*/
- final ILttngEventProcessor getStateDumpEndHandler() {
+ final IEventProcessing getStateDumpEndHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_STATEDUMP_END;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
}
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
+
/**
* Private method used to establish the first execution state in the
* stack for a given process
*
* @return
*/
- final ILttngEventProcessor getEnumProcessStateHandler() {
+ final IEventProcessing getEnumProcessStateHandler() {
AbsStateUpdate handler = new AbsStateUpdate() {
+ private Events eventType = Events.LTT_EVENT_PROCESS_STATE;
+
// @Override
public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
return false;
}
+
+ // @Override
+ public Events getEventHandleType() {
+ return eventType;
+ }
};
return handler;
}
/*******************************************************************************
-+ * Copyright (c) 2009, 2010 Ericsson
+ * Copyright (c) 2009 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
import java.util.HashMap;
import java.util.Map;
-import org.eclipse.linuxtools.lttng.TraceDebug;
-import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory;
-import org.eclipse.linuxtools.lttng.control.LttngSyntheticEventProvider;
-import org.eclipse.linuxtools.lttng.event.LttngEvent;
-import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
-import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
-import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
-import org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener;
-import org.eclipse.linuxtools.lttng.signal.StateExperimentListener;
-import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager;
-import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.lttng.state.IStateDataRequestListener;
+import org.eclipse.linuxtools.lttng.state.StateManager;
+import org.eclipse.linuxtools.tmf.component.TmfComponent;
import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.request.ITmfEventRequest;
-import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
-import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
-import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal;
-import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.trace.TmfExperimentSelectedSignal;
/**
* @author alvaro
*
*/
-public class StateExperimentManager extends LTTngTreeNode implements
- ILttExperimentSelectedListener, IStateExperimentManager {
+public class StateExperimentManager extends TmfComponent {
// ========================================================================
// Data
// =======================================================================
- private LTTngTreeNode fSelectedExperiment = null; // one selected experiment
- // supported
- private final StateExperimentListener fexperimentListener;
- private boolean fwaitForCompletion = false;
- /**
- * Used to route incoming events to proper trace manager, during check point
- * building
- */
- private final Map<ITmfTrace, IStateTraceManager> ftraceToManagerMap = new HashMap<ITmfTrace, IStateTraceManager>();
- private LttngSyntheticEvent syntheticEvent = null;
- private ITmfEventRequest<LttngEvent> fStateCheckPointRequest = null;
-
+
+ private final Map<String, StateManager> managersByID = new HashMap<String, StateManager>();
+ private TmfExperiment fExperiment = null; // one experiment supported
// ========================================================================
// Constructors
// =======================================================================
- public StateExperimentManager(Long id, String name) {
- super(id, null, name, null);
- fexperimentListener = new StateExperimentListener("Experiment Manager",
- this);
- }
+ /**
+ * package level constructor, creation from factory
+ */
+ StateExperimentManager() {
+ super();
+ }
// ========================================================================
// Methods
// =======================================================================
-// /* (non-Javadoc)
-// * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperimentTimeWindow(org.eclipse.linuxtools.tmf.event.TmfTimeRange, java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
-// */
-// public ILttngSyntEventRequest readExperimentTimeWindow(TmfTimeRange trange,
-// Object source, IRequestStatusListener listener,
-// ITransEventProcessor processor) {
-//
-// ILttngSyntEventRequest request = null;
-//
-// // validate
-// if (fSelectedExperiment != null) {
-// // Get all trace manager nodes
-// LTTngTreeNode[] traceMgrs = fSelectedExperiment.getChildren();
-//
-// if (traceMgrs != null && traceMgrs.length > 0) {
-// IStateTraceManager traceManager;
-// // Trigger one request per trace
-// for (LTTngTreeNode traceNode : traceMgrs) {
-// traceManager = (IStateTraceManager) traceNode;
-// request = traceManager.executeDataRequest(trange, source,
-// listener,
-// processor);
-// }
-// }
-// } else {
-// if (fSelectedExperiment == null) {
-// TraceDebug.debug("No experiment selected");
-// }
-// }
-//
-// return request;
-// }
-
-// /* (non-Javadoc)
-// * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperiment(java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
-// */
-// @SuppressWarnings("unchecked")
-// public void readExperiment(Object source, IRequestStatusListener listener,
-// ITransEventProcessor processor) {
-// // validate
-// if (fSelectedExperiment != null) {
-// TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) fSelectedExperiment
-// .getValue();
-// TmfTimeRange trange = experiment.getTimeRange();
-// readExperimentTimeWindow(trange, source, listener, processor);
-// } else {
-// TraceDebug.debug("No selected experiment available");
-// }
-// }
-
-
-
- /*
- * (non-Javadoc)
+ /**
+ * Return the Map of unique id to Manager instance
*
- * @see
- * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
- * #experimentSelected_prep
- * (org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
+ * @return
*/
- public void experimentSelected_prep(TmfExperiment<LttngEvent> experiment) {
- LTTngTreeNode experimentNode = null;
- if (experiment != null) {
- experimentNode = getChildByName(experiment.getName());
- // keep experiment if already loaded with the same value
- if (experimentNode != null
- && experimentNode.getValue() != experiment) {
- // rebuild the experiment nodes from scratch
- removeChild(experimentNode);
- experimentNode = null;
- }
-
- // Make sure all traces involved have a corresponding state manager
- // and
- // state system to request its initial data
- if (experimentNode == null) {
- // Create the new experiment tree node
- experimentNode = new LTTngTreeNode(getNextUniqueId(), this,
- experiment.getName(), experiment);
- // add the new experiment to this children list
- addChild(experimentNode);
- }
-
- // Make sure the traces exists in the tree
- ITmfTrace[] rtraces = experiment.getTraces();
- String traceName;
- LTTngTreeNode traceStateManagerNode;
- // StateStacksHandler
- for (ITmfTrace rtrace : rtraces) {
- traceName = rtrace.getName();
- traceStateManagerNode = experimentNode.getChildByName(traceName);
- // Node does not exist for this experiment, so needs to be
- // created
- if (traceStateManagerNode == null) {
- traceStateManagerNode = StateManagerFactory.getManager(
- rtrace, experimentNode);
- experimentNode.addChild(traceStateManagerNode);
- }
- }
-
- // Reset event provider to handle requests for the new experiment
- LttngSyntheticEventProvider synEventProvider = LttngCoreProviderFactory
- .getEventProvider();
- synEventProvider.reset(experimentNode);
-
- // preserve the selected experiment
- fSelectedExperiment = experimentNode;
- }
+ public Map<String, StateManager> getManagersByID() {
+ return managersByID;
}
- /*
- * (non-Javadoc)
+ /**
+ * Read all available traces from the nearest checkpoint from start position
+ * to the end of a specified time range
*
- * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
- * experimentSelected(java.lang.Object,
- * org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
+ * @param trange
+ * @param obs
+ * @param transactionID
+ * @param display
*/
- public void experimentSelected(Object source,
- TmfExperiment<LttngEvent> experiment) {
- // validate
- if (experiment == null) {
- TraceDebug.debug("Received expriment is null");
- return;
+ public void readExperimentTimeWindow(TmfTimeRange trange,
+ String transactionID, IStateDataRequestListener listener) {
+ if (fExperiment != null) {
+ String id = fExperiment.getExperimentId();
+ StateManager manager = managersByID.get(id);
+ if (manager != null) {
+ // TODO: A loop to request data for each trace needs to be used
+ // here when multiple traces are supported.
+ manager.executeDataRequest(trange, transactionID, listener);
+ }
}
+ }
- // If previous request is ongoing, cancel it before requesting a new
- // one.
- if (fStateCheckPointRequest != null && !fStateCheckPointRequest.isCompleted()) {
- fStateCheckPointRequest.cancel();
+ public void readExperiment(String transactionID,
+ IStateDataRequestListener listener) {
+ // Need someone to listen to the updates as well as an fExperiment
+ // loaded.
+ if (listener != null && fExperiment != null) {
+ TmfTimeRange trange = fExperiment.getTimeRange();
+ String experimentId = fExperiment.getExperimentId();
+
+ // FIXME: there should be an id field available at the trace level
+ // to be fixed with the support of multiple files.
+ // We also need to iterate over the traces in the Experiment and
+ // execute a data Request on each of them
+ // This is also on hold till the request can be performed at a trace
+ // level.
+ // ITmfTrace[] fTraces = fExperiment.getTraces();
+ // for (int i=0; i < fTraces.length; i++) {
+ StateManager manager = StateManagerFactory.getManager(experimentId);
+ manager.executeDataRequest(trange, transactionID, listener);
+ // }
}
-
- // trigger data request to build the state system check points
- fStateCheckPointRequest = buildCheckPoints(experiment);
-
-// LTTngTreeNode experimentNode = getChildByName(experiment.getName());
-// if (experimentNode != null) {
-// // get the trace manager nodes
-// LTTngTreeNode[] traceNodes = experimentNode.getChildren();
-// for (LTTngTreeNode traceStateManagerNode : traceNodes) {
-// // The trace node needs to perform its first data request
-// // for this experiment with the main goal of building its
-// // checkpoints
-// if (traceStateManagerNode instanceof ILttExperimentSelectedListener) {
-// // no need to provide the trace to the trace manager
-// ((ILttExperimentSelectedListener) traceStateManagerNode).experimentUpdated(
-// new TmfExperimentUpdatedSignal(source, experiment, null), fwaitForCompletion);
-// }
-// }
-// }
}
-
+
/*
* (non-Javadoc)
*
- * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
- * experimentUpdated
- * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean)
+ * @see
+ * org.eclipse.linuxtools.tmf.eventlog.ITmfEventLogEventListener#handleEvent
+ * (org.eclipse.linuxtools.tmf.eventlog.ITmfEventLogEvent)
*/
- public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean wait) {
- // NOTE: This represents the end of TMF indexing for a trace, however
- // the node was already existing and the state system check points are
- // already requested and built upon selection.
- // No action for the time being
+ @TmfSignalHandler
+ public void experimentSelected(TmfExperimentSelectedSignal signal) {
+ // TmfExperiment experiment = signal.getExperiment();
+ // ITmfTrace[] traces = experiment.getTraces();
+ // for (ITmfTrace trace : traces) {
+ //
+ // }
+ if (signal != null) {
+ fExperiment = signal.getExperiment();
+ traceSelected(fExperiment);
+ }
}
-
/**
- * @return the SelectedExperiment tree node
+ * A new Experiment selected, notification received from the framework
+ * Notify the new log selection to the state handling managers
+ *
+ * @param experiment
*/
- public LTTngTreeNode getSelectedExperiment() {
- return fSelectedExperiment;
+ private void traceSelected(TmfExperiment experiment) {
+ // TODO: Re-factor when multiple traces are supported
+ // traceId, as well as when the request can be specified at the trace
+ // level
+ // For the moment it does work for only one trace per experiment.
+ String experimentId = experiment.getExperimentId();
+ StateManager manager = StateManagerFactory.getManager(experimentId);
+ // TODO: clearAllData shall not be applied to all manager calls below
+ // since that would clean all data loaded within previous iterations in
+ // the future loop. i.e. It can be applied to first manager in the loop.
+ boolean clearAllData = true;
+ manager.setTraceSelection(experiment, clearAllData);
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange()
+ /**
+ * @return
*/
- @SuppressWarnings("unchecked")
public TmfTimeRange getExperimentTimeRange() {
TmfTimeRange timeRangeResult = null;
- if (fSelectedExperiment != null) {
- timeRangeResult = ((TmfExperiment<LttngEvent>) fSelectedExperiment
- .getValue()).getTimeRange();
+ if (fExperiment != null) {
+ timeRangeResult = fExperiment.getTimeRange();
}
return timeRangeResult;
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() {
- fexperimentListener.dispose();
- }
-
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
- * #waitForComplete(boolean)
- */
- public void waitForCompletion(boolean wait) {
- fwaitForCompletion = wait;
- }
-
- private ITmfEventRequest<LttngEvent> buildCheckPoints(TmfExperiment<LttngEvent> experiment) {
- // validate
- if (experiment == null) {
- TraceDebug.debug("Received expriment is null");
- return null;
- }
-
- LTTngTreeNode experimentNode = getChildByName(experiment.getName());
- if (experimentNode == null) {
- TraceDebug.debug("Expriment Node " + experiment.getName() + " does not exist");
- return null;
- }
-
- // get the trace manager nodes associated to the experiment
- LTTngTreeNode[] traceNodes = experimentNode.getChildren();
- synchronized (ftraceToManagerMap) {
- ftraceToManagerMap.clear();
- }
-
- for (LTTngTreeNode traceStateManagerNode : traceNodes) {
- IStateTraceManager traceManager;
- try {
- traceManager = (IStateTraceManager) traceStateManagerNode;
- } catch (ClassCastException e) {
- System.out.println(e.getStackTrace().toString());
- return null;
- }
-
- // Clear all previously created check points as preparation to
- // re-build
- traceManager.clearCheckPoints();
-
- // build the trace to manager mapping for event dispatching
- synchronized (ftraceToManagerMap) {
- ftraceToManagerMap.put(traceManager.getTrace(), traceManager);
- }
- }
-
- // if no trace mapping
- if (ftraceToManagerMap.size() < 1) {
- TraceDebug.debug("No traces associated to experiment " + experiment.getName());
- return null;
- }
-
- // Prepare event data request to build state model
- ITmfEventRequest<LttngEvent> request = new TmfEventRequest<LttngEvent>(
- LttngEvent.class, TmfTimeRange.Eternity,
- TmfDataRequest.ALL_DATA, 1) {
-
- Long nbEvents = 0L;
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData()
- */
- @Override
- public void handleData() {
- TmfEvent[] events = getData();
- if (events.length > 0) {
- nbEvents++;
-
- LttngEvent event = (LttngEvent) events[0];
- ITmfTrace trace = event.getParentTrace();
- IStateTraceManager traceManager = ftraceToManagerMap
- .get(trace);
- if (traceManager != null) {
- // obtain synthetic event
- LttngSyntheticEvent synEvent = updateSynEvent(event,
- traceManager);
- // update state system, and save check points as needed
- traceManager.handleEvent(synEvent, nbEvents);
- } else {
- TraceDebug
- .debug("StateTraceManager not found for trace"
- + trace.getName());
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleFailure()
- */
- public void handleFailure() {
- printCompletedMessage();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCancel()
- */
- public void handleCancel() {
- printCompletedMessage();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleSuccess()
- */
- public void handleSuccess() {
- printCompletedMessage();
- }
-
- /**
- * @param header
- */
- private void printCompletedMessage() {
- // super.handleCompleted();
- if (TraceDebug.isDEBUG()) {
- TraceDebug.debug("Trace check point building completed, number of events handled: " + nbEvents
- + "\n\t\t");
- for (IStateTraceManager traceMgr : ftraceToManagerMap.values()) {
- TraceDebug.debug(traceMgr.toString() + "\n\t\t");
- }
- }
- }
- };
-
- // Execute event data request
- experiment.sendRequest(request);
- if (fwaitForCompletion) {
- try {
- request.waitForCompletion();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- return request;
- }
-
- private LttngSyntheticEvent updateSynEvent(LttngEvent e,
- IStateTraceManager stateTraceManager) {
- if (syntheticEvent == null || syntheticEvent.getBaseEvent() != e) {
- syntheticEvent = new LttngSyntheticEvent(e);
- }
-
- // Trace model needed by application handlers
- syntheticEvent.setTraceModel(stateTraceManager.getStateModel());
- syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
-
- return syntheticEvent;
- }
-
-}
\ No newline at end of file
+}
/*******************************************************************************
- * Copyright (c) 2009, 2010 Ericsson
+ * Copyright (c) 2009 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
package org.eclipse.linuxtools.lttng.state.experiment;
-import org.eclipse.linuxtools.lttng.TraceDebug;
-import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
-import org.eclipse.linuxtools.lttng.state.LttngStateException;
-import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager;
-import org.eclipse.linuxtools.lttng.state.trace.StateTraceManager;
-import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.state.StateManager;
+import org.eclipse.linuxtools.lttng.state.StateStacksHandler;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.state.model.StateModelFactory;
/**
* @author alvaro
// Data
// =======================================================================
- private static IStateExperimentManager experimentManager = null;
- /**
- * Allows to modify the check point interval for every new instance of trace manager
- */
- private static Long ftraceCheckPointInterval = null;
+ private static StateExperimentManager experimentManager = null;
+ private static Map<String, StateManager> instanceBook = null;
- static {
- initCheck();
- }
// ========================================================================
// Methods
// =======================================================================
/**
- * @param traceUniqueId
- * @param experiment
+ * Provide a stateManager instance per trace
+ *
* @return
*/
- public static LTTngTreeNode getManager(ITmfTrace rtrace,
- LTTngTreeNode experiment) {
+ public static StateManager getManager(String traceUniqueId) {
- // Validate
- if (rtrace == null) {
- return null;
- }
-
- String traceUniqueId = rtrace.getName();
if (traceUniqueId == null) {
return null;
}
+ initCheck();
- LTTngTreeNode managerNode = null;
- managerNode = experiment.getChildByName(traceUniqueId);
-
- if (managerNode != null && managerNode instanceof IStateTraceManager) {
- return managerNode;
+ if (instanceBook.containsKey(traceUniqueId)) {
+ return instanceBook.get(traceUniqueId);
}
-// LttngTraceState traceModel =
-// StateModelFactory.getStateEntryInstance();
- StateTraceManager manager = null;
-
- // catch potential construction problems
- try {
- manager = new StateTraceManager(experiment.getNextUniqueId(), experiment, traceUniqueId, rtrace);
+ LttngTraceState traceModel = StateModelFactory.getStateEntryInstance();
+ StateStacksHandler stateInputHandler = new StateStacksHandler(
+ traceModel);
+ StateManager manager = new StateManager(stateInputHandler);
- // Allow the possibility to configure the trace state check point
- // interval at creation time
- if (ftraceCheckPointInterval != null) {
- manager.setCheckPointInterval(ftraceCheckPointInterval);
- }
-
- } catch (LttngStateException e) {
- e.printStackTrace();
- }
-
- experiment.addChild(manager);
+ instanceBook.put(traceUniqueId, manager);
return manager;
}
*
* @return
*/
- public static IStateExperimentManager getExperimentManager() {
+ public static StateExperimentManager getExperimentManager() {
+ initCheck();
return experimentManager;
}
*
* @param traceUniqueId
*/
- public static void removeManager(ITmfTrace rtrace, LTTngTreeNode rexperiment) {
- Object experimentObj = rexperiment.getValue();
- if (rtrace != null && rexperiment != null
- && experimentObj instanceof TmfExperiment<?>) {
- LTTngTreeNode childToremove = rexperiment.getChildByName(rtrace
- .getName());
- if (childToremove != null) {
- rexperiment.removeChild(childToremove);
- }
- } else {
- TraceDebug.debug("Invalid arguments to remove manager for trace: "
- + rtrace.getName());
+ public static void removeManager(String traceUniqueId) {
+ initCheck();
+ if (traceUniqueId != null && instanceBook.containsKey(traceUniqueId)) {
+ instanceBook.remove(traceUniqueId);
}
}
*/
private static void initCheck() {
if (experimentManager == null) {
- Long id = 0L; // unique id
- String name = "StateExperimentManager"; // name
- experimentManager = new StateExperimentManager(id, name);
+ experimentManager = new StateExperimentManager();
+ instanceBook = experimentManager.getManagersByID();
}
}
*/
public static void dispose() {
if (experimentManager != null) {
+ experimentManager.dispose();
experimentManager = null;
+ instanceBook = null;
}
}
-
- /**
- * @return the traceCheckPointInterval
- */
- public static Long getTraceCheckPointInterval() {
- return ftraceCheckPointInterval;
- }
-
- /**
- * @param traceCheckPointInterval
- * the traceCheckPointInterval to set
- */
- public static void setTraceCheckPointInterval(Long traceCheckPointInterval) {
- StateManagerFactory.ftraceCheckPointInterval = traceCheckPointInterval;
- }
-}
\ No newline at end of file
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state.model;
+
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+/**
+ * <b><u>ILttngStateModelInput</u></b>
+ * <p>Interface providing the data needed by the State model
+ *
+ */
+
+/**
+ * @author alvaro
+ *
+ */
+public interface ILttngStateInputRef {
+
+ public int getNumberOfCpus();
+ public TmfTimeRange getTraceTimeWindow();
+ public String getTraceId();
+ public TmfTimeRange getExperimentTimeWindow();
+
+}
import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode;
import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
-import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext;
import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
/**
private int nb_events = 0;
// reference to input data provider
- ILttngStateContext fContext = null;
+ ILttngStateInputRef inputDataRef = null;
String traceId = "";
// ========================================================================
newState.irq_names = this.irq_names;
// This reference should never need to be updated, should it?
- newState.fContext = this.fContext;
+ newState.inputDataRef = this.inputDataRef;
// *** We need loop on each ArrayList and HashMap, as java implement
// nothing that's remotely near deep copying.
return newState;
}
- public void init(ILttngStateContext context)
+ public void init(ILttngStateInputRef inputReference)
throws LttngStateException {
- if (context == null) {
+ if (inputReference == null) {
StringBuilder sb = new StringBuilder(
"The input provider reference must not be null");
throw new LttngStateException(sb.toString());
}
// Save the input data reference
- fContext = context;
+ inputDataRef = inputReference;
// Save traceid
- traceId = fContext.getTraceId();
+ traceId = inputDataRef.getTraceId();
// max time
max_time_state_recomputed_in_seek = 0L;
// Obtain the total num of available CPUs and initialize the map
// to the corresponding size
- int numCpus = fContext.getNumberOfCpus();
+ int numCpus = inputDataRef.getNumberOfCpus();
for (Long i = 0L; i < numCpus; i++) {
cpu_states.put(i, new LTTngCPUState());
}
processes.clear();
nb_events = 0;
- TmfTimeRange timeWin = fContext.getTraceTimeWindow();
+ TmfTimeRange timeWin = inputDataRef.getTraceTimeWindow();
/* Put the per cpu running_process to beginning state : process 0. */
for (Long i = 0L; i < numCpus; i++) {
* @return total number of CPUs registered as read from the Trace
*/
public int getNumberOfCPUs() {
- return fContext.getNumberOfCpus();
+ return inputDataRef.getNumberOfCpus();
}
/**
*
* @return
*/
- public ILttngStateContext getContext() {
- return fContext;
+ public ILttngStateInputRef getInputDataRef() {
+ return inputDataRef;
}
public Long getMax_time_state_recomputed_in_seek() {
// Data
// =======================================================================
private Long running;
-
+
// ========================================================================
// Constructor
// =======================================================================
-
- public LttngTrapState() {
- this.running = 0L;
- }
-
public LttngTrapState(Long running) {
this.running = running;
}
running--;
}
}
-
- @Override
- public String toString() {
- return "running : " + running;
- }
-
}
\ No newline at end of file
package org.eclipse.linuxtools.lttng.state.model;
import org.eclipse.linuxtools.lttng.state.LttngStateException;
-import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext;
/**
* Entry point to the package
* @return
*/
public static LttngTraceState getStateEntryInstance(
- ILttngStateContext stateInputRef) {
+ ILttngStateInputRef stateInputRef) {
LttngTraceState traceState = new LttngTraceState();
try {
traceState.init(stateInputRef);
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
+import java.util.Collections;
import java.util.HashMap;
import org.eclipse.linuxtools.lttng.event.LttngEvent;
import org.eclipse.linuxtools.lttng.event.LttngEventType;
import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
import org.eclipse.linuxtools.lttng.jni.JniEvent;
-import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.trace.ITmfLocation;
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.request.ITmfRequestHandler;
import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
-import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint;
-import org.eclipse.linuxtools.tmf.trace.TmfContext;
-import org.eclipse.linuxtools.tmf.trace.TmfLocation;
import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceCheckpoint;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceContext;
-public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
+public class LTTngTextTrace extends TmfTrace implements ITmfTrace, ITmfRequestHandler<TmfEvent> {
private LttngTimestamp eventTimestamp = null;
private LttngEventSource eventSource = null;
private LttngEventType eventType = null;
}
public LTTngTextTrace(String path, boolean skipIndexing) throws Exception {
- super(path, LttngEvent.class, path, 1);
+ super(path, 1, true);
tracepath = path;
traceTypes = new HashMap<String, LttngEventType>();
eventContent = new TextLttngEventContent(currentLttngEvent);
eventReference = new LttngEventReference(this.getName());
- currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference);
+ currentLttngEvent = new TextLttngEvent(eventTimestamp, eventSource, eventType, eventContent, eventReference);
eventContent.setEvent(currentLttngEvent);
if ( positionToFirstEvent() == false ) {
throw new IOException("Fail to position to the beginning of the trace");
}
else {
- fIndexPageSize = 1000;
+ fCacheSize = 1000;
// Skip indexing if asked
-// if ( skipIndexing == true ) {
- fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation<Long>(0L)));
-// }
-// else {
-// indexTrace(true);
-// }
+ if ( skipIndexing == true ) {
+ fCheckpoints.add(new TmfTraceCheckpoint(new LttngTimestamp(0L), 0L));
+ }
+ else {
+ indexStream();
+ }
Long endTime = currentLttngEvent.getTimestamp().getValue();
positionToFirstEvent();
- getNextEvent(new TmfContext(null, 0));
+ getNextEvent(new TmfTraceContext(null, null, 0));
Long starTime = currentLttngEvent.getTimestamp().getValue();
positionToFirstEvent();
}
- public LTTngTextTrace(LTTngTextTrace oldTrace) throws Exception {
- this(oldTrace.getPath(), true);
-
- // *** VERIFY ***
- // Is this safe?
- fCheckpoints = oldTrace.fCheckpoints;
+ private LTTngTextTrace(LTTngTrace oldStream) throws Exception {
+ super(null);
+ throw new Exception("Copy constructor should never be use with a LTTngTrace!");
}
- public LTTngTextTrace createTraceCopy() {
-
- LTTngTextTrace returnedTrace = null;
-
- try {
- returnedTrace = new LTTngTextTrace(this);
- }
- catch (Exception e) {
- System.out.println("ERROR : Could not create LTTngTextTrace copy (createTraceCopy).\nError is : " + e.getStackTrace());
- }
-
- return returnedTrace;
- }
+ @Override
+ public void indexStream() {
+ // Position the trace at the beginning
+ TmfTraceContext context = seekLocation(null);
+
+ long nbEvents=1L;
+ fCheckpoints.add(new TmfTraceCheckpoint(new LttngTimestamp(0L), 0L));
+
+ LttngTimestamp startTime = null;
+ LttngTimestamp lastTime = new LttngTimestamp();
+ LttngTimestamp timestamp = null;
+ Long previousCharRead = 0L;
+
+ TextLttngEvent tmpEvent = (TextLttngEvent)getNextEvent(context);
+
+ while ( tmpEvent != null) {
+ timestamp = (LttngTimestamp)context.getTimestamp();
+ previousCharRead = nbCharRead;
+
+ if ( startTime == null ) {
+ startTime = new LttngTimestamp(timestamp.getValue());
+ }
+
+ if ((++nbEvents % fCacheSize) == 0) {
+ fCheckpoints.add(new TmfTraceCheckpoint(new LttngTimestamp(timestamp.getValue()), previousCharRead));
+ }
+
+ tmpEvent = (TextLttngEvent)getNextEvent(context);
+ }
+
+ if (timestamp != null) {
+ lastTime.setValue(timestamp.getValue());
+
+ setTimeRange( new TmfTimeRange(startTime, lastTime) );
+ notifyListeners(getTimeRange());
+ }
+
+ fNbEvents = nbEvents;
+
+ if ( showDebug == true ) {
+ for ( int pos=0; pos < fCheckpoints.size(); pos++) {
+ System.out.print(pos + ": " + "\t");
+ System.out.print( fCheckpoints.get(pos).getTimestamp() + "\t" );
+ System.out.println( fCheckpoints.get(pos).getLocation() );
+ }
+ }
+
+ }
private boolean positionToFirstEvent() {
return isSuccessful;
}
- private void skipToPosition(TmfLocation<Long> skip) {
+ private void skipToPosition(Long skipPosition) {
try {
- long skipPosition = skip.getLocation();
- if ( skipPosition < 0 ) {
- skipPosition = 0L;
- }
-
if ( showDebug == true ) {
System.out.println("skipToPosition(Long skipPosition)");
System.out.println("\tSkipping to : " + skipPosition);
System.out.println();
}
positionToFirstEvent();
- long nbSkipped = br.skip(skipPosition);
- if ( nbSkipped != skipPosition) {
- throw new IOException("Too few characters skipped, positionning failed! (skipToPosition)");
- }
+ br.skip(skipPosition);
nbCharRead = skipPosition;
}
}
}
- @Override
- @SuppressWarnings("unchecked")
- public TmfContext seekLocation(ITmfLocation<?> location) {
+ public TmfTraceContext seekLocation(Object location) {
if (location == null) {
- location = new TmfLocation<Long>(0L);
+ location = 0L;
}
-
- if (!((TmfLocation<Long>) location).getLocation().equals(nbCharRead)) {
- skipToPosition((TmfLocation<Long>) location);
+
+ TmfTraceContext tmpTraceContext = new TmfTraceContext(nbCharRead, (LttngTimestamp)currentLttngEvent.getTimestamp(), 0L);
+ Long previousCharRead = nbCharRead;
+ Long previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+ Long tmploc = (Long)location;
+
+ if ( showDebug == true ) {
+ System.out.println("seekLocation(Object location)");
+ System.out.println("\ttimestamp: " + (LttngTimestamp)currentLttngEvent.getTimestamp());
+ System.out.println("\tnbCharRead:" + nbCharRead);
+ System.out.println("\tlocation: " + location);
+ System.out.println();
}
-
- TmfContext tmpTraceContext = new TmfContext(location, 0L);
+
+ if ( tmploc < nbCharRead ) {
+ skipToPosition(tmploc);
+ }
+
+ if ( tmploc > nbCharRead ) {
+ while ( tmploc > nbCharRead ) {
+ previousCharRead = nbCharRead;
+ previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+ getNextEvent(tmpTraceContext);
+ }
+ }
+
+ tmpTraceContext.setTimestamp(new LttngTimestamp(previousTimestamp));
+ tmpTraceContext.setLocation(previousCharRead);
return tmpTraceContext;
}
- private LttngEvent parseMyNextEvent(TmfContext context) {
+
+ @Override
+ public TmfTraceContext seekEvent(TmfTimestamp timestamp) {
+
+ if (timestamp == null) {
+ timestamp = getStartTime();
+ }
+
+ int index = Collections.binarySearch(fCheckpoints, new TmfTraceCheckpoint(timestamp, 0));
+
+ if (index < 0) {
+ index = 0;
+ }
+
+ Object location = (index < fCheckpoints.size()) ? fCheckpoints.elementAt(index).getLocation() : null;
+
+ if ( showDebug == true ) {
+ System.out.println("seekEvent(TmfTimestamp timestamp)");
+ System.out.println("\ttimestamp: " + timestamp.getValue());
+ System.out.println("\tindex: " + index);
+ System.out.println("\tlocation: " + location);
+ System.out.println();
+ }
+
+ // *** HACK ***
+ // We only know the timestamp AFTER we read the actual event
+ // For this reason, we save the current "position" in byte (nbCharRead) and we seek back 1 event after we find our event
+ TmfTraceContext currentEventContext = seekLocation(location);
+
+ Long previousCharRead = nbCharRead;
+ Long previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+ TmfEvent event = getNextEvent(currentEventContext);
+
+ while ( (event != null) && (event.getTimestamp().getValue() < timestamp.getValue()) ) {
+ previousCharRead = nbCharRead;
+ previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+ event = getNextEvent(currentEventContext);
+ }
+
+ if ( event != null ) {
+ skipToPosition(previousCharRead);
+ currentEventContext.setLocation(previousCharRead);
+ currentEventContext.setTimestamp(new LttngTimestamp(previousTimestamp));
+ }
+
+ return currentEventContext;
+ }
+
+ @Override
+ public TmfTraceContext seekEvent(long position) {
+
+ int checkPointPos = ((int)position / fCacheSize);
+
+ Object location;
+ location = ( checkPointPos < fCheckpoints.size()) ? fCheckpoints.elementAt(checkPointPos).getLocation() : null;
+
+ long index = ((position / fCacheSize)*fCacheSize)-1;
+
+ if ( index < 0) {
+ index = 0;
+ }
+
+ if ( showDebug == true ) {
+ System.out.println("seekEvent(long position)");
+ System.out.println("\tposition: " + position);
+ System.out.println("\tindex: " + index);
+ System.out.println("\tlocation: " + location);
+ System.out.println();
+ }
+ TmfTraceContext currentEventContext = seekLocation(location);
+ Long previousCharRead = (Long)currentEventContext.getLocation();
+ Long previousTimestamp = currentEventContext.getTimestamp().getValue();
+
+ TmfEvent event = null;
+ while (index < position) {
+ event = getNextEvent(currentEventContext);
+ previousCharRead = nbCharRead;
+ previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+ index++;
+ }
+
+ if ( event != null ) {
+ skipToPosition(previousCharRead);
+ currentEventContext.setLocation(previousCharRead);
+ currentEventContext.setTimestamp(new LttngTimestamp(previousTimestamp));
+ }
+
+ return currentEventContext;
+ }
+
+ @Override
+ public TmfEvent getNextEvent(TmfTraceContext context) {
// All parsing variables declared here so to be able to print them into the catch if needed
String tmpContent = null;
// *** HACK ***
// Evil exit case here : the two last line of the text dump does not contain "."
- // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more
+ // We should check in a better way (string comparaison and such) but it make the whole process to weight a lot more
// Conclusion : this is ugly but fast.
if ( tmpCurIndex < 0 ) {
if ( showDebug == true ) {
System.out.println("END OF FILE.");
System.out.println();
}
- return null;
+ return returnedEvent;
}
tracefile = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
currentLttngEvent.setContent(eventContent);
currentLttngEvent.setType(traceTypes.get(tmpTypeKey));
+ context.setTimestamp(eventTimestamp);
+ context.setLocation(nbCharRead);
+
returnedEvent = currentLttngEvent;
}
else if ( showDebug == true ) {
}
@Override
- public ITmfLocation<?> getCurrentLocation() {
- return new TmfLocation<Long>(nbCharRead);
+ public Object getCurrentLocation() {
+ return nbCharRead;
}
- @Override
- public LttngEvent parseEvent(TmfContext context) {
- context = seekLocation(context.getLocation());
- return parseMyNextEvent(context);
+ @Override
+ public LttngEvent parseEvent(TmfTraceContext context) {
+ Long location = null;
+ LttngEvent returnedEvent = null;
+
+ if ( (currentLttngEvent!= null) && (! currentLttngEvent.getTimestamp().equals(context.getTimestamp()) ) ) {
+ seekEvent(context.getTimestamp());
+ getNextEvent(context);
+ }
+
+ if ( currentLttngEvent != null ) {
+ returnedEvent = currentLttngEvent;
+ }
+ location = (Long)getCurrentLocation();
+
+ context.setLocation(location);
+ context.setTimestamp(currentLttngEvent.getTimestamp());
+ context.incrIndex();
+
+ return returnedEvent;
}
- public int getCpuNumber() {
+ public int getCpuNumber() {
return cpuNumber;
}
}
// Redefine event to override method we know won't work with a Text tracefile
class TextLttngEvent extends LttngEvent {
- public TextLttngEvent( TmfTrace<LttngEvent> parent,
- LttngTimestamp timestamp,
+ public TextLttngEvent( LttngTimestamp timestamp,
LttngEventSource source,
LttngEventType type,
LttngEventContent content,
LttngEventReference reference)
{
- super(parent, timestamp, source, type, content, reference, null);
+ super(timestamp, source, type, content, reference, null);
}
public TextLttngEvent(TextLttngEvent oldEvent) {
this(
- oldEvent.getParentTrace(),
(LttngTimestamp)oldEvent.getTimestamp(),
(LttngEventSource)oldEvent.getSource(),
(LttngEventType)oldEvent.getType(),
@Override
public LttngEventField getField(int position) {
LttngEventField returnedField = null;
- String label = null;
- try {
- label = fParentEvent.getType().getLabel(position);
- returnedField = this.getField(label);
- }
- catch (TmfNoSuchFieldException e) {
- System.out.println("Invalid field position requested : " + position + ", ignoring (getField).");
- }
+ String label = fParentEvent.getType().getLabel(position);
+
+ if ( label != null ) {
+ returnedField = this.getField(label);
+ }
return returnedField;
}
-}
\ No newline at end of file
+}
import org.eclipse.linuxtools.lttng.event.LttngEventReference;
import org.eclipse.linuxtools.lttng.event.LttngEventSource;
import org.eclipse.linuxtools.lttng.event.LttngEventType;
-import org.eclipse.linuxtools.lttng.event.LttngLocation;
import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
import org.eclipse.linuxtools.lttng.jni.JniEvent;
import org.eclipse.linuxtools.lttng.jni.JniMarker;
+import org.eclipse.linuxtools.lttng.jni.JniTime;
import org.eclipse.linuxtools.lttng.jni.JniTrace;
import org.eclipse.linuxtools.lttng.jni.JniTracefile;
-import org.eclipse.linuxtools.lttng.jni.common.JniTime;
-import org.eclipse.linuxtools.lttng.jni.exception.JniException;
-import org.eclipse.linuxtools.lttng.jni.factory.JniTraceFactory;
import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
-import org.eclipse.linuxtools.tmf.trace.ITmfLocation;
-import org.eclipse.linuxtools.tmf.trace.TmfContext;
import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceContext;
class LTTngTraceException extends LttngException {
* LTTng trace implementation. It accesses the C trace handling library
* (seeking, reading and parsing) through the JNI component.
*/
-public class LTTngTrace extends TmfTrace<LttngEvent> {
-
- public static boolean printDebug = false;
- public static boolean uniqueEvent = false;
-
- private final static boolean SHOW_LTT_DEBUG_DEFAULT = false;
- private final static boolean IS_PARSING_NEEDED_DEFAULT = true;
- private final static int CHECKPOINT_PAGE_SIZE = 1000;
+public class LTTngTrace extends TmfTrace {
+ private final static boolean SHOW_LTT_DEBUG_DEFAULT = false;
+ private final static boolean IS_PARSING_NEEDED_DEFAULT = false;
+ private final static int CHECKPOINT_PAGE_SIZE = 1;
// Reference to our JNI trace
private JniTrace currentJniTrace = null;
- // ***
- // UNHACKED : We can no longer do that because TCF need to maintain several events at once.
- // This is very slow to do so in LTTng, this has to be temporary.
- // *** HACK ***
- // To save time, we will declare all component of the LttngEvent during the construction of the trace
- // Then, while reading the trace, we will just SET the values instead of declaring new object
- // ***
+ // *** HACK ***
+ // To save time, we will declare all component of the LttngEvent during the construction of the trace
+ // Then, while reading the trace, we will just SET the values instead of declaring new object
LttngTimestamp eventTimestamp = null;
LttngEventSource eventSource = null;
+ LttngEventType eventType = null;
LttngEventContent eventContent = null;
LttngEventReference eventReference = null;
-
-
// The actual event
LttngEvent currentLttngEvent = null;
- // The current location
- LttngLocation previousLocation = null;
-
- LttngEventType eventType = null;
// Hashmap of the possible types of events (Tracefile/CPU/Marker in the JNI)
HashMap<String, LttngEventType> traceTypes = null;
// This vector will be used to quickly find a marker name from a position
*
*/
public LTTngTrace(String path, boolean waitForCompletion, boolean bypassIndexing) throws Exception {
- super(path, LttngEvent.class, path, CHECKPOINT_PAGE_SIZE);
+ super(path, CHECKPOINT_PAGE_SIZE, true);
try {
- currentJniTrace = JniTraceFactory.getJniTrace(path, SHOW_LTT_DEBUG_DEFAULT);
+ currentJniTrace = new JniTrace(path, SHOW_LTT_DEBUG_DEFAULT);
}
catch (Exception e) {
throw new LTTngTraceException(e.getMessage());
}
+ // Set the start time of the trace
+ setTimeRange( new TmfTimeRange( new LttngTimestamp(currentJniTrace.getStartTime().getTime()),
+ new LttngTimestamp(currentJniTrace.getEndTime().getTime())
+ )
+ );
+
// Export all the event types from the JNI side
traceTypes = new HashMap<String, LttngEventType>();
traceTypeNames = new Vector<String>();
eventReference = new LttngEventReference(this.getName());
// Create the skeleton event
- currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
-
- // Create a new current location
- previousLocation = new LttngLocation();
-
+ currentLttngEvent = new LttngEvent(eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
// Set the currentEvent to the eventContent
eventContent.setEvent(currentLttngEvent);
-// // Bypass indexing if asked
-// if ( bypassIndexing == false ) {
-// indexTrace(true);
-// }
-// else {
- // Even if we don't have any index, set ONE checkpoint
-// fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L) , new LttngLocation() ) );
-
- // Set the start time of the trace
- setTimeRange( new TmfTimeRange( new LttngTimestamp(currentJniTrace.getStartTime().getTime()),
- new LttngTimestamp(currentJniTrace.getEndTime().getTime())
- ) );
-// }
+ // Bypass indexing if asked
+ if ( bypassIndexing == false ) {
+ indexStream();
+ }
}
/*
* Copy constructor is forbidden for LttngEvenmStream
*
+ * Events are only valid for a very limited period of time and
+ * JNI library does not support multiple access at once (yet?).
+ * For this reason, copy constructor should NEVER be used.
*/
- public LTTngTrace(LTTngTrace oldTrace) throws Exception {
- this(oldTrace.getPath(), false, true);
-
- // *** VERIFY ***
- // Is this safe?
- this.fCheckpoints = oldTrace.fCheckpoints;
-
- /*
- // This would only work if the index is already done
- this.fCheckpoints = new Vector<TmfCheckpoint>( oldTrace.fCheckpoints.size() );
- for (int x = 0; x<oldTrace.fCheckpoints.size(); x++){
- TmfCheckpoint tmpCheckPoint = oldTrace.fCheckpoints.get(x);
- this.fCheckpoints.add( new TmfCheckpoint(tmpCheckPoint.getTimestamp(), tmpCheckPoint.getLocation()) );
- }
- */
-
- // Set the start time of the trace
- setTimeRange( new TmfTimeRange( new LttngTimestamp(oldTrace.getStartTime()),
- new LttngTimestamp(oldTrace.getEndTime()))
- );
- }
-
- public LTTngTrace createTraceCopy() {
- LTTngTrace returnedTrace = null;
-
- try {
- returnedTrace = new LTTngTrace(this);
- }
- catch (Exception e) {
- System.out.println("ERROR : Could not create LTTngTrace copy (createTraceCopy).\nError is : " + e.getStackTrace());
- }
-
- return returnedTrace;
- }
-
- @Override
- public LTTngTrace clone() {
- LTTngTrace clone = null;
- try {
- clone = (LTTngTrace) super.clone();
- try {
- clone.currentJniTrace = JniTraceFactory.getJniTrace(getPath(), SHOW_LTT_DEBUG_DEFAULT);
- } catch (JniException e) {
- e.printStackTrace();
- }
-
- // Export all the event types from the JNI side
- clone.traceTypes = new HashMap<String, LttngEventType>();
- clone.traceTypeNames = new Vector<String>();
- clone.initialiseEventTypes(clone.currentJniTrace);
-
- // Verify that all those "default constructor" are safe to use
- clone.eventTimestamp = new LttngTimestamp();
- clone.eventSource = new LttngEventSource();
- clone.eventType = new LttngEventType();
- clone.eventContent = new LttngEventContent(clone.currentLttngEvent);
- clone.eventReference = new LttngEventReference(this.getName());
-
- // Create the skeleton event
- clone.currentLttngEvent = new LttngEvent(this, clone.eventTimestamp, clone.eventSource, clone.eventType, clone.eventContent, clone.eventReference, null);
-
- // Create a new current location
- clone.previousLocation = new LttngLocation();
-
- // Set the currentEvent to the eventContent
- clone.eventContent.setEvent(clone.currentLttngEvent);
-
- // Set the start time of the trace
- setTimeRange(new TmfTimeRange(
- new LttngTimestamp(clone.currentJniTrace.getStartTime().getTime()),
- new LttngTimestamp(clone.currentJniTrace.getEndTime().getTime())
- ));
- }
- catch (CloneNotSupportedException e) {
- }
-
- return clone;
+ private LTTngTrace(LTTngTrace oldStream) throws Exception {
+ super(null);
+ throw new Exception("Copy constructor should never be use with a LTTngTrace!");
}
-
/*
* Fill out the HashMap with "Type" (Tracefile/Marker)
*
this.traceTypeNames.add(newTypeKey);
}
-// /**
-// * Index the current trace.
-// *
-// * @param useless This boolean is only to comply to the interface and will be ignored.
-// */
-// @Override
-// public synchronized void indexTrace(boolean useless) {
-//
-// long nbEvents=0L;
-//
-// // Start time need to be null to detect none have been set
-// // LastTime need to exist so we can ajust it as we go
-// LttngTimestamp startTime = null;
-// LttngTimestamp lastTime = new LttngTimestamp();
-//
-// // Position the trace at the beginning
-// TmfContext context = seekEvent( new LttngTimestamp(0L) );
-//
-// // Read the first event and extract the location
-// LttngEvent tmpEvent = (LttngEvent)getNextEvent(context);
-//
-// // If we read the first event, define the start time.
-// if ( tmpEvent != null ) {
-// startTime = new LttngTimestamp( tmpEvent.getTimestamp() );
-// lastTime.setValue(tmpEvent.getTimestamp().getValue());
-// }
-//
-// // Now, we read each event until we hit the end of the trace
-// // We will create a new checkpoint every "getCacheSize()" event
-// while ( tmpEvent != null) {
-// // Update the last time each time we read a new event
-// lastTime.setValue(tmpEvent.getTimestamp().getValue());
-//
-// // Save a check point if needed
-// if ((nbEvents++ % getCacheSize()) == 0) {
-// // *** IMPORTANT
-// // We need to NEW each stuff we put in checkpoint
-// // Otherwise everything will be the same!
-// LttngTimestamp tmpTimestamp = new LttngTimestamp( (LttngTimestamp)tmpEvent.getTimestamp() );
-// LttngLocation newLocation = new LttngLocation( (LttngTimestamp)tmpEvent.getTimestamp() );
-//
-// fCheckpoints.add(new TmfCheckpoint(tmpTimestamp, newLocation ) );
-// }
-// // Read the next event
-// tmpEvent = (LttngEvent)getNextEvent(context);
-// }
-//
-// // If we have a start time, we should have an end time as well
-// // Issue the new range
-// if (startTime != null) {
-// setTimeRange( new TmfTimeRange(startTime, lastTime) );
-// notifyListeners(getTimeRange() );
-// }
-//
-// // Ajust the total number of event in the trace
-// fNbEvents = nbEvents;
-// //printCheckpointsVector();
-// //printDebug = true;
-// }
-
- /**
- * Return the latest saved location.
- * Note : Modifying the returned location may result in buggy positionning!
- *
- * @return The LttngLocation as it was after the last operation.
- *
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- */
- @Override
- public ITmfLocation<?> getCurrentLocation() {
- return previousLocation;
- }
-
- /**
- * Position the trace to the event at the given location.<p>
- * NOTE : Seeking by location is very fast compare to seeking by position
- * but is still slower than "ReadNext", avoid using it for small interval.
- *
- * @param location Location of the event in the trace.
- * If no event available at this exact location, we will position ourself to the next one.
- *
- * @return The TmfContext that point to this event
- *
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- * @see org.eclipse.linuxtools.tmf.trace.TmfContext
- */
- @Override
- public synchronized TmfContext seekLocation(ITmfLocation<?> location) {
-
- if ( printDebug == true ) {
- System.out.println("seekLocation(location) location -> " + location);
- }
-
- // If the location in context is null, create a new one
- LttngLocation curLocation = null;
- if ( location == null ) {
- curLocation = new LttngLocation();
- }
- else {
- curLocation = (LttngLocation)location;
- }
-
- // *** NOTE :
- // Update to location should (and will) be done in SeekEvent.
-
- // The only seek valid in LTTng is with the time, we call seekEvent(timestamp)
- return seekEvent( curLocation.getOperationTime() );
- }
-
- /**
- * Position the trace to the event at the given time.<p>
- * NOTE : Seeking by time is very fast compare to seeking by position
- * but is still slower than "ReadNext", avoid using it for small interval.
+ /**
+ * Return the next event in the trace.<p>
*
- * @param timestamp Time of the event in the trace.
- * If no event available at this exact time, we will position ourself to the next one.
+ * @param context The actual context of the trace
*
- * @return The TmfContext that point to this event
+ * @return The next event, or null if none available
*
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- * @see org.eclipse.linuxtools.tmf.trace.TmfContext
- */
+ * @see org.eclipse.linuxtools.lttng.event.LttngEvent
+ */
@Override
- public synchronized TmfContext seekEvent(TmfTimestamp timestamp) {
-
- if ( printDebug == true ) {
- System.out.println("seekEvent(timestamp) timestamp -> " + timestamp);
- }
-
- // Call JNI to seek
- currentJniTrace.seekToTime(new JniTime(timestamp.getValue()));
+ public LttngEvent parseEvent(TmfTraceContext context) {
+ JniEvent jniEvent;
+ LttngTimestamp timestamp = null;
+ LttngEvent returnedEvent = null;
- // Save the time at which we seeked
- previousLocation.setOperationTime(timestamp.getValue());
- // Set the operation marker as seek, to be able to detect we did "seek" this event
- previousLocation.setLastOperationSeek();
-
- // *** VERIFY ***
- // Is that too paranoid?
- //
- // We don't trust what upper level could do with our internal location
- // so we create a new one to return instead
- LttngLocation curLocation = new LttngLocation(previousLocation);
-
- return new TmfContext( curLocation );
- }
-
- /**
- * Position the trace to the event at the given position (rank).<p>
- * NOTE : Seeking by position is very slow in LTTng, consider seeking by timestamp.
- *
- * @param position Position (or rank) of the event in the trace, starting at 0.
- *
- * @return The TmfContext that point to this event
- *
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- * @see org.eclipse.linuxtools.tmf.trace.TmfContext
- */
- @Override
- public synchronized TmfContext seekEvent(long position) {
-
- if ( printDebug == true ) {
- System.out.println("seekEvent(position) position -> " + position);
- }
-
- TmfTimestamp timestamp = null;
- long index = position / getCacheSize();
-
- // Get the timestamp of the closest check point to the given position
- if (fCheckpoints.size() > 0) {
- if (index >= fCheckpoints.size()) {
- index = fCheckpoints.size() - 1;
- }
- timestamp = (TmfTimestamp)fCheckpoints.elementAt((int)index).getTimestamp();
- }
- // If none, take the start time of the trace
- else {
- timestamp = getStartTime();
- }
-
- // Seek to the found time
- TmfContext tmpContext = seekEvent(timestamp);
- previousLocation = (LttngLocation)tmpContext.getLocation();
-
- // Ajust the index of the event we found at this check point position
- Long currentPosition = index * getCacheSize();
-
- Long lastTimeValueRead = 0L;
-
- // Get the event at current position. This won't move to the next one
- JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
- // Now that we are positionned at the checkpoint,
- // we need to "readNext" (Position - CheckpointPosition) times or until trace "run out"
- while ( (tmpJniEvent != null) && ( currentPosition < position ) ) {
- tmpJniEvent = currentJniTrace.readNextEvent();
- currentPosition++;
- }
-
- // If we found our event, save its timestamp
- if ( tmpJniEvent != null ) {
- lastTimeValueRead = tmpJniEvent.getEventTime().getTime();
- }
-
- // Set the operation marker as seek, to be able to detect we did "seek" this event
- previousLocation.setLastOperationSeek();
- // Save read event time
- previousLocation.setOperationTime(lastTimeValueRead);
-
- // *** VERIFY ***
- // Is that too paranoid?
- //
- // We don't trust what upper level could do with our internal location
- // so we create a new one to return instead
- LttngLocation curLocation = new LttngLocation(previousLocation);
-
- return new TmfContext( curLocation );
- }
-
- /**
- * Return the event in the trace according to the given context. Read it if necessary.<p>
- * Similar (same?) as ParseEvent except that calling GetNext twice read the next one the second time.
- *
- * @param context Current TmfContext where to get the event
- *
- * @return The LttngEvent we read of null if no event are available
- *
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- * @see org.eclipse.linuxtools.tmf.trace.TmfContext
- */
-
- public int nbEventsRead = 0;
- @Override
- public synchronized LttngEvent getNextEvent(TmfContext context) {
-
- if ( printDebug == true ) {
- System.out.println("getNextEvent(context) context.getLocation() -> " + context.getLocation());
- }
-
- LttngEvent returnedEvent = null;
- LttngLocation curLocation = null;
-
- // If the location in context is null, create a new one
- if ( context.getLocation() == null ) {
- curLocation = new LttngLocation();
- context.setLocation(curLocation);
- }
- else {
- // Otherwise, we use the one in context; it should be a valid LttngLocation
- curLocation = (LttngLocation)context.getLocation();
- }
-
- // *** HACK ***
- // TMF assumes it is possible to read (GetNextEvent) to the next Event once ParseEvent() is called
- // In LTTNG, there is not difference between "Parsing" and "Reading" an event.
- // Since parsing/reading invalidate the previous event,
- // we need to make sure the sequence ParseEvent() -> GetNextEvent() will not actually move to the next event.
- // To do so, we avoid moving for call to "GetNextEvent()" that follow call to a call to "ParseEvent()".
- // However, calling ParseEvent() -> GetNextEvent() -> GetNextEvent() will only move next by one.
-
- // *** Positioning trick :
- // GetNextEvent only read the trace if :
- // 1- The last operation was NOT a ParseEvent --> A read is required
- // OR
- // 2- The time of the previous location is different from the current one --> A seek + a read is required
- if ( (curLocation.isLastOperationParse() != true) ||
- (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) )
- {
- if ( previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) {
- if ( printDebug == true ) {
- System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " + previousLocation.getOperationTimeValue() + " CurrentTime" + curLocation.getOperationTimeValue() + " ]");
- }
- seekEvent( curLocation.getOperationTime() );
- }
- // Read the next event from the trace. The last one will NO LONGER BE VALID.
- returnedEvent = readEvent(curLocation);
- nbEventsRead++;
-
- // Set the operation marker as read to both location, to be able to detect we did "read" this event
- previousLocation.setLastOperationReadNext();
- curLocation.setLastOperationReadNext();
- }
- else {
- // No event was read, just return the one currently loaded (the last one we read)
- returnedEvent = currentLttngEvent;
+ synchronized (currentJniTrace) {
+ // Seek to the context's location
+ seekLocation(context.getLocation());
- // *** IMPORTANT!
- // Reset (erase) the operation marker to both location, to be able to detect we did NOT "read" this event
- previousLocation.resetLocationState();
- curLocation.resetLocationState();
- }
-
- // If we read an event, set it's time to the locations (both previous and current)
- if ( returnedEvent != null ) {
- previousLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
- curLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
+ // Read an event from the JNI and convert it into a LttngEvent
+ jniEvent = currentJniTrace.readNextEvent();
- updateIndex(context, context.getRank(), returnedEvent.getTimestamp());
- context.updateRank(1);
- }
-
- return returnedEvent;
- }
-
-
- /**
- * Return the event in the trace according to the given context. Read it if necessary.<p>
- * Similar (same?) as GetNextEvent except that calling ParseEvent twice will return the same event
- *
- * @param context Current TmfContext where to get the event
- *
- * @return The LttngEvent we read of null if no event are available
- *
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- * @see org.eclipse.linuxtools.tmf.trace.TmfContext
- */
- @Override
- public synchronized LttngEvent parseEvent(TmfContext context) {
-
- if ( printDebug == true ) {
- System.out.println("parseEvent(context) context.getLocation() -> " + context.getLocation());
- }
-
- LttngEvent returnedEvent = null;
- LttngLocation curLocation = null;
-
- // If the location in context is null, create a new one
- if ( context.getLocation() == null ) {
- curLocation = new LttngLocation();
- context.setLocation(curLocation);
- }
- // Otherwise, we use the one in context; it should be a valid LttngLocation
- else {
- curLocation = (LttngLocation)context.getLocation();
- }
-
- // *** HACK ***
- // TMF assumes it is possible to read (GetNextEvent) to the next Event once ParseEvent() is called
- // In LTTNG, there is not difference between "Parsing" and "Reading" an event.
- // So, before "Parsing" an event, we have to make sure we didn't "Read" it alreafy.
- // Also, "Reading" invalidate the previous Event in LTTNG and seek back is very costly,
- // so calling twice "Parse" will return the same event, giving a way to get the "Currently loaded" event
-
- // *** Positionning trick :
- // ParseEvent only read the trace if :
- // 1- The last operation was NOT a ParseEvent or a GetNextEvent --> A read is required
- // OR
- // 2- The time of the previous location is different from the current one --> A seek + a read is required
- if ( ( (curLocation.isLastOperationParse() != true) && ((curLocation.isLastOperationReadNext() != true)) ) ||
- (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) )
- {
- // Previous time != Current time : We need to reposition to the current time
- if (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) {
- if ( printDebug == true ) {
- System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " + previousLocation.getOperationTimeValue() + " CurrentTime" + curLocation.getOperationTimeValue() + " ]");
- }
- seekEvent( curLocation.getOperationTime() );
- }
-
- // Read the next event from the trace. The last one will NO LONGER BE VALID.
- returnedEvent = readEvent(curLocation);
- }
- else {
- // No event was read, just return the one currently loaded (the last one we read)
- returnedEvent = currentLttngEvent;
- }
-
- // If we read an event, set it's time to the locations (both previous and current)
- if ( returnedEvent != null ) {
- previousLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
- curLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
+ //currentLttngEvent = (jniEvent != null) ? convertJniEventToTmf(jniEvent, true) : null;
+ if ( jniEvent != null ) {
+ currentLttngEvent = convertJniEventToTmf(jniEvent);
+ returnedEvent = currentLttngEvent;
+ }
+
+ // Save timestamp
+ timestamp = (LttngTimestamp) getCurrentLocation();
}
-
- // Set the operation marker as parse to both location, to be able to detect we already "read" this event
- previousLocation.setLastOperationParse();
- curLocation.setLastOperationParse();
-
- return returnedEvent;
- }
-
- /*
- * Read the next event from the JNI and convert it as Lttng Event<p>
- *
- * @param location Current LttngLocation that to be updated with the event timestamp
- *
- * @return The LttngEvent we read of null if no event are available
- *
- * @see org.eclipse.linuxtools.lttng.event.LttngLocation
- * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
- */
- private synchronized LttngEvent readEvent(LttngLocation location) {
- LttngEvent returnedEvent = null;
- JniEvent tmpEvent = null;
-
- // Read the next event from JNI. THIS WILL INVALIDATE THE CURRENT LTTNG EVENT.
- tmpEvent = currentJniTrace.readNextEvent();
-
- if ( tmpEvent != null ) {
- // *** NOTE
- // Convert will update the currentLttngEvent
- returnedEvent = convertJniEventToTmf(tmpEvent);
-
- location.setOperationTime( (LttngTimestamp)returnedEvent.getTimestamp() );
- }
- // *** NOTE
- // If the read failed (likely the last event in the trace), set the LastReadTime to the JNI time
- // That way, even if we try to read again, we will step over the bogus seek and read
- else {
- location.setOperationTime( getEndTime().getValue() + 1 );
- }
-
- return returnedEvent;
+ context.setLocation(timestamp);
+ context.setTimestamp(timestamp);
+ context.incrIndex();
+
+ return returnedEvent;
}
/**
* @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
* @see org.eclipse.linuxtools.lttng.event.LttngEvent
*/
- public synchronized LttngEvent convertJniEventToTmf(JniEvent newEvent) {
+ public LttngEvent convertJniEventToTmf(JniEvent newEvent) {
currentLttngEvent = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT);
return currentLttngEvent;
* @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
* @see org.eclipse.linuxtools.lttng.event.LttngEvent
*/
- public synchronized LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) {
-
- if ( uniqueEvent == true ) {
-
- // ***
- // UNHACKED : We can no longer do that because TCF need to maintain several events at once.
- // This is very slow to do so in LTTng, this has to be temporary.
- // *** HACK ***
- // To save time here, we only set value instead of allocating new object
- // This give an HUGE performance improvement
- // all allocation done in the LttngTrace constructor
- // ***
- eventTimestamp.setValue(jniEvent.getEventTime().getTime());
- eventSource.setSourceId(jniEvent.requestEventSource());
-
- eventType = traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) );
-
- eventReference.setValue(jniEvent.getParentTracefile().getTracefilePath());
- eventReference.setTracepath(this.getName());
-
- eventContent.emptyContent();
-
- currentLttngEvent.setType(eventType);
- // Save the jni reference
- currentLttngEvent.updateJniEventReference(jniEvent);
-
- // Parse now if was asked
- // Warning : THIS IS SLOW
- if (isParsingNeeded == true ) {
- eventContent.getFields();
- }
-
- return currentLttngEvent;
+ public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) {
+ // *** HACK ***
+ // To save time here, we only set value instead of allocating new object
+ // This give an HUGE performance improvement
+ // all allocation done in the LttngTrace constructor
+
+ eventTimestamp.setValue(jniEvent.getEventTime().getTime());
+ eventSource.setSourceId(jniEvent.requestEventSource());
+
+ eventType = traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) );
+
+ eventReference.setValue(jniEvent.getParentTracefile().getTracefilePath());
+ eventReference.setTracepath(this.getName());
+
+// eventContent.setEvent(currentLttngEvent);
+// eventContent.setType(eventType);
+ eventContent.emptyContent();
+
+// currentLttngEvent.setContent(eventContent);
+ currentLttngEvent.setType(eventType);
+ // Save the jni reference
+ currentLttngEvent.updateJniEventReference(jniEvent);
+
+ // Parse now if was asked
+ // Warning : THIS IS SLOW
+ if (isParsingNeeded == true ) {
+ eventContent.getFields();
+ }
+
+ return currentLttngEvent;
+ }
+
+ /**
+ * Seek (move) to a certain location in the trace.<p>
+ *
+ * WARNING : No event is read by this function, it just seek to a certain time.<br>
+ * Use "parseEvent()" or "getNextEvent()" to get the event we seeked to.
+ *
+ * @param location a TmfTimestamp of a position in the trace
+ *
+ * @return TmfTraceContext pointing the position in the trace at the seek location
+ */
+ public TmfTraceContext seekLocation(Object location) {
+
+ LttngTimestamp timestamp = null;
+
+ // If location is null, interpret this as a request to get back to the beginning of the trace
+ // in that case, just change the location, the seek will happen below
+ if (location == null) {
+ location = getStartTime();
+ }
+
+ if (location instanceof TmfTimestamp) {
+ long value = ((TmfTimestamp) location).getValue();
+ if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) {
+ synchronized (currentJniTrace) {
+ currentJniTrace.seekToTime(new JniTime(value));
+ timestamp = (LttngTimestamp) getCurrentLocation();
+ }
+ }
}
else {
- return convertJniEventToTmfMultipleEventEvilFix(jniEvent, isParsingNeeded);
+ System.out.println("ERROR : Location not instance of TmfTimestamp");
}
-
+
+ // FIXME: LTTng hack - start
+ // return new TmfTraceContext(timestamp, timestamp, 0); // Original
+ return new TmfTraceContext(timestamp, timestamp, -1); // Hacked
+ // FIXME: LTTng hack - end
}
/**
- * This method is a temporary fix to support multiple events at once in TMF
- * This is expected to be slow and should be fixed in another way.
- * See comment in convertJniEventToTmf();
+ * Location (timestamp) of our current position in the trace.<p>
*
- * @param jniEvent The current JNI Event
- * @return Current Lttng Event fully parsed
+ * @return The time (in LttngTimestamp format) of the current event or AFTER endTime if no more event is available.
*/
- private synchronized LttngEvent convertJniEventToTmfMultipleEventEvilFix(JniEvent jniEvent, boolean isParsingNeeded) {
- // *** HACK ***
- // Below : the "fix" with all the new and the full-parse
- // Allocating new memory is slow.
- // Parsing every events is very slow.
- eventTimestamp = new LttngTimestamp(jniEvent.getEventTime().getTime());
- eventSource = new LttngEventSource(jniEvent.requestEventSource());
- eventReference = new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName());
- eventType = new LttngEventType(traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) ));
- eventContent = new LttngEventContent(currentLttngEvent);
- currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
-
- // The jni reference is no longer reliable but we will keep it anyhow
- currentLttngEvent.updateJniEventReference(jniEvent);
- // Ensure that the content is correctly set
- eventContent.setEvent(currentLttngEvent);
+ @Override
+ public Object getCurrentLocation() {
+ LttngTimestamp returnedLocation = null;
+ JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
- // Parse the event if it was needed
- // *** WARNING ***
- // ONLY for testing, NOT parsing events with non-unique events WILL result in segfault in the JVM
- if ( isParsingNeeded == true ) {
- eventContent.getFields();
+ if ( tmpJniEvent != null ) {
+ returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime());
}
-
- return currentLttngEvent;
+ else {
+ returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 );
+ }
+
+ return returnedLocation;
}
-
-
/**
* Reference to the current LttngTrace we are reading from.<p>
*
}
}
- /**
- * Print the content of the checkpoint vector.<p>
- *
- * This is intended for debug purpose only.
- */
- public void printCheckpointsVector() {
- System.out.println("StartTime : " + getTimeRange().getStartTime().getValue());
- System.out.println("EndTime : " + getTimeRange().getEndTime().getValue());
-
- for ( int pos=0; pos < fCheckpoints.size(); pos++) {
- System.out.print(pos + ": " + "\t");
- System.out.print( fCheckpoints.get(pos).getTimestamp() + "\t" );
- System.out.println( fCheckpoints.get(pos).getLocation() );
- }
- }
- /**
- * Return a String identifying this trace.
- *
- * @return String that identify this trace
- */
@Override
public String toString() {
String returnedData="";
return key;
}
-}
\ No newline at end of file
+}