1 package org
.eclipse
.linuxtools
.lttng
.jni
;
2 /*******************************************************************************
3 * Copyright (c) 2009 Ericsson
5 * All rights reserved. This program and the accompanying materials are
6 * made available under the terms of the Eclipse Public License v1.0 which
7 * accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
11 * William Bourque (wbourque@gmail.com) - Initial API and implementation
12 *******************************************************************************/
15 import java
.util
.HashMap
;
17 import org
.eclipse
.linuxtools
.lttng
.jni
.common
.JniTime
;
18 import org
.eclipse
.linuxtools
.lttng
.jni
.common
.Jni_C_Pointer_And_Library_Id
;
19 import org
.eclipse
.linuxtools
.lttng
.jni
.exception
.JniEventException
;
20 import org
.eclipse
.linuxtools
.lttng
.jni
.exception
.JniException
;
21 import org
.eclipse
.linuxtools
.lttng
.jni
.exception
.JniNoSuchEventException
;
24 * <b><u>JniEvent</u></b> <p>
26 * A JniEvent has the actual content that got traced by Lttng.<br>
27 * Provides access to the LttEvent C structure in java. <p>
29 * Most important fields in the JniEvent are :
31 * <li>an event time, which is a digested timestamp.
33 * Note that the JniEvent content is not directly accessibe and should be obtained
34 * using the parseAllFields() or parseFieldBy...() methods.
37 * This class is ABSTRACT, you need to extends it to support your specific LTTng version.<p>
40 public abstract class JniEvent
extends Jni_C_Common
implements Comparable
<JniEvent
>
42 // Variables to detect if the event have been filled at least once
43 // this make possible the detection of "uninitialized" struct in Ltt
44 // Can be "EOK", "ERANGE" or "EPERM" (defined in Jni_C_Common)
45 private int eventState
= EPERM
; // Start with EPERM to ensure sanity
47 // Internal C pointer of the JniEvent used in LTT
48 private Jni_C_Pointer_And_Library_Id thisEventPtr
= new Jni_C_Pointer_And_Library_Id();
50 // Reference to the parent tracefile
51 private JniTracefile parentTracefile
= null;
53 // This map hold marker relative to the parent tracefile of this event
54 // They are "our" marker in this event
55 private HashMap
<Integer
, JniMarker
> markersMap
= null;
57 // Data we should populate from ltt
58 // Note that all type have been scaled up as there is no "unsigned" in java
59 // This might be a problem about "unsigned long" as there is no equivalent
61 private Jni_C_Pointer_And_Library_Id tracefilePtr
= new Jni_C_Pointer_And_Library_Id();
62 private JniTime eventTime
= null;
64 // These methods need a tracefile pointer, instead of a event pointer
65 protected native int ltt_readNextEvent(int libId
, long tracefilePtr
);
66 protected native int ltt_seekEvent(int libId
, long tracefilePtr
, JniTime givenTime
);
67 protected native int ltt_positionToFirstEvent(int libId
, long tracefilePtr
);
69 // Native access functions
70 protected native long ltt_getTracefilePtr(int libId
, long eventPtr
);
71 protected native long ltt_getBlock(int libId
, long eventPtr
);
72 protected native long ltt_getOffset(int libId
, long eventPtr
);
73 protected native long ltt_getCurrentTimestampCounter(int libId
, long eventPtr
);
74 protected native long ltt_getTimestamp(int libId
, long eventPtr
);
75 protected native int ltt_getEventMarkerId(int libId
, long eventPtr
);
76 protected native long ltt_getNanosencondsTime(int libId
, long eventPtr
);
77 protected native void ltt_feedEventTime(int libId
, long eventPtr
, JniTime eventTime
);
78 protected native long ltt_getEventDataSize(int libId
, long eventPtr
);
79 protected native long ltt_getEventSize(int libId
, long eventPtr
);
80 protected native int ltt_getCount(int libId
, long eventPtr
);
81 protected native long ltt_getOverflowNanoSeconds(int libId
, long eventPtr
);
83 // This method can be use to obtain the content as byte array
84 // Warning : untested!
85 protected native void ltt_getDataContent(int libId
, long eventPtr
, long dataSize
, byte[] returnedContent
);
87 // Debug native function, ask LTT to print event structure
88 protected native void ltt_printEvent(int libId
, long eventPtr
);
91 * Default constructor is forbidden
93 protected JniEvent() {
97 * Copy constructor.<p>
99 * @param oldEvent Reference to the JniEvent you want to copy.
101 public JniEvent(JniEvent oldEvent
) {
102 thisEventPtr
= oldEvent
.thisEventPtr
;
103 markersMap
= oldEvent
.markersMap
;
104 parentTracefile
= oldEvent
.parentTracefile
;
105 eventState
= oldEvent
.eventState
;
107 tracefilePtr
= oldEvent
.tracefilePtr
;
108 eventTime
= oldEvent
.eventTime
;
112 * Constructor with parameters<p>
114 * This constructor could throw. It will happen if an event can not be populated on <u>first read</u>.<br>
115 * In that case, the parent tracefile is probably useless and should be deleted.
117 * @param newEventPtr C pointer (converted in long) of the LttEvent C structure.
118 * @param newMarkersMap Reference an already populated HashMap of JniMarker objects
119 * @param newParentTracefile Reference to the parent JniTracefile of this JniEvent
121 * @exception JniException
123 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id
124 * @see org.eclipse.linuxtools.lttng.jni.JniMarker
125 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
127 public JniEvent(Jni_C_Pointer_And_Library_Id newEventPtr
, HashMap
<Integer
, JniMarker
> newMarkersMap
, JniTracefile newParentTracefile
) throws JniException
{
129 // Basic test to make sure we didn't get null/empty value
130 if ((newEventPtr
.getPointer() == NULL
)
131 || (newMarkersMap
== null)
132 || (newMarkersMap
.size() == 0)
133 || (newParentTracefile
== null)) {
134 throw new JniEventException("Null or empty value passed to constructor, object is invalid! (JniEvent)");
137 thisEventPtr
= newEventPtr
;
138 tracefilePtr
= newParentTracefile
.getTracefilePtr();
139 markersMap
= newMarkersMap
;
140 parentTracefile
= newParentTracefile
;
142 eventTime
= new JniTime();
144 // Try to move to the first event
145 // If the event is Out of Range (ERANGE) at the first read,
146 // this event type will never be usable.
147 // In that case, throw JniNoSuchEventException to warn the tracefile.
148 eventState
= positionToFirstEvent();
149 if (eventState
!= EOK
) {
150 throw new JniNoSuchEventException("Object not populated, unusable. There is probably no event of that type in the trace. (JniEvent)");
153 populateEventInformation();
158 * Move to the next event and populate the java object with LttEvent structure.<p>
160 * If the move fails, the event will not get populated and the last event data will still be available.
162 * @return LTT read status, as defined in Jni_C_Constant.
164 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Constant
166 public int readNextEvent() {
167 // Ask Ltt to read the next event for this particular tracefile
168 eventState
= ltt_readNextEvent(tracefilePtr
.getLibraryId(), tracefilePtr
.getPointer() );
169 // If the event state is sane populate it
170 if (eventState
== EOK
) {
171 populateEventInformation();
178 * Seek to a certain time.<p>
180 * Seek to a certain time and read event at this exact time or the next one if there is no event there.<p>
182 * Note that this function can seek in an invalid position if the timestamp is after the last event.<br>
183 * In that case, a seek back would be required to get back to a consistent state.<p>
185 * If the seek fails, the event will not get populated and the last event data will still be available.<p>
187 * @return LTT read status, as defined in Jni_C_Constant
189 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Constant
191 public int seekToTime(JniTime seekTime
) {
192 // Ask Ltt to read the next event for this particular tracefile
193 eventState
= ltt_seekEvent(tracefilePtr
.getLibraryId(), tracefilePtr
.getPointer(), seekTime
);
195 // If the event state is sane populate it
196 if (eventState
== EOK
) {
197 populateEventInformation();
204 * Try to seek to a certain time and seek back if it failed.<p>
206 * Seek to a certain time and read event at this exact time or the next one if there is no event there.<p>
208 * If the seek fails, we will seek back to the previous position, so the event will stay in a consistent state.<p>
210 * @return LTT read status, as defined in Jni_C_Constant
212 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Constant
214 public int seekOrFallBack(JniTime seekTime
) {
216 JniTime oldTime
= new JniTime(eventTime
);
218 // Call seek to move ahead
219 // Save the state for the return (eventState will be modified if we seek back)
220 int returnState
= seekToTime(seekTime
);
222 // If the event state is sane populate it
223 if (returnState
== EOK
) {
224 populateEventInformation();
234 * Position on the first event in the tracefile.<p>
236 * The function return the read status after the first event.<p>
238 * A status different of EOK probably means there is no event associated to this tracefile.
240 * @return LTT read status, as defined in Jni_C_Constant
242 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Constant
244 public int positionToFirstEvent() {
245 eventState
= ltt_positionToFirstEvent(tracefilePtr
.getLibraryId(), tracefilePtr
.getPointer());
251 * Obtain a marker associated with this tracefile's event.
253 * @return Reference to the marker for this tracefile's event or null if none.
255 * @see org.eclipse.linuxtools.lttng.jni.JniMarker
257 public JniMarker
requestEventMarker() {
258 return markersMap
.get(getEventMarkerId());
262 * Obtain the raw data of a LttEvent object.<p>
264 * The data will be in raw C bytes, not java bytes.<br>
265 * Note : This function is mostly untested and provided "as is".
267 * @return Bytes array of raw data (contain raw C bytes).
269 public byte[] requestEventContent() {
270 byte dataContent
[] = new byte[(int) getEventDataSize()];
272 ltt_getDataContent(thisEventPtr
.getLibraryId(), thisEventPtr
.getPointer(), getEventDataSize(), dataContent
);
278 * Obtain an event source.<p>
280 * This is not implemented yet and will always return "Kernel core" for now.
282 * @return Reference to the JniMarker object for this event or null if none.
284 * @see org.eclipse.linuxtools.lttng.jni.JniMarker
286 public String
requestEventSource() {
288 // No "Source" of event exists in Ltt so far
289 // It would be a good addition to have a way to detect where an event come
290 // from, like "kernel" or "userspace"
292 return "Kernel Core";
296 * Parse a particular field in the event payload, identified by its id (position).<p>
298 * Note : Position are relative to an event marker (i.e. requestEventMarker().getMarkerFieldsArrayList() )
300 * @param fieldId Position of the field to parse.
302 * @return Object that contain the parsed payload
304 * @see org.eclipse.linuxtools.lttng.jni.JniParser
306 public Object
parseFieldById(int fieldId
) {
307 return JniParser
.parseField(this, fieldId
);
311 * Parse a particular field in the event payload, identified by its name.<p>
313 * Note : Name are relative to an event marker (i.e. requestEventMarker().getMarkerFieldsHashMap() )
315 * @param fieldName Position of the field to parse.
317 * @return Object that contain the parsed payload
319 * @see org.eclipse.linuxtools.lttng.jni.JniParser
321 public Object
parseFieldByName(String fieldName
) {
322 return JniParser
.parseField(this, fieldName
);
326 * Method to parse all the event payload.<p>
328 * @return HashMap<String, Object> which is the parsedContent objects and their name as key.
330 * @see org.eclipse.linuxtools.lttng.jni.JniParser
332 public HashMap
<String
, Object
> parseAllFields() {
333 return JniParser
.parseAllFields(this);
337 * This function populates the event data with data from LTT
339 * NOTE : To get better performance, we copy very few data into memory here
342 private void populateEventInformation() {
343 // We need to save the time, as it is not a primitive (can't be dynamically called in getter)
344 eventTime
.setTime(ltt_getNanosencondsTime(thisEventPtr
.getLibraryId(), thisEventPtr
.getPointer()));
347 public JniTime
getEventTime() {
351 // *** To get better performance, all getter belows call LTT directly ****
352 // That way, we can avoid copying data into memory
353 public int getEventMarkerId() {
354 return ltt_getEventMarkerId(thisEventPtr
.getLibraryId(), thisEventPtr
.getPointer());
357 public long getEventDataSize() {
358 return ltt_getEventDataSize(thisEventPtr
.getLibraryId(), thisEventPtr
.getPointer());
361 public HashMap
<Integer
, JniMarker
> getMarkersMap() {
366 * Pointer to the parent LTTTracefile C structure.<br>
368 * The pointer should only be used <u>INTERNALY</u>, do not use unless you
369 * know what you are doing.
371 * @return The actual (long converted) pointer or NULL.
373 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id
375 public Jni_C_Pointer_And_Library_Id
getTracefilePtr() {
376 return new Jni_C_Pointer_And_Library_Id(thisEventPtr
.getLibraryId(), ltt_getTracefilePtr(thisEventPtr
.getLibraryId(), thisEventPtr
.getPointer()) );
380 * Pointer to the LttEvent C structure.<br>
382 * The pointer should only be used <u>INTERNALY</u>, do not use unless you
383 * know what you are doing.
385 * @return The actual (long converted) pointer or NULL.
387 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id
389 public Jni_C_Pointer_And_Library_Id
getEventPtr() {
393 public int getEventState() {
398 * Getter to the parent tracefile for this event.
400 * @return The parent tracefile
402 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
404 public JniTracefile
getParentTracefile() {
405 return parentTracefile
;
408 public boolean equals(JniEvent other
) {
410 return (this.getEventTime().equals(other
.getEventTime())
411 && this.parentTracefile
.equals(other
.parentTracefile
));
417 * Compare fonction for JNIEvent.<p>
419 * This will compare the current JNIEvent with a passed one by timestamp AND tracefile ("type").<br>
420 * If both are equal but type differs, current event is considered to be older (-1 returned).
422 * @return -1 if given event happens before, 0 if equal, 1 if passed event happens after.
425 public int compareTo(JniEvent other
) {
427 // By default, we consider the current event to be older.
428 int eventComparaison
= -1;
430 // Test against null before performing anything
432 // Compare the timestamp first
433 eventComparaison
= this.getEventTime().compareTo(other
.getEventTime());
435 // If timestamp is equal, compare the parent trace file ("event type")
436 if ((eventComparaison
== 0)
437 && (!this.parentTracefile
.equals(other
.parentTracefile
))) {
438 eventComparaison
= 1;
441 return eventComparaison
;
445 * Print information for this event.
446 * <u>Intended to debug</u><br>
448 * This function will call Ltt to print, so information printed will be
449 * the one from the C structure, not the one populated in java.<p>
451 public void printEventInformation() {
452 ltt_printEvent(thisEventPtr
.getLibraryId(), thisEventPtr
.getPointer());
457 * <u>Intended to debug.</u><p>
459 * @return Attributes of the object concatenated in String
462 @SuppressWarnings("nls")
463 public String
toString() {
464 String returnData
= "";
466 returnData
+= "tracefilePtr : " + tracefilePtr
+ "\n";
467 returnData
+= "eventMarkerId : " + getEventMarkerId() + "\n";
468 returnData
+= "eventTime : " + eventTime
.getReferenceToString() + "\n";
469 returnData
+= " seconds : " + eventTime
.getSeconds() + "\n";
470 returnData
+= " nanoSeconds : " + eventTime
.getNanoSeconds() + "\n";
471 returnData
+= "eventDataSize : " + getEventDataSize() + "\n";
472 returnData
+= "markersMap : " + markersMap
.keySet() + "\n"; // Hack to avoid ending up with markersMap.toString()