Fix for Bug354541 - TraceLibPath handling + JUnits
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.jni / src / org / eclipse / linuxtools / lttng / jni / JniTrace.java
CommitLineData
0152140d 1package org.eclipse.linuxtools.lttng.jni;
e4dc0a9a 2
0152140d 3/*******************************************************************************
a3767fd9 4 * Copyright (c) 2009, 2011 Ericsson, MontaVista Software
0152140d
ASL
5 *
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors:
12 * William Bourque (wbourque@gmail.com) - Initial API and implementation
a3767fd9 13 * Yufen Kuo (ykuo@mvista.com) - add support to allow user specify trace library path
0152140d
ASL
14 *******************************************************************************/
15
16import java.util.HashMap;
17import java.util.Iterator;
18import java.util.PriorityQueue;
19
20import org.eclipse.linuxtools.lttng.jni.common.JniTime;
c85e8cb2 21import org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id;
0152140d
ASL
22import org.eclipse.linuxtools.lttng.jni.exception.JniException;
23import org.eclipse.linuxtools.lttng.jni.exception.JniOpenTraceFailedException;
24import org.eclipse.linuxtools.lttng.jni.exception.JniTraceException;
25import org.eclipse.linuxtools.lttng.jni.exception.JniTracefileWithoutEventException;
26
27/**
28 * <b><u>JniTrace</u></b>
29 * <p>
e4dc0a9a
FC
30 * This is the top level class in the JNI. It provides access to the LttTrace C
31 * structure in java.
0152140d
ASL
32 * <p>
33 * Most important fields in the JniTrace are :
34 * <ul>
35 * <li>a JniTrace path (a trace <b>directory</b>)
36 * <li>a HashMap of tracefiles that exists in this trace
37 * </ul>
3b7509b0 38 * <p>
e4dc0a9a
FC
39 * <b>NOTE</b>
40 * <p>
41 * This class is ABSTRACT, you need to extends it to support your specific LTTng
42 * version.<br>
43 * Please look at the abstract functions to override at the bottom of this file.
44 * <p>
0152140d
ASL
45 */
46public abstract class JniTrace extends Jni_C_Common {
e4dc0a9a 47
0152140d 48 private final static boolean DEFAULT_LTT_DEBUG = false;
e4dc0a9a 49
0152140d 50 // Internal C pointer of the JniTrace used in LTT
c85e8cb2 51 private Jni_C_Pointer_And_Library_Id thisTracePtr = new Jni_C_Pointer_And_Library_Id();
0152140d
ASL
52
53 // Data we should populate from LTT
54 // Note that all type have been scaled up as there is no "unsigned" in java
55 // This might be a problem about "unsigned long" as there is no equivalent
56 // in java
e4dc0a9a 57
9c4eb5f7 58 private String tracepath = ""; // Path of the trace. Should be a directory (like : /tmp/traceX) //$NON-NLS-1$
e4dc0a9a
FC
59 private int cpuNumber = 0;
60 private long archType = 0;
61 private long archVariant = 0;
62 private short archSize = 0;
63 private short lttMajorVersion = 0;
64 private short lttMinorVersion = 0;
65 private short flightRecorder = 0;
66 private long freqScale = 0;
67 private long startFreq = 0;
68 private long startTimestampCurrentCounter = 0;
69 private long startMonotonic = 0;
0152140d
ASL
70 private JniTime startTimeNoAdjustement = null;
71 private JniTime startTime = null;
72 private JniTime endTime = null;
e4dc0a9a 73
0152140d
ASL
74 // This Map holds a reference to the tracefiles owned by this trace
75 private HashMap<String, JniTracefile> tracefilesMap = null;
e4dc0a9a 76 // The priority queue (similar to heap) hold events
0152140d 77 private PriorityQueue<JniEvent> eventsHeap = null;
e4dc0a9a 78
0152140d 79 // This variable will hold the content of the "last" event we read
e4dc0a9a
FC
80 private JniEvent currentEvent = null;
81
0152140d
ASL
82 // Should we print debug in the C library or not?
83 private boolean printLttDebug = DEFAULT_LTT_DEBUG;
e4dc0a9a 84
eb25c724 85 // flag determine if live trace is supported or not
e4dc0a9a
FC
86 // will be set to false in constructor if opening in live mode fails
87 private boolean isLiveTraceSupported = true;
a3767fd9
FC
88
89 // If traceLibPath is specified, it will be used to construct the complete path of the traceread library
90 private String traceLibPath;
e4dc0a9a 91
0152140d 92 // This need to be called prior to any operation
c85e8cb2 93 protected native int ltt_initializeHandle(String libname);
e4dc0a9a 94
0152140d 95 // This need to be called at the very end (destructor)
c85e8cb2 96 protected native boolean ltt_freeHandle(int libId);
e4dc0a9a 97
0152140d 98 // Open/close native functions
c85e8cb2 99 protected native long ltt_openTrace(int libId, String pathname, boolean printDebug);
e4dc0a9a 100
a79913eb 101 protected native long ltt_openTraceLive(int libId, String pathname, boolean printDebug);
e4dc0a9a 102
c85e8cb2 103 protected native void ltt_closeTrace(int libId, long tracePtr);
0152140d
ASL
104
105 // Native access functions
c85e8cb2 106 protected native String ltt_getTracepath(int libId, long tracePtr);
e4dc0a9a
FC
107
108 protected native int ltt_getCpuNumber(int libId, long tracePtr);
109
110 protected native long ltt_getArchType(int libId, long tracePtr);
111
112 protected native long ltt_getArchVariant(int libId, long tracePtr);
113
114 protected native short ltt_getArchSize(int libId, long tracePtr);
115
116 protected native short ltt_getLttMajorVersion(int libId, long tracePtr);
117
118 protected native short ltt_getLttMinorVersion(int libId, long tracePtr);
119
120 protected native short ltt_getFlightRecorder(int libId, long tracePtr);
121
122 protected native long ltt_getFreqScale(int libId, long tracePtr);
123
124 protected native long ltt_getStartFreq(int libId, long tracePtr);
125
126 protected native long ltt_getStartTimestampCurrentCounter(int libId, long tracePtr);
127
128 protected native long ltt_getStartMonotonic(int libId, long tracePtr);
129
a79913eb
FC
130 // Native function to update trace file and file size information
131 protected native int ltt_updateTrace(int libId, long tracePtr);
e4dc0a9a 132
0152140d 133 // Native function to fill out startTime
c85e8cb2 134 protected native void ltt_feedStartTime(int libId, long tracePtr, JniTime startTime);
e4dc0a9a 135
0152140d 136 // Native function to fill out startTimeFromTimestampCurrentCounter
c85e8cb2 137 protected native void ltt_feedStartTimeFromTimestampCurrentCounter(int libId, long tracePtr, JniTime startTime);
0152140d
ASL
138
139 // Native function to fill out tracefilesMap
c85e8cb2 140 protected native void ltt_feedAllTracefiles(int libId, long tracePtr);
e4dc0a9a 141
0152140d 142 // Native function to fill out the start and end time of the trace
c85e8cb2 143 protected native void ltt_feedTracefileTimeRange(int libId, long tracePtr, JniTime startTime, JniTime endTime);
e4dc0a9a 144
0152140d 145 // Debug native function, ask LTT to print trace structure
c85e8cb2 146 protected native void ltt_printTrace(int libId, long tracePtr);
e4dc0a9a 147
0152140d
ASL
148 /*
149 * Default constructor is forbidden
150 */
151 protected JniTrace() {
152 }
e4dc0a9a 153
0152140d 154 /**
e4dc0a9a
FC
155 * Constructor that takes a tracepath parameter.
156 * <p>
0152140d
ASL
157 *
158 * This constructor also opens the trace.
159 *
160 * @param newpath The <b>directory</b> of the trace to be opened
161 *
162 * @exception JniException
163 */
164 public JniTrace(String newpath) throws JniException {
165 this(newpath, DEFAULT_LTT_DEBUG);
166 }
e4dc0a9a 167
0152140d 168 /**
e4dc0a9a
FC
169 * Constructor that takes a tracepath parameter and a debug value.
170 * <p>
0152140d
ASL
171 *
172 * This constructor also opens the trace.
173 *
174 * @param newpath The <b>directory</b> of the trace to be opened
e4dc0a9a
FC
175 * @param newPrintDebug Should the debug information be printed in the LTT C
176 * library
0152140d
ASL
177 *
178 * @exception JniException
179 */
180 public JniTrace(String newpath, boolean newPrintDebug) throws JniException {
181 tracepath = newpath;
c85e8cb2 182 thisTracePtr = new Jni_C_Pointer_And_Library_Id();
0152140d 183 printLttDebug = newPrintDebug;
0152140d 184 }
e4dc0a9a 185
0152140d
ASL
186 /**
187 * Copy constructor.
188 *
e4dc0a9a 189 * @param oldTrace A reference to the JniTrace to copy.
0152140d
ASL
190 */
191 public JniTrace(JniTrace oldTrace) {
e4dc0a9a
FC
192 thisTracePtr = oldTrace.thisTracePtr;
193
194 tracepath = oldTrace.tracepath;
195 cpuNumber = oldTrace.cpuNumber;
196 archType = oldTrace.archType;
197 archVariant = oldTrace.archVariant;
198 archSize = oldTrace.archSize;
0152140d
ASL
199 lttMajorVersion = oldTrace.lttMajorVersion;
200 lttMinorVersion = oldTrace.lttMinorVersion;
e4dc0a9a
FC
201 flightRecorder = oldTrace.flightRecorder;
202 freqScale = oldTrace.freqScale;
203 startFreq = oldTrace.startFreq;
0152140d 204 startTimestampCurrentCounter = oldTrace.startTimestampCurrentCounter;
e4dc0a9a 205 startMonotonic = oldTrace.startMonotonic;
0152140d 206 startTimeNoAdjustement = oldTrace.startTimeNoAdjustement;
e4dc0a9a
FC
207 startTime = oldTrace.startTime;
208 endTime = oldTrace.endTime;
0152140d
ASL
209
210 tracefilesMap = new HashMap<String, JniTracefile>(oldTrace.tracefilesMap.size());
e0ea56dd 211 ltt_feedAllTracefiles(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
e4dc0a9a
FC
212
213 eventsHeap = new PriorityQueue<JniEvent>(oldTrace.eventsHeap.size());
e0ea56dd 214 populateEventHeap();
e4dc0a9a 215
0152140d 216 printLttDebug = oldTrace.printLttDebug;
e4dc0a9a
FC
217 }
218
0152140d 219 /**
e4dc0a9a
FC
220 * Constructor, using C pointer.
221 * <p>
0152140d
ASL
222 *
223 * @param newPtr The pointer to an already opened LttTrace C structure.
e4dc0a9a
FC
224 * @param newPrintDebug Should the debug information be printed in the LTT C
225 * library
226 *
0152140d
ASL
227 * @exception JniException
228 *
c85e8cb2 229 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id
0152140d 230 */
c85e8cb2 231 public JniTrace(Jni_C_Pointer_And_Library_Id newPtr, boolean newPrintDebug) throws JniException {
0152140d
ASL
232 thisTracePtr = newPtr;
233 printLttDebug = newPrintDebug;
e4dc0a9a 234
0152140d
ASL
235 // Populate our trace
236 populateTraceInformation();
237 }
e4dc0a9a 238
b9fb2d51 239 @Override
e4dc0a9a
FC
240 public void finalize() {
241 // If the trace is open, close it
0152140d
ASL
242 if (thisTracePtr.getPointer() != NULL) {
243 closeTrace();
244 }
e4dc0a9a 245
687cc7e7 246 // Tell the C to free the allocated memory
0152140d
ASL
247 freeLibrary();
248 }
e4dc0a9a 249
0152140d 250 /**
e4dc0a9a
FC
251 * Open an existing trace.
252 * <p>
0152140d 253 *
e4dc0a9a
FC
254 * The tracepath is a directory and needs to exist, otherwise a
255 * JniOpenTraceFailedException is throwed.
0152140d
ASL
256 *
257 * @param newPath The <b>directory</b> of the trace to be opened
258 *
259 * @exception JniOpenTraceFailedException Thrown if the open failed
260 */
261 public void openTrace(String newPath) throws JniException {
e4dc0a9a
FC
262 // If open is called while a trace is already opened, we will try to
263 // close it first
0152140d
ASL
264 if (thisTracePtr.getPointer() != NULL) {
265 closeTrace();
266 }
267
268 // Set the tracepath and open it
269 tracepath = newPath;
270 openTrace();
271 }
e4dc0a9a 272
0152140d 273 /**
e4dc0a9a
FC
274 * Open an existing trace.
275 * <p>
0152140d
ASL
276 *
277 * The tracepath should have been set already,
278 *
e4dc0a9a 279 * @exception JniOpenTraceFailedException Thrown if the open failed
0152140d
ASL
280 */
281 public void openTrace() throws JniException {
e4dc0a9a
FC
282
283 // Raise an exception if the tracepath is empty, otherwise open the
284 // trace
9c4eb5f7
FC
285 if (tracepath == "") { //$NON-NLS-1$
286 throw new JniTraceException("Tracepath is not set. (openTrace)"); //$NON-NLS-1$
0152140d 287 }
e4dc0a9a 288
0152140d
ASL
289 // If the file is already opened, close it first
290 if (thisTracePtr.getPointer() != NULL) {
291 closeTrace();
292 }
e4dc0a9a 293
c85e8cb2
WB
294 // Initialization of the library is made here
295 // It is very important that the id is kept!
296 int newLibraryId = initializeLibrary();
e4dc0a9a
FC
297 if (newLibraryId != -1) {
298 // Call the LTT to open the trace
299 // Note that the libraryId is not yet and the pointer
300 long newPtr = NULL;
301
302 try {
303 newPtr = ltt_openTraceLive(newLibraryId, tracepath, printLttDebug);
304 } catch (UnsatisfiedLinkError e) {
305 }
306
307 if (newPtr == NULL) {
308 // JNI library doesn't support live trace read. Set flag for
309 // live trace support to false and
310 // open trace in offline mode.
311 isLiveTraceSupported = false;
312 newPtr = ltt_openTrace(newLibraryId, tracepath, printLttDebug);
313 }
314
315 if (newPtr == NULL) {
316 thisTracePtr = new Jni_C_Pointer_And_Library_Id();
317 throw new JniOpenTraceFailedException("Error while opening trace. Is the tracepath correct? (openTrace)"); //$NON-NLS-1$
318 }
319
320 // This is OUR pointer
321 thisTracePtr = new Jni_C_Pointer_And_Library_Id(newLibraryId, newPtr);
322
323 // Populate the trace with LTT information
324 populateTraceInformation();
325 } else {
326 thisTracePtr = new Jni_C_Pointer_And_Library_Id();
327 throw new JniTraceException("Failed to initialize library! Is the trace version supported?\n" + //$NON-NLS-1$
328 "Make sure you have the correct LTTv library compiled. (openTrace)"); //$NON-NLS-1$
0152140d
ASL
329 }
330 }
e4dc0a9a 331
0152140d 332 /**
e4dc0a9a
FC
333 * Close a trace.
334 * <p>
0152140d
ASL
335 *
336 * If the trace is already closed, will silently do nothing.
337 */
338 public void closeTrace() {
e4dc0a9a 339
0152140d 340 if (thisTracePtr.getPointer() != NULL) {
c85e8cb2 341 ltt_closeTrace(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
e4dc0a9a 342
0152140d
ASL
343 // Clear the tracefile map
344 tracefilesMap.clear();
345 tracefilesMap = null;
e4dc0a9a 346
0152140d
ASL
347 // Clear the eventsHeap and make it points to null
348 eventsHeap.clear();
349 eventsHeap = null;
e4dc0a9a 350
0152140d 351 // Nullify the pointer
c85e8cb2 352 thisTracePtr = new Jni_C_Pointer_And_Library_Id();
0152140d
ASL
353 }
354 }
e4dc0a9a 355
0152140d 356 /**
e4dc0a9a
FC
357 * This function force the library to free its memory.
358 * <p>
0152140d 359 *
e4dc0a9a
FC
360 * Note : No call to the library will work after this until
361 * ltt_initializeHandle is called again
0152140d
ASL
362 */
363 public void freeLibrary() {
e4dc0a9a 364 ltt_freeHandle(thisTracePtr.getLibraryId());
0152140d 365 }
e4dc0a9a
FC
366
367 /*
0152140d
ASL
368 * This function populates the trace data with data from LTT
369 *
370 * @throws JniException
371 */
372 private void populateTraceInformation() throws JniException {
373 if (thisTracePtr.getPointer() == NULL) {
9c4eb5f7 374 throw new JniTraceException("Pointer is NULL, trace not opened/already closed? (populateTraceInformation)"); //$NON-NLS-1$
0152140d
ASL
375 }
376
377 // Populate from the LTT library
e4dc0a9a
FC
378 tracepath = ltt_getTracepath(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
379 cpuNumber = ltt_getCpuNumber(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
380 archType = ltt_getArchType(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
c85e8cb2 381 archVariant = ltt_getArchVariant(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
e4dc0a9a 382 archSize = ltt_getArchSize(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
c85e8cb2
WB
383 lttMajorVersion = ltt_getLttMajorVersion(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
384 lttMinorVersion = ltt_getLttMinorVersion(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
e4dc0a9a
FC
385 flightRecorder = ltt_getFlightRecorder(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
386 freqScale = ltt_getFreqScale(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
387 startFreq = ltt_getStartFreq(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
c85e8cb2
WB
388 startTimestampCurrentCounter = ltt_getStartTimestampCurrentCounter(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
389 startMonotonic = ltt_getStartMonotonic(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
0152140d 390
e4dc0a9a
FC
391 // Creation of time is a bit different, we need to pass the object
392 // reference to C
0152140d 393 //
e4dc0a9a
FC
394 // *** NOTE : LTTv consider "raw startTime" (time without any frequency
395 // adjustement) to be default startTime
396 // So "startTimeNoAdjustement" is obtain throught "ltt_feedStartTime()"
397 // and
398 // "startTime" is obtained from
399 // ltt_feedStartTimeFromTimestampCurrentCounter()
0152140d 400 startTimeNoAdjustement = new JniTime();
c85e8cb2 401 ltt_feedStartTime(thisTracePtr.getLibraryId(), thisTracePtr.getPointer(), startTimeNoAdjustement);
e4dc0a9a 402
0152140d 403 startTime = new JniTime();
c85e8cb2 404 ltt_feedStartTimeFromTimestampCurrentCounter(thisTracePtr.getLibraryId(), thisTracePtr.getPointer(), startTime);
0152140d
ASL
405
406 // Call the fill up function for the tracefiles map
e4dc0a9a 407 if (tracefilesMap == null) {
0152140d
ASL
408 tracefilesMap = new HashMap<String, JniTracefile>();
409 }
c85e8cb2 410 ltt_feedAllTracefiles(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
e4dc0a9a 411
0152140d
ASL
412 // Now, obtain the trace "endTime"
413 // Note that we discard "startTime" right away, as we already have it
414 endTime = new JniTime();
c85e8cb2 415 ltt_feedTracefileTimeRange(thisTracePtr.getLibraryId(), thisTracePtr.getPointer(), new JniTime(), endTime);
e4dc0a9a 416
0152140d
ASL
417 if (eventsHeap == null) {
418 eventsHeap = new PriorityQueue<JniEvent>(tracefilesMap.size());
419 }
e4dc0a9a 420
0152140d
ASL
421 // Populate the heap with events
422 populateEventHeap();
423 }
e4dc0a9a
FC
424
425 /*
0152140d
ASL
426 * This function populates the event heap with one event from each tracefile
427 * It should be called after each seek or when the object is constructed
428 */
429 private void populateEventHeap() {
430 currentEvent = null;
431 eventsHeap.clear();
e4dc0a9a 432
0152140d
ASL
433 Object new_key = null;
434 JniTracefile tmpTracefile = null;
e4dc0a9a 435
0152140d 436 Iterator<String> iterator = tracefilesMap.keySet().iterator();
e4dc0a9a 437 while (iterator.hasNext()) {
0152140d 438 new_key = iterator.next();
e4dc0a9a 439
0152140d 440 tmpTracefile = tracefilesMap.get(new_key);
e4dc0a9a
FC
441 if (tmpTracefile.getCurrentEvent().getEventState() == EOK) {
442 eventsHeap.add(tmpTracefile.getCurrentEvent());
0152140d
ASL
443 }
444 }
445 }
e4dc0a9a
FC
446
447 /*
0152140d
ASL
448 * Fills a map of all the trace files.
449 *
450 * Note: This function is called from C and there is no way to propagate
451 * exception back to the caller without crashing JNI. Therefore, it MUST
452 * catch all exceptions.
453 *
454 * @param tracefileName
e4dc0a9a 455 *
0152140d
ASL
456 * @param tracefilePtr
457 */
458 protected void addTracefileFromC(String tracefileName, long tracefilePtr) {
e4dc0a9a 459
0152140d 460 JniTracefile newTracefile = null;
e4dc0a9a 461
0152140d 462 // Create a new tracefile object and insert it in the map
e4dc0a9a 463 // the tracefile fill itself with LTT data while being constructed
0152140d 464 try {
c85e8cb2 465 newTracefile = allocateNewJniTracefile(new Jni_C_Pointer_And_Library_Id(thisTracePtr.getLibraryId(), tracefilePtr), this);
e4dc0a9a
FC
466 getTracefilesMap().put((tracefileName + newTracefile.getCpuNumber()), newTracefile);
467 } catch (JniTracefileWithoutEventException e) {
468 if (printLttDebug == true) {
469 printlnC(thisTracePtr.getLibraryId(), "JniTracefile " + tracefileName + " has no event (addTracefileFromC). Ignoring."); //$NON-NLS-1$ //$NON-NLS-2$
470 }
471 } catch (Exception e) {
472 if (printLttDebug == true) {
473 printlnC(thisTracePtr.getLibraryId(),
474 "Failed to add tracefile " + tracefileName + " to tracefilesMap!(addTracefileFromC)\n\tException raised : " + e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
475 }
0152140d
ASL
476 }
477 }
e4dc0a9a 478
0152140d 479 /**
e4dc0a9a
FC
480 * Return the top event in the events stack, determined by timestamp, in the
481 * trace (all the tracefiles).
482 * <p>
0152140d 483 *
e4dc0a9a
FC
484 * Note : If the events were read before, the top event and the event
485 * currently loaded (currentEvent) are most likely the same.
0152140d
ASL
486 *
487 * @return The top event in the stack or null if no event is available.
488 *
c357e4b6 489 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
0152140d
ASL
490 */
491 public JniEvent findNextEvent() {
492 return eventsHeap.peek();
493 }
e4dc0a9a 494
0152140d 495 /**
e4dc0a9a
FC
496 * Return the next event in the events stack, determined by timestamp, in
497 * the trace (all the tracefiles).
498 * <p>
0152140d
ASL
499 *
500 * @return The next event in the trace or null if no event is available.
501 *
c357e4b6 502 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
0152140d
ASL
503 */
504 public JniEvent readNextEvent() {
505 // Get the "next" event on the top of the heap but DO NOT remove it
506 JniEvent tmpEvent = eventsHeap.peek();
e4dc0a9a
FC
507
508 // If the event is null, it was the last one in the trace we can leave
509 // the function
0152140d
ASL
510 if (tmpEvent == null) {
511 return null;
512 }
e4dc0a9a
FC
513
514 // Otherwise, we need to make sure the timestamp of the event we got is
515 // not the same as the last "NextEvent" we requested
516 // NOTE : JniEvent.compareTo() compare by timestamp AND type, as 2
517 // events of different type could have the same timestamp.
64fe8e8a
FC
518// if( currentEvent != null ){
519 if (tmpEvent.equals(currentEvent)) {
0152140d
ASL
520 // Remove the event on top as it is the same currentEventTimestamp
521 eventsHeap.poll();
e4dc0a9a 522
0152140d
ASL
523 // Read the next event for this particular event type
524 tmpEvent.readNextEvent();
e4dc0a9a
FC
525
526 // If the event state is sane (not Out of Range), put it back in the
527 // heap
528 if (tmpEvent.getEventState() == EOK) {
0152140d
ASL
529 eventsHeap.add(tmpEvent);
530 }
e4dc0a9a 531
0152140d
ASL
532 // Pick the top event again
533 tmpEvent = eventsHeap.peek();
e4dc0a9a 534
0152140d
ASL
535 // Save the event we just read as the "current event"
536 currentEvent = tmpEvent;
537 }
e4dc0a9a
FC
538 // If the event on top has different timestamp than the
539 // currentTimestamp, just save this timestamp as current
0152140d
ASL
540 else {
541 currentEvent = tmpEvent;
542 }
e4dc0a9a 543
0152140d
ASL
544 return tmpEvent;
545 }
e4dc0a9a 546
0152140d 547 /**
e4dc0a9a
FC
548 * Read the next event on a certain tracefile.
549 * <p>
0152140d 550 *
e4dc0a9a
FC
551 * By calling this function make sure the "global" readNextEvent() stay
552 * synchronised. Calling readNextEvent() after this function will consider
553 * this tracefile moved and is then consistent.
0152140d 554 *
e4dc0a9a 555 * @param targetTracefile The tracefile object to read from
0152140d
ASL
556 *
557 * @return The next event in the tracefile or null if no event is available.
558 *
c357e4b6
WB
559 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
560 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
0152140d
ASL
561 */
562 public JniEvent readNextEvent(JniTracefile targetTracefile) {
563 JniEvent returnedEvent = null;
e4dc0a9a
FC
564
565 // There is 2 special cases where we should read the CURRENT event, not
566 // the next one
567 // 1- The currentEvent is null --> We never read or we just seeked
568 // 2- The currentEvent is of another type --> We last read on a
569 // DIFFERENT tracefile
570 if ((currentEvent == null) || (currentEvent.getParentTracefile().equals(targetTracefile) == false)) {
0152140d
ASL
571 returnedEvent = targetTracefile.getCurrentEvent();
572 // Save the event we read
e4dc0a9a
FC
573 currentEvent = returnedEvent;
574 } else {
575 // Remove from the event related to this tracefile from the event
576 // heap, if it exists.
577 // WARNING : This only safe as long getCurrentEvent() never return
578 // "null" in any case.
579 eventsHeap.remove(targetTracefile.getCurrentEvent());
580
581 // If status EOK, we can return the event, otherwise something wrong
582 // happen (out of range, read error, etc...)
583 if (targetTracefile.readNextEvent() == EOK) {
584 returnedEvent = targetTracefile.getCurrentEvent();
585 // Add back to the heap the read event
586 eventsHeap.add(returnedEvent);
587 }
588 // Save the event we read...
589 // Note : might be null if the read failed and it's ok
590 currentEvent = targetTracefile.getCurrentEvent();
0152140d 591 }
e4dc0a9a
FC
592
593 return returnedEvent;
0152140d 594 }
e4dc0a9a 595
0152140d 596 /**
e4dc0a9a
FC
597 * Seek to a certain time but <b>do not</b> read the next event.
598 * <p>
599 *
600 * This only position the trace, it will not return anything.
601 * <p>
602 *
603 * @param seekTime The time where we want to seek to
604 *
605 * @see org.eclipse.linuxtools.lttng.jni.common.JniTime
606 */
0152140d 607 public void seekToTime(JniTime seekTime) {
e4dc0a9a 608
0152140d
ASL
609 // Invalidate the last read event
610 currentEvent = null;
e4dc0a9a 611
0152140d 612 Object tracefile_name = null;
e4dc0a9a
FC
613 Iterator<String> iterator = tracefilesMap.keySet().iterator();
614
615 while (iterator.hasNext()) {
616 // We seek to the given event for ALL tracefiles
617 tracefile_name = iterator.next();
618 seekToTime(seekTime, tracefilesMap.get(tracefile_name));
619 }
620
621 populateEventHeap();
622 }
623
0152140d 624 /**
e4dc0a9a
FC
625 * Seek to a certain time on a certain tracefile but <b>do not</b> read the
626 * next event.
627 * <p>
628 *
629 * This only position the trace, it will not return anything.
630 * <p>
631 *
632 * @param targetTracefile The tracefile object to read from
633 * @param seekTime The time where we want to seek to
634 *
635 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
636 * @see org.eclipse.linuxtools.lttng.jni.common.JniTime
637 */
0152140d
ASL
638 public void seekToTime(JniTime seekTime, JniTracefile targetTracefile) {
639 // Invalidate the current read event
640 currentEvent = null;
e4dc0a9a
FC
641
642 // Remove from the event related to this tracefile from the event heap,
643 // if it exists.
644 // WARNING : This is only safe as long getCurrentEvent() never return
645 // "null" in any case.
646 eventsHeap.remove(targetTracefile.getCurrentEvent());
647
0152140d
ASL
648 // Perform the actual seek on the tracefile
649 // Add the event to the heap if it succeed
e4dc0a9a
FC
650 if (targetTracefile.seekToTime(seekTime) == EOK) {
651 // Add back to the heap the read event
0152140d
ASL
652 eventsHeap.add(targetTracefile.getCurrentEvent());
653 }
654 }
e4dc0a9a 655
0152140d 656 /**
e4dc0a9a
FC
657 * Seek to a certain timestamp and read the next event.
658 * <p>
659 * If no more events are available or an error happen, null will be
660 * returned.
661 *
662 * @param seekTime The time where we want to seek to.
663 *
664 * @return The event just after the seeked time or null if none available.
665 *
666 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
667 * @see org.eclipse.linuxtools.lttng.jni.common.JniTime
668 */
669 public JniEvent seekAndRead(JniTime seekTime) {
670 JniEvent returnedEvent = null;
671 seekToTime(seekTime);
672
673 // The trace should be correctly positionned, let's get the event
674 returnedEvent = readNextEvent();
675
676 return returnedEvent;
677 }
678
0152140d 679 /**
e4dc0a9a
FC
680 * Seek to a certain timestamp on a certain tracefile and read the next
681 * event.
682 * <p>
683 *
684 * If no more events are available or an error happen, null will be
685 * returned.
686 *
687 * Calling readNextEvent() after this function will consider this tracefile
688 * moved and is then consistent.<br>
689 *
690 * @param targetTracefile The tracefile object to read from
691 * @param seekTime The time where we want to seek to
692 *
693 * @return The event just after the seeked time or null if none available.
694 *
695 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
696 * @see org.eclipse.linuxtools.lttng.jni.common.JniTime
697 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
698 */
699 public JniEvent seekAndRead(JniTime seekTime, JniTracefile targetTracefile) {
0152140d
ASL
700 seekToTime(seekTime, targetTracefile);
701 return readNextEvent(targetTracefile);
702 }
e4dc0a9a 703
0152140d 704 /**
e4dc0a9a
FC
705 * Get a certain tracefile from its given name.
706 * <p>
0152140d 707 *
e4dc0a9a 708 * @param tracefileName The name of the tracefile.
0152140d
ASL
709 *
710 * @return The tracefile found or null if none.
711 *
c357e4b6 712 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
0152140d
ASL
713 */
714 public JniTracefile requestTracefileByName(String tracefileName) {
715 return tracefilesMap.get(tracefileName);
e4dc0a9a
FC
716 }
717
0152140d 718 /**
e4dc0a9a
FC
719 * Get a certain event associated to a tracefile from the tracefile name.
720 * <p>
0152140d 721 *
e4dc0a9a 722 * @param tracefileName The name of the trace file.
0152140d
ASL
723 *
724 * @return Event of the tracefile or null if none found.
725 *
c357e4b6 726 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
0152140d
ASL
727 */
728 public JniEvent requestEventByName(String tracefileName) {
729 JniEvent returnValue = null;
730
731 JniTracefile tmpTracefile = tracefilesMap.get(tracefileName);
732
733 // If the tracefile is found, return the current event
734 // There should always be an event linked to a tracefile
735 if (tmpTracefile != null) {
736 returnValue = tmpTracefile.getCurrentEvent();
737 }
738
739 return returnValue;
e4dc0a9a
FC
740 }
741
0152140d
ASL
742 // Access to class variable. Most of them doesn't have setter
743 public String getTracepath() {
744 return tracepath;
745 }
746
747 public int getCpuNumber() {
748 return cpuNumber;
749 }
750
751 public long getArchType() {
752 return archType;
753 }
754
755 public long getArchVariant() {
756 return archVariant;
757 }
758
759 public short getArchSize() {
760 return archSize;
761 }
762
763 public short getLttMajorVersion() {
764 return lttMajorVersion;
765 }
766
767 public short getLttMinorVersion() {
768 return lttMinorVersion;
769 }
770
771 public short getFlightRecorder() {
772 return flightRecorder;
773 }
774
775 public long getFreqScale() {
776 return freqScale;
777 }
778
779 public long getStartFreq() {
780 return startFreq;
781 }
782
783 public long getStartTimestampCurrentCounter() {
784 return startTimestampCurrentCounter;
785 }
786
787 public long getStartMonotonic() {
788 return startMonotonic;
789 }
790
a79913eb 791 /**
e4dc0a9a
FC
792 * Update trace file and file size information.
793 * <p>
a79913eb
FC
794 *
795 * If the trace has any new events, fetch the new end time.
796 */
797 public void updateTrace() {
798 if (thisTracePtr.getPointer() != NULL && isLiveTraceSupported()) {
799 int numUpdated = ltt_updateTrace(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
800 if (numUpdated > 0) {
801 ltt_feedTracefileTimeRange(thisTracePtr.getLibraryId(), thisTracePtr.getPointer(), new JniTime(), endTime);
802 }
803 }
804 }
e4dc0a9a 805
0152140d
ASL
806 public JniTime getStartTime() {
807 return startTime;
808 }
e4dc0a9a 809
0152140d
ASL
810 public JniTime getEndTime() {
811 return endTime;
812 }
813
814 public JniTime getStartTimeNoAdjustement() {
815 return startTimeNoAdjustement;
816 }
e4dc0a9a 817
0152140d
ASL
818 public HashMap<String, JniTracefile> getTracefilesMap() {
819 return tracefilesMap;
e4dc0a9a
FC
820 }
821
0152140d 822 /**
e4dc0a9a
FC
823 * The timestamp of the last read event.
824 * <p>
0152140d
ASL
825 *
826 * Note : If no event is available, Long.MAX_VALUE is returned.
827 *
828 * @return Time of the last event read
829 *
c357e4b6 830 * @see org.eclipse.linuxtools.lttng.jni.common.JniTime
0152140d
ASL
831 */
832 public JniTime getCurrentEventTimestamp() {
833 JniTime returnedTime = null;
e4dc0a9a
FC
834
835 // If no event were read or we reach the last event in the trace,
836 // currentEvent will be null
837 if (currentEvent != null) {
0152140d 838 returnedTime = currentEvent.getEventTime();
e4dc0a9a 839 } else {
0152140d
ASL
840 returnedTime = new JniTime(Long.MAX_VALUE);
841 }
842 return returnedTime;
843 }
e4dc0a9a 844
0152140d 845 /**
e4dc0a9a
FC
846 * Pointer to the LttTrace C structure.
847 * <p>
0152140d
ASL
848 *
849 * The pointer should only be used <u>INTERNALY</u>, do not use unless you
850 * know what you are doing.
851 *
852 * @return The actual (long converted) pointer or NULL.
853 *
c85e8cb2 854 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id
0152140d 855 */
c85e8cb2 856 public Jni_C_Pointer_And_Library_Id getTracePtr() {
0152140d 857 return thisTracePtr;
e4dc0a9a 858 }
a79913eb
FC
859
860 /**
861 * Indicate whether a trace can be opened in live mode.
a79913eb
FC
862 *
863 * @return true if the trace version supports live
864 */
865 public boolean isLiveTraceSupported() {
eb25c724
BH
866 return isLiveTraceSupported;
867 }
e4dc0a9a 868
0152140d 869 /**
e4dc0a9a
FC
870 * Return boolean value saying if the debug is enabled in LTT or not.
871 * <p>
0152140d
ASL
872 *
873 * Note : this need to be set at construction.
874 *
875 * @return If the debug is set or not
876 */
877 public boolean isPrintingLttDebug() {
878 return printLttDebug;
879 }
e4dc0a9a 880
0152140d
ASL
881 /**
882 * Print information for all the tracefiles associated with this trace.
e4dc0a9a
FC
883 * <u>Intended to debug</u>
884 * <p>
0152140d
ASL
885 *
886 * This function will call Ltt to print, so information printed will be the
887 * one from the C structure, not the one populated in java.
888 *
c357e4b6 889 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
0152140d
ASL
890 */
891 public void printAllTracefilesInformation() {
892 JniTracefile tracefile = null;
893
894 Iterator<String> iterator = tracefilesMap.keySet().iterator();
895 while (iterator.hasNext()) {
896 tracefile = tracefilesMap.get(iterator.next());
897 tracefile.printTracefileInformation();
898 }
e4dc0a9a
FC
899 }
900
0152140d 901 /**
e4dc0a9a
FC
902 * Print information for this trace. <u>Intended to debug</u>
903 * <p>
0152140d
ASL
904 *
905 * This function will call Ltt to print, so information printed will be the
e4dc0a9a
FC
906 * one from the C structure, not the one populated in java.
907 * <p>
0152140d
ASL
908 */
909 public void printTraceInformation() {
c85e8cb2 910 ltt_printTrace(thisTracePtr.getLibraryId(), thisTracePtr.getPointer());
0152140d 911 }
e4dc0a9a 912
0152140d 913 /**
e4dc0a9a 914 * toString() method. <u>Intended to debug</u><br>
0152140d
ASL
915 *
916 * @return Attributes of the object concatenated in String
917 */
918 @Override
3b38ea61 919 @SuppressWarnings("nls")
e4dc0a9a 920 public String toString() {
0152140d
ASL
921 String returnData = "";
922 returnData += "tracepath : " + tracepath + "\n";
923 returnData += "cpuNumber : " + cpuNumber + "\n";
924 returnData += "archType : " + archType + "\n";
925 returnData += "archVariant : " + archVariant + "\n";
926 returnData += "archSize : " + archSize + "\n";
927 returnData += "lttMajorVersion : " + lttMajorVersion + "\n";
928 returnData += "lttMinorVersion : " + lttMinorVersion + "\n";
929 returnData += "flightRecorder : " + flightRecorder + "\n";
930 returnData += "freqScale : " + freqScale + "\n";
931 returnData += "startFreq : " + startFreq + "\n";
932 returnData += "startTimestampCurrentCounter : " + startTimestampCurrentCounter + "\n";
933 returnData += "startMonotonic : " + startMonotonic + "\n";
934 returnData += "startTimeNoAdjustement : " + startTimeNoAdjustement.getReferenceToString() + "\n";
935 returnData += " seconds : " + startTimeNoAdjustement.getSeconds() + "\n";
936 returnData += " nanoSeconds : " + startTimeNoAdjustement.getNanoSeconds() + "\n";
937 returnData += "startTime : " + startTime.getReferenceToString() + "\n";
938 returnData += " seconds : " + startTime.getSeconds() + "\n";
939 returnData += " nanoSeconds : " + startTime.getNanoSeconds() + "\n";
940 returnData += "endTime : " + endTime.getReferenceToString() + "\n";
941 returnData += " seconds : " + endTime.getSeconds() + "\n";
942 returnData += " nanoSeconds : " + endTime.getNanoSeconds() + "\n";
e4dc0a9a
FC
943 returnData += "tracefilesMap : " + tracefilesMap.keySet() + "\n"; // Hack
944 // to
945 // avoid
946 // ending
947 // up
948 // with
949 // tracefilesMap.toString()
0152140d
ASL
950
951 return returnData;
952 }
e4dc0a9a 953
c357e4b6
WB
954 // ****************************
955 // **** ABSTRACT FUNCTIONS ****
956 // You MUST override those in your version specific implementation
e4dc0a9a 957
c357e4b6 958 /**
e4dc0a9a
FC
959 * Function place holder to load the correct C library.
960 * <p>
c357e4b6 961 * <br>
e4dc0a9a
FC
962 * Can be as simple as calling ltt_initializeHandle(LIBRARY_NAME) with the
963 * correct .so instead of LIBRARY_NAME.<br>
c357e4b6
WB
964 * You may also want to perform some check or some additionnal validations.<br>
965 * <br>
966 * <b>!! Override this with you version specific implementation.</b><br>
967 *
e4dc0a9a
FC
968 * @return integer that is the library id, or -1 if the load was
969 * unsuccessful
c357e4b6 970 */
c85e8cb2 971 public abstract int initializeLibrary();
e4dc0a9a 972
c357e4b6 973 /**
e4dc0a9a
FC
974 * Function place holder to allocate a new JniTracefile.
975 * <p>
c357e4b6 976 *
e4dc0a9a
FC
977 * JniTracefile constructor is non overridable so we need another
978 * overridable function to return the correct version of JniTracefile.<br>
979 * Effect of this function should be the same (allocate a fresh new
980 * JniTracefile)<br>
c357e4b6
WB
981 * <br>
982 * <b>!! Override this with you version specific implementation.</b><br>
983 *
e4dc0a9a
FC
984 * @param newPtr The pointer of an already opened LttTracefile C Structure
985 * @param newParentTrace The JniTrace parent of this tracefile.
c357e4b6 986 *
e4dc0a9a 987 * @return The newly allocated JniTracefile of the correct version
c357e4b6 988 *
e4dc0a9a 989 * @throws JniException The construction (allocation) failed.
c357e4b6
WB
990 *
991 * @see org.eclipse.linuxtools.lttng.jni.JniTracefile
c85e8cb2 992 * @see org.eclipse.linuxtools.lttng.jni.common.Jni_C_Pointer_And_Library_Id
c357e4b6
WB
993 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
994 */
c85e8cb2 995 public abstract JniTracefile allocateNewJniTracefile(Jni_C_Pointer_And_Library_Id newPtr, JniTrace newParentTrace) throws JniException;
e4dc0a9a 996
a3767fd9
FC
997 /**
998 * Function set trace library path
999 * @param traceLibPath Path to a <b>directory</b> that contain LTTng trace libraries
1000 */
1001 public void setTraceLibPath(String traceLibPath) {
1002 this.traceLibPath = traceLibPath;
1003 }
1004
1005 /**
1006 * Function to get trace library path
1007 * @return Path to a <b>directory</b> that contain LTTng trace libraries
1008 */
1009 public String getTraceLibPath() {
1010 return traceLibPath;
1011 }
1012
c357e4b6 1013}
This page took 0.085772 seconds and 5 git commands to generate.