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