|
Line 0
Link Here
|
|
|
1 |
/******************************************************************************* |
| 2 |
* Copyright (c) 2009 Ericsson |
| 3 |
* |
| 4 |
* All rights reserved. This program and the accompanying materials are |
| 5 |
* made available under the terms of the Eclipse Public License v1.0 which |
| 6 |
* accompanies this distribution, and is available at |
| 7 |
* http://www.eclipse.org/legal/epl-v10.html |
| 8 |
* |
| 9 |
* Contributors: |
| 10 |
* William Bourque (wbourque@gmail.com) - Initial API and implementation |
| 11 |
*******************************************************************************/ |
| 12 |
|
| 13 |
package org.eclipse.linuxtools.lttng.jni; |
| 14 |
|
| 15 |
import java.util.Comparator; |
| 16 |
import java.util.HashMap; |
| 17 |
import java.util.Iterator; |
| 18 |
import java.util.PriorityQueue; |
| 19 |
|
| 20 |
/** |
| 21 |
* <b><u>JniTrace</u></b> |
| 22 |
* <p> |
| 23 |
* This is the top level class in the JNI. It provides access to the |
| 24 |
* LttTrace C structure in java. |
| 25 |
* <p> |
| 26 |
* Most important fields in the JniTrace are : |
| 27 |
* <ul> |
| 28 |
* <li>a JniTrace path (a trace <b>directory</b>) |
| 29 |
* <li>a HashMap of tracefiles that exists in this trace |
| 30 |
* </ul> |
| 31 |
*/ |
| 32 |
public class JniTrace extends Jni_C_Common { |
| 33 |
|
| 34 |
// Internal C pointer of the JniTrace used in LTT |
| 35 |
private C_Pointer thisTracePtr = new C_Pointer(); |
| 36 |
|
| 37 |
// Data we should populate from LTT |
| 38 |
// Note that all type have been scaled up as there is no "unsigned" in java |
| 39 |
// This might be a problem about "unsigned long" as there is no equivalent |
| 40 |
// in java |
| 41 |
|
| 42 |
private String tracepath = ""; // Path of the trace. Should be a directory (like : /tmp/traceX) |
| 43 |
private int cpuNumber = 0; |
| 44 |
private long archType = 0; |
| 45 |
private long archVariant = 0; |
| 46 |
private short archSize = 0; |
| 47 |
private short lttMajorVersion = 0; |
| 48 |
private short lttMinorVersion = 0; |
| 49 |
private short flightRecorder = 0; |
| 50 |
private long freqScale = 0; |
| 51 |
private long startFreq = 0; |
| 52 |
private long startTimestampCurrentCounter = 0; |
| 53 |
private long startMonotonic = 0; |
| 54 |
private JniTime startTime = null; |
| 55 |
private JniTime startTimeFromTimestampCurrentCounter = null; |
| 56 |
|
| 57 |
// This Map holds a reference to the tracefiles owned by this trace |
| 58 |
private HashMap<String, JniTracefile> tracefilesMap = null; |
| 59 |
// The priority queue (similar to heap) hold events |
| 60 |
private PriorityQueue<JniEvent> eventsHeap = null; |
| 61 |
|
| 62 |
// This variable will hold the content of the "last" event we read |
| 63 |
private JniTime currentEventTimestamp = new JniTime(); |
| 64 |
|
| 65 |
// Comparator we will need for the heap construction |
| 66 |
private Comparator<JniEvent> eventComparator = new Comparator<JniEvent>() { |
| 67 |
public int compare(JniEvent left, JniEvent right ){ |
| 68 |
return ( left.getEventTime().compare( right.getEventTime() ) ); |
| 69 |
} |
| 70 |
}; |
| 71 |
|
| 72 |
|
| 73 |
// Open/close native functions |
| 74 |
private native long ltt_openTrace(String pathname); |
| 75 |
private native void ltt_closeTrace(long tracePtr); |
| 76 |
|
| 77 |
// Native access functions |
| 78 |
private native String ltt_getTracepath(long tracePtr); |
| 79 |
private native int ltt_getCpuNumber(long tracePtr); |
| 80 |
private native long ltt_getArchType(long tracePtr); |
| 81 |
private native long ltt_getArchVariant(long tracePtr); |
| 82 |
private native short ltt_getArchSize(long tracePtr); |
| 83 |
private native short ltt_getLttMajorVersion(long tracePtr); |
| 84 |
private native short ltt_getLttMinorVersion(long tracePtr); |
| 85 |
private native short ltt_getFlightRecorder(long tracePtr); |
| 86 |
private native long ltt_getFreqScale(long tracePtr); |
| 87 |
private native long ltt_getStartFreq(long tracePtr); |
| 88 |
private native long ltt_getStartTimestampCurrentCounter(long tracePtr); |
| 89 |
private native long ltt_getStartMonotonic(long tracePtr); |
| 90 |
|
| 91 |
// Native function to fill out startTime |
| 92 |
private native void ltt_feedStartTime(long tracePtr, JniTime startTime); |
| 93 |
|
| 94 |
// Native function to fill out startTimeFromTimestampCurrentCounter |
| 95 |
private native void ltt_feedStartTimeFromTimestampCurrentCounter(long tracePtr, JniTime startTime); |
| 96 |
|
| 97 |
// Native function to fill out tracefilesMap |
| 98 |
private native void ltt_getAllTracefiles(long tracePtr); |
| 99 |
|
| 100 |
// Debug native function, ask LTT to print trace structure |
| 101 |
private native void ltt_printTrace(long tracePtr); |
| 102 |
|
| 103 |
static { |
| 104 |
System.loadLibrary("lttvtraceread"); |
| 105 |
} |
| 106 |
|
| 107 |
/** |
| 108 |
* Default constructor is forbidden |
| 109 |
*/ |
| 110 |
@SuppressWarnings("unused") |
| 111 |
private JniTrace() { |
| 112 |
} |
| 113 |
|
| 114 |
/** |
| 115 |
* Copy constructor. |
| 116 |
* |
| 117 |
* @param oldTrace |
| 118 |
* A reference to the JniTrace you want to copy. |
| 119 |
*/ |
| 120 |
public JniTrace(JniTrace oldTrace) { |
| 121 |
thisTracePtr = oldTrace.thisTracePtr; |
| 122 |
|
| 123 |
tracepath = oldTrace.tracepath; |
| 124 |
cpuNumber = oldTrace.cpuNumber; |
| 125 |
archType = oldTrace.archType; |
| 126 |
archVariant = oldTrace.archVariant; |
| 127 |
archSize = oldTrace.archSize; |
| 128 |
lttMajorVersion = oldTrace.lttMajorVersion; |
| 129 |
lttMinorVersion = oldTrace.lttMinorVersion; |
| 130 |
flightRecorder = oldTrace.flightRecorder; |
| 131 |
freqScale = oldTrace.freqScale; |
| 132 |
startFreq = oldTrace.startFreq; |
| 133 |
startTimestampCurrentCounter = oldTrace.startTimestampCurrentCounter; |
| 134 |
startMonotonic = oldTrace.startMonotonic; |
| 135 |
startTime = oldTrace.startTime; |
| 136 |
startTimeFromTimestampCurrentCounter = oldTrace.startTimeFromTimestampCurrentCounter; |
| 137 |
|
| 138 |
tracefilesMap = new HashMap<String, JniTracefile>(oldTrace.tracefilesMap.size()); |
| 139 |
tracefilesMap = oldTrace.tracefilesMap; |
| 140 |
|
| 141 |
eventsHeap = new PriorityQueue<JniEvent>( oldTrace.eventsHeap.size(), eventComparator ); |
| 142 |
eventsHeap = oldTrace.eventsHeap; |
| 143 |
} |
| 144 |
|
| 145 |
/** |
| 146 |
* Copy constructor, using pointer. |
| 147 |
* |
| 148 |
* @param newPtr The pointer to an already opened LttTrace C structure |
| 149 |
* |
| 150 |
* @exception JniException |
| 151 |
*/ |
| 152 |
public JniTrace(C_Pointer newPtr) throws JniException { |
| 153 |
thisTracePtr = newPtr; |
| 154 |
|
| 155 |
// Populate our trace |
| 156 |
populateTraceInformation(); |
| 157 |
} |
| 158 |
|
| 159 |
/** |
| 160 |
* Constructor that takes a tracepath parameter |
| 161 |
* <br> |
| 162 |
* This constructor also opens the trace |
| 163 |
* |
| 164 |
* @param newpath The <b>directory</b> of the trace to be opened |
| 165 |
* |
| 166 |
* @exception JniException |
| 167 |
*/ |
| 168 |
public JniTrace(String newpath) throws JniException { |
| 169 |
tracepath = newpath; |
| 170 |
thisTracePtr = new C_Pointer(); |
| 171 |
|
| 172 |
openTrace(newpath); |
| 173 |
} |
| 174 |
|
| 175 |
/** |
| 176 |
* Open an existing trace<br> |
| 177 |
* <br> |
| 178 |
* The tracepath is a directory and needs to exist, otherwise |
| 179 |
* a JafOpenTraceFailedException is raised. |
| 180 |
* |
| 181 |
* @param newPath |
| 182 |
* The <b>directory</b> of the trace to be opened |
| 183 |
* @exception JafOpenTraceFailedException |
| 184 |
* Thrown if the open failed |
| 185 |
*/ |
| 186 |
public void openTrace(String newPath) throws JniException { |
| 187 |
// If open is called while a trace is already opened, we will try to close it first |
| 188 |
if (thisTracePtr.getPointer() != NULL) { |
| 189 |
closeTrace(); |
| 190 |
} |
| 191 |
|
| 192 |
// Set the tracepath and open it |
| 193 |
tracepath = newPath; |
| 194 |
openTrace(); |
| 195 |
} |
| 196 |
|
| 197 |
/** |
| 198 |
* Open an existing trace<br> |
| 199 |
* <br> |
| 200 |
* The tracepath should have been set already, |
| 201 |
* |
| 202 |
* @exception JafOpenTraceFailedException |
| 203 |
* Thrown if the open failed |
| 204 |
*/ |
| 205 |
public void openTrace() throws JniException { |
| 206 |
|
| 207 |
// Raise an exception if the tracepath is empty, otherwise open the trace |
| 208 |
if (tracepath == "") { |
| 209 |
throw new JniTraceException("Tracepath is not set. (openTrace)"); |
| 210 |
} |
| 211 |
|
| 212 |
// If the file is already opened, close it first |
| 213 |
if (thisTracePtr.getPointer() != NULL) { |
| 214 |
closeTrace(); |
| 215 |
} |
| 216 |
|
| 217 |
// Call the LTT to open the trace |
| 218 |
long newPtr = ltt_openTrace(tracepath); |
| 219 |
if (newPtr == NULL) { |
| 220 |
throw new JniOpenTraceFailedException("Error while opening trace. Is the tracepath correct? (openTrace)"); |
| 221 |
} |
| 222 |
|
| 223 |
// This is OUR pointer |
| 224 |
thisTracePtr = new C_Pointer(newPtr); |
| 225 |
|
| 226 |
// Populate the trace with LTT information |
| 227 |
populateTraceInformation(); |
| 228 |
} |
| 229 |
|
| 230 |
/** |
| 231 |
* Close a trace |
| 232 |
* |
| 233 |
* If the trace is already closed, will silently do nothing. |
| 234 |
*/ |
| 235 |
public void closeTrace() { |
| 236 |
if (thisTracePtr.getPointer() != NULL) { |
| 237 |
ltt_closeTrace(thisTracePtr.getPointer()); |
| 238 |
thisTracePtr = new C_Pointer(NULL); |
| 239 |
|
| 240 |
// Clear the tracefile map |
| 241 |
tracefilesMap.clear(); |
| 242 |
tracefilesMap = null; |
| 243 |
|
| 244 |
// Clear the eventsHeap and make it points to null |
| 245 |
eventsHeap.clear(); |
| 246 |
eventsHeap = null; |
| 247 |
|
| 248 |
// Ask the garbage collector to make a little pass here, as we could |
| 249 |
// be left with 100's of unreferenced objects |
| 250 |
System.gc(); |
| 251 |
} |
| 252 |
} |
| 253 |
|
| 254 |
/* |
| 255 |
* This function populates the trace data with data from LTT |
| 256 |
* |
| 257 |
* @throws JafException |
| 258 |
*/ |
| 259 |
private void populateTraceInformation() throws JniException { |
| 260 |
if (thisTracePtr.getPointer() == NULL) { |
| 261 |
throw new JniTraceException("Pointer is NULL, trace not opened/already closed? (populateTraceInformation)"); |
| 262 |
} |
| 263 |
|
| 264 |
// Populate from the LTT library |
| 265 |
tracepath = ltt_getTracepath( thisTracePtr.getPointer() ); |
| 266 |
cpuNumber = ltt_getCpuNumber( thisTracePtr.getPointer() ); |
| 267 |
archType = ltt_getArchType( thisTracePtr.getPointer() ); |
| 268 |
archVariant = ltt_getArchVariant( thisTracePtr.getPointer() ); |
| 269 |
archSize = ltt_getArchSize( thisTracePtr.getPointer() ); |
| 270 |
lttMajorVersion = ltt_getLttMajorVersion( thisTracePtr.getPointer() ); |
| 271 |
lttMinorVersion = ltt_getLttMinorVersion( thisTracePtr.getPointer() ); |
| 272 |
flightRecorder = ltt_getFlightRecorder( thisTracePtr.getPointer() ); |
| 273 |
freqScale = ltt_getFreqScale( thisTracePtr.getPointer() ); |
| 274 |
startFreq = ltt_getStartFreq( thisTracePtr.getPointer() ); |
| 275 |
startTimestampCurrentCounter = ltt_getStartTimestampCurrentCounter( thisTracePtr.getPointer() ); |
| 276 |
startMonotonic = ltt_getStartMonotonic( thisTracePtr.getPointer() ); |
| 277 |
|
| 278 |
// Creation of time is a bit different, we need to pass the object reference to C |
| 279 |
startTime = new JniTime(); |
| 280 |
ltt_feedStartTime( thisTracePtr.getPointer(), startTime ); |
| 281 |
|
| 282 |
startTimeFromTimestampCurrentCounter = new JniTime(); |
| 283 |
ltt_feedStartTimeFromTimestampCurrentCounter( thisTracePtr.getPointer(), startTimeFromTimestampCurrentCounter ); |
| 284 |
|
| 285 |
// Call the fill up function for the tracefiles map |
| 286 |
if ( tracefilesMap== null ) { |
| 287 |
tracefilesMap = new HashMap<String, JniTracefile>(); |
| 288 |
} |
| 289 |
|
| 290 |
ltt_getAllTracefiles( thisTracePtr.getPointer() ); |
| 291 |
|
| 292 |
if (eventsHeap == null) { |
| 293 |
eventsHeap = new PriorityQueue<JniEvent>(tracefilesMap.size(), eventComparator); |
| 294 |
} |
| 295 |
|
| 296 |
// Populate the heap with events |
| 297 |
populateEventHeap(); |
| 298 |
} |
| 299 |
|
| 300 |
/* |
| 301 |
* This function populates the event heap with one event from each tracefile |
| 302 |
* It should be called after each seek or when the object is constructed |
| 303 |
*/ |
| 304 |
private void populateEventHeap() { |
| 305 |
currentEventTimestamp = new JniTime(); |
| 306 |
eventsHeap.clear(); |
| 307 |
|
| 308 |
Object new_key = null; |
| 309 |
JniTracefile tmpTracefile = null; |
| 310 |
|
| 311 |
Iterator<String> iterator = tracefilesMap.keySet().iterator(); |
| 312 |
while( iterator.hasNext() ) { |
| 313 |
new_key = iterator.next(); |
| 314 |
|
| 315 |
tmpTracefile = tracefilesMap.get(new_key); |
| 316 |
if ( tmpTracefile.getCurrentEvent().getEventState() == EOK ) { |
| 317 |
eventsHeap.add( tmpTracefile.getCurrentEvent() ); |
| 318 |
} |
| 319 |
} |
| 320 |
} |
| 321 |
|
| 322 |
/* |
| 323 |
* Fills a map of all the trace files. |
| 324 |
* |
| 325 |
* Note: This function is called from C and there is no way to propagate |
| 326 |
* exception back to the caller without crashing JNI. Therefore, it MUST |
| 327 |
* catch all exceptions. |
| 328 |
* |
| 329 |
* @param tracefileName |
| 330 |
* @param tracefilePtr |
| 331 |
*/ |
| 332 |
@SuppressWarnings("unused") |
| 333 |
private void addTracefileFromC(String tracefileName, long tracefilePtr) { |
| 334 |
// Create a new tracefile object and insert it in the map |
| 335 |
// the tracefile fill itself with LTT data while being constructed |
| 336 |
try { |
| 337 |
JniTracefile newTracefile = new JniTracefile( new C_Pointer(tracefilePtr), this ); |
| 338 |
tracefilesMap.put(tracefileName, newTracefile); |
| 339 |
} |
| 340 |
catch(JniTracefileWithoutEventException e) { |
| 341 |
printlnC("JniTracefile " + tracefileName + " has no event (addTracefileFromC). Ignoring."); |
| 342 |
} |
| 343 |
catch(Exception e) { |
| 344 |
printlnC("Failed to add tracefile " + tracefileName + " to tracefilesMap!(addTracefileFromC)\n\tException raised : " + e.toString() ); |
| 345 |
} |
| 346 |
} |
| 347 |
|
| 348 |
|
| 349 |
/** |
| 350 |
* Return the next event, determined by timestamp, among the trace files. |
| 351 |
* The event content is populated. |
| 352 |
* |
| 353 |
* Returns null in case of error or if we reach end of trace. |
| 354 |
* |
| 355 |
* @return The next event in the trace or null |
| 356 |
* @see org.eclipse.linuxtools.lttng.jni.JniEvent |
| 357 |
*/ |
| 358 |
public JniEvent readNextEvent() { |
| 359 |
// Get the "next" event on the top of the heap but DO NOT remove it |
| 360 |
JniEvent tmpEvent = eventsHeap.peek(); |
| 361 |
|
| 362 |
// If the event is null, it was the last one in the trace we can leave the function |
| 363 |
if (tmpEvent == null) { |
| 364 |
return null; |
| 365 |
} |
| 366 |
|
| 367 |
// Otherwise, we need to make sure the timestamp of the event we got is not the same as the last "NextEvent" we requested |
| 368 |
if (tmpEvent.getEventTime().getTime() == currentEventTimestamp.getTime() ) { |
| 369 |
// Remove the event on top as it is the same currentEventTimestamp |
| 370 |
eventsHeap.poll(); |
| 371 |
|
| 372 |
// Read the next event for this particular event type |
| 373 |
tmpEvent.readNextEvent(); |
| 374 |
|
| 375 |
// If the event state is sane (not Out of Range), put it back in the heap |
| 376 |
if ( tmpEvent.getEventState() == EOK ) { |
| 377 |
eventsHeap.add(tmpEvent); |
| 378 |
} |
| 379 |
|
| 380 |
// Pick the top event again |
| 381 |
tmpEvent = eventsHeap.peek(); |
| 382 |
|
| 383 |
// Save the timestamp if the event is not null (null mean we reached the last event in the trace) |
| 384 |
if (tmpEvent != null) { |
| 385 |
currentEventTimestamp = tmpEvent.getEventTime(); |
| 386 |
} |
| 387 |
} |
| 388 |
// If the event on top has differetn timestamp than the currentTimestamp, just save this timestamp as current |
| 389 |
else { |
| 390 |
currentEventTimestamp = tmpEvent.getEventTime(); |
| 391 |
} |
| 392 |
|
| 393 |
return tmpEvent; |
| 394 |
} |
| 395 |
|
| 396 |
/** |
| 397 |
* Return the next event, determined by timestamp, among the trace files. |
| 398 |
* The event content is NOT populated (requires a call to readNextEvent()). |
| 399 |
* |
| 400 |
* Returns null in case of error or EOF. |
| 401 |
* |
| 402 |
* @return The next event, or null if none is available |
| 403 |
* @see org.eclipse.linuxtools.lttng.jni.JniEvent |
| 404 |
*/ |
| 405 |
public JniEvent findNextEvent() { |
| 406 |
return eventsHeap.peek(); |
| 407 |
} |
| 408 |
|
| 409 |
/** |
| 410 |
* Seek to a certain time and read the next event from that time.<br> |
| 411 |
* <br> |
| 412 |
* If no more events are available or an error happen, null will be returned |
| 413 |
* |
| 414 |
* @param seekTime The time where we want to seek to |
| 415 |
* @return JniEvent The next event after the seek time or null |
| 416 |
* |
| 417 |
* @see org.eclipse.linuxtools.lttng.jni.JniEvent |
| 418 |
*/ |
| 419 |
public JniEvent seekAndRead(JniTime seekTime) { |
| 420 |
JniEvent returnedEvent = null; |
| 421 |
seekToTime(seekTime); |
| 422 |
|
| 423 |
// The trace should be correctly positionned, let's get the event |
| 424 |
returnedEvent = readNextEvent(); |
| 425 |
|
| 426 |
return returnedEvent; |
| 427 |
} |
| 428 |
|
| 429 |
/** |
| 430 |
* Seek to a certain time but <b>do not</b> read the next event.<br> |
| 431 |
* <br> |
| 432 |
* This only position the trace, it will not return anything. |
| 433 |
* |
| 434 |
* @param seekTime The time where we want to seek to |
| 435 |
*/ |
| 436 |
public void seekToTime(JniTime seekTime) { |
| 437 |
Object tracefile_name = null; |
| 438 |
Iterator<String> iterator = tracefilesMap.keySet().iterator(); |
| 439 |
|
| 440 |
while (iterator.hasNext() ) { |
| 441 |
// We seek to the given event for ALL tracefiles |
| 442 |
tracefile_name = iterator.next(); |
| 443 |
tracefilesMap.get(tracefile_name).seekToTime(seekTime); |
| 444 |
} |
| 445 |
|
| 446 |
populateEventHeap(); |
| 447 |
} |
| 448 |
|
| 449 |
/** |
| 450 |
* Get a certain tracefile from its given name<br> |
| 451 |
* |
| 452 |
* @param tracefileName The name of the tracefile |
| 453 |
* @return JniTracefile The tracefile found or null if none |
| 454 |
* @see org.eclipse.linuxtools.lttng.jni.JniTracefile |
| 455 |
*/ |
| 456 |
public JniTracefile requestTracefileByName(String tracefileName) { |
| 457 |
return tracefilesMap.get(tracefileName); |
| 458 |
} |
| 459 |
|
| 460 |
/** |
| 461 |
* Get a certain event associated to a trace file from the trace file name<br> |
| 462 |
* |
| 463 |
* @param tracefileName The name of the trace file |
| 464 |
* @return The JniEvent found or null if none |
| 465 |
* @see org.eclipse.linuxtools.lttng.jni.JniEvent |
| 466 |
*/ |
| 467 |
public JniEvent requestEventByName(String tracefileName) { |
| 468 |
JniEvent returnValue = null; |
| 469 |
|
| 470 |
JniTracefile tmpTracefile = tracefilesMap.get(tracefileName); |
| 471 |
|
| 472 |
// If the tracefile is found, return the current event |
| 473 |
// There should always be an event linked to a tracefile |
| 474 |
if (tmpTracefile != null) { |
| 475 |
returnValue = tmpTracefile.getCurrentEvent(); |
| 476 |
} |
| 477 |
|
| 478 |
return returnValue; |
| 479 |
} |
| 480 |
|
| 481 |
// Access to class variable. Most of them doesn't have setter |
| 482 |
public String getTracepath() { |
| 483 |
return tracepath; |
| 484 |
} |
| 485 |
|
| 486 |
public int getCpuNumber() { |
| 487 |
return cpuNumber; |
| 488 |
} |
| 489 |
|
| 490 |
public long getArchType() { |
| 491 |
return archType; |
| 492 |
} |
| 493 |
|
| 494 |
public long getArchVariant() { |
| 495 |
return archVariant; |
| 496 |
} |
| 497 |
|
| 498 |
public short getArchSize() { |
| 499 |
return archSize; |
| 500 |
} |
| 501 |
|
| 502 |
public short getLttMajorVersion() { |
| 503 |
return lttMajorVersion; |
| 504 |
} |
| 505 |
|
| 506 |
public short getLttMinorVersion() { |
| 507 |
return lttMinorVersion; |
| 508 |
} |
| 509 |
|
| 510 |
public short getFlightRecorder() { |
| 511 |
return flightRecorder; |
| 512 |
} |
| 513 |
|
| 514 |
public long getFreqScale() { |
| 515 |
return freqScale; |
| 516 |
} |
| 517 |
|
| 518 |
public long getStartFreq() { |
| 519 |
return startFreq; |
| 520 |
} |
| 521 |
|
| 522 |
public long getStartTimestampCurrentCounter() { |
| 523 |
return startTimestampCurrentCounter; |
| 524 |
} |
| 525 |
|
| 526 |
public long getStartMonotonic() { |
| 527 |
return startMonotonic; |
| 528 |
} |
| 529 |
|
| 530 |
public JniTime getStartTime() { |
| 531 |
return startTime; |
| 532 |
} |
| 533 |
|
| 534 |
public JniTime getStartTimeFromTimestampCurrentCounter() { |
| 535 |
return startTimeFromTimestampCurrentCounter; |
| 536 |
} |
| 537 |
|
| 538 |
public HashMap<String, JniTracefile> getTracefilesMap() { |
| 539 |
return tracefilesMap; |
| 540 |
} |
| 541 |
|
| 542 |
/** |
| 543 |
* Getter for the last read event timestamp<br> |
| 544 |
* |
| 545 |
* @return The time of the last event read |
| 546 |
*/ |
| 547 |
public JniTime getCurrentEventTimestamp() { |
| 548 |
return currentEventTimestamp; |
| 549 |
} |
| 550 |
|
| 551 |
/** |
| 552 |
* Pointer to the LttTrace C structure<br> |
| 553 |
* <br> |
| 554 |
* The pointer should only be used INTERNALY, do not use these unless you |
| 555 |
* know what you are doing. |
| 556 |
* |
| 557 |
* @return The actual (long converted) pointer or NULL |
| 558 |
*/ |
| 559 |
public C_Pointer getTracePtr() { |
| 560 |
return thisTracePtr; |
| 561 |
} |
| 562 |
|
| 563 |
/** |
| 564 |
* Print information for all the tracefiles associated with this trace. |
| 565 |
* <u>Intended to debug</u><br> |
| 566 |
* |
| 567 |
* This function will call Ltt to print, so information printed will be the |
| 568 |
* one from the C structure |
| 569 |
* |
| 570 |
* @see org.eclipse.linuxtools.lttng.jni.JniTracefile |
| 571 |
*/ |
| 572 |
public void printAllTracefilesInformation() { |
| 573 |
|
| 574 |
Object new_key = null; |
| 575 |
JniTracefile tracefile; |
| 576 |
|
| 577 |
Iterator<String> iterator = tracefilesMap.keySet().iterator(); |
| 578 |
while (iterator.hasNext()) { |
| 579 |
new_key = iterator.next(); |
| 580 |
|
| 581 |
tracefile = tracefilesMap.get(new_key); |
| 582 |
|
| 583 |
tracefile.printTracefileInformation(); |
| 584 |
} |
| 585 |
} |
| 586 |
|
| 587 |
/** |
| 588 |
* Print information for this trace. <u>Intended to debug</u><br> |
| 589 |
* |
| 590 |
* This function will call Ltt to print, so information printed will be the |
| 591 |
* one from the C structure<br> |
| 592 |
* <br> |
| 593 |
* This function will not throw but will complain loudly if pointer is NULL |
| 594 |
*/ |
| 595 |
public void printTraceInformation() { |
| 596 |
|
| 597 |
// If null pointer, print a warning! |
| 598 |
if (thisTracePtr.getPointer() == NULL) { |
| 599 |
printlnC("Pointer is NULL, cannot print. (printTraceInformation)"); |
| 600 |
} else { |
| 601 |
ltt_printTrace( thisTracePtr.getPointer() ); |
| 602 |
} |
| 603 |
} |
| 604 |
|
| 605 |
/** |
| 606 |
* toString() method. <u>Intended to debug</u><br> |
| 607 |
* |
| 608 |
* @return String Attributes of the object concatenated in String |
| 609 |
*/ |
| 610 |
public String toString() { |
| 611 |
String returnData = ""; |
| 612 |
returnData += "tracepath : " + tracepath + "\n"; |
| 613 |
returnData += "cpuNumber : " + cpuNumber + "\n"; |
| 614 |
returnData += "archType : " + archType + "\n"; |
| 615 |
returnData += "archVariant : " + archVariant + "\n"; |
| 616 |
returnData += "archSize : " + archSize + "\n"; |
| 617 |
returnData += "lttMajorVersion : " + lttMajorVersion + "\n"; |
| 618 |
returnData += "lttMinorVersion : " + lttMinorVersion + "\n"; |
| 619 |
returnData += "flightRecorder : " + flightRecorder + "\n"; |
| 620 |
returnData += "freqScale : " + freqScale + "\n"; |
| 621 |
returnData += "startFreq : " + startFreq + "\n"; |
| 622 |
returnData += "startTimestampCurrentCounter : " + startTimestampCurrentCounter + "\n"; |
| 623 |
returnData += "startMonotonic : " + startMonotonic + "\n"; |
| 624 |
returnData += "startTime : " + startTime.getReferenceToString() + "\n"; |
| 625 |
returnData += " seconds : " + startTime.getSeconds() + "\n"; |
| 626 |
returnData += " nanoSeconds : " + startTime.getNanoSeconds() + "\n"; |
| 627 |
returnData += "startTimeFromTimestampCurrentCounter : " + startTimeFromTimestampCurrentCounter.getReferenceToString() + "\n"; |
| 628 |
returnData += " seconds : " + startTimeFromTimestampCurrentCounter.getSeconds() + "\n"; |
| 629 |
returnData += " nanoSeconds : " + startTimeFromTimestampCurrentCounter.getNanoSeconds() + "\n"; |
| 630 |
returnData += "tracefilesMap : " + tracefilesMap.keySet() + "\n"; // Hack to avoid ending up with tracefilesMap.toString() |
| 631 |
|
| 632 |
return returnData; |
| 633 |
} |
| 634 |
|
| 635 |
/* |
| 636 |
* MAIN : For testing only! |
| 637 |
*/ |
| 638 |
public static void main(String[] args) { |
| 639 |
JniTrace testTrace = null; |
| 640 |
JniEvent tmpEvent = null; |
| 641 |
|
| 642 |
try { |
| 643 |
testTrace = new JniTrace("/home/william/trace1"); |
| 644 |
} |
| 645 |
catch (JniException e) { |
| 646 |
System.out.println(e.getMessage() ); |
| 647 |
return; |
| 648 |
} |
| 649 |
|
| 650 |
|
| 651 |
testTrace.printlnC( testTrace.toString() ); |
| 652 |
|
| 653 |
long nbEvent = 0; |
| 654 |
|
| 655 |
testTrace.printlnC("Beginning test run on 600k events"); |
| 656 |
tmpEvent = testTrace.readNextEvent(); |
| 657 |
while (tmpEvent != null) { |
| 658 |
nbEvent++; |
| 659 |
tmpEvent = testTrace.readNextEvent(); |
| 660 |
|
| 661 |
if ( tmpEvent != null ) { |
| 662 |
tmpEvent.parseAllFields(); |
| 663 |
} |
| 664 |
} |
| 665 |
testTrace.printlnC("We read " + nbEvent + " total events (JAF)\n"); |
| 666 |
|
| 667 |
|
| 668 |
/* |
| 669 |
|
| 670 |
tmpEvent = testTrace.readNextEvent(); |
| 671 |
|
| 672 |
JniTime test_time = new JniTime(960386633737L); |
| 673 |
tmpEvent = testTrace.seekAndRead(test_time); |
| 674 |
|
| 675 |
testTrace.printlnC(tmpEvent.getParentTracefile().getTracefileName().toString() ); |
| 676 |
testTrace.printlnC(tmpEvent.toString() ); |
| 677 |
|
| 678 |
|
| 679 |
test_time = new JniTime(960386638531L); |
| 680 |
tmpEvent = testTrace.seekAndRead(test_time); |
| 681 |
|
| 682 |
testTrace.printlnC(tmpEvent.getParentTracefile().getTracefileName().toString() ); |
| 683 |
testTrace.printlnC(tmpEvent.toString() ); |
| 684 |
|
| 685 |
|
| 686 |
tmpEvent = testTrace.readNextEvent(); |
| 687 |
if ( tmpEvent == null ) { |
| 688 |
testTrace.printlnC("NULL NULL NULL1"); |
| 689 |
} |
| 690 |
else { |
| 691 |
testTrace.printlnC(tmpEvent.getParentTracefile().getTracefileName().toString() ); |
| 692 |
testTrace.printlnC(tmpEvent.toString() ); |
| 693 |
} |
| 694 |
|
| 695 |
tmpEvent = testTrace.readNextEvent(); |
| 696 |
if ( tmpEvent == null ) { |
| 697 |
testTrace.printlnC("NULL NULL NULL2"); |
| 698 |
} |
| 699 |
else { |
| 700 |
testTrace.printlnC(tmpEvent.getParentTracefile().getTracefileName().toString() ); |
| 701 |
testTrace.printlnC(tmpEvent.toString() ); |
| 702 |
} |
| 703 |
*/ |
| 704 |
|
| 705 |
|
| 706 |
|
| 707 |
|
| 708 |
|
| 709 |
|
| 710 |
/* |
| 711 |
testTrace.printlnC("Beginning test run seek time"); |
| 712 |
JniTime test_time = new JniTime(953, 977711854); |
| 713 |
testTrace.seekToTime(test_time); |
| 714 |
tmpEvent = testTrace.findNextEvent(); |
| 715 |
testTrace.printlnC(tmpEvent.toString() ); |
| 716 |
*/ |
| 717 |
|
| 718 |
/* |
| 719 |
testTrace.printlnC("Beginning test run parsing event"); |
| 720 |
Object[] parsedName = null; |
| 721 |
HashMap<String,Object> parsedData = null; |
| 722 |
for ( int x = 0; x<30; x++) { |
| 723 |
tmpEvent = testTrace.readNextEvent(); |
| 724 |
|
| 725 |
testTrace.printlnC(tmpEvent.getParentTracefile().getTracefileName().toString() ); |
| 726 |
testTrace.printC(tmpEvent.toString() ); |
| 727 |
|
| 728 |
testTrace.printlnC("Format : " + tmpEvent.requestEventMarker().getFormatOverview().toString() ); |
| 729 |
parsedData = tmpEvent.parse(); |
| 730 |
parsedName = parsedData.keySet().toArray(); |
| 731 |
|
| 732 |
testTrace.printC(" "); |
| 733 |
for ( int pos=0; pos<parsedName.length; pos++) { |
| 734 |
testTrace.printC( parsedName[pos].toString() + " " + parsedData.get(parsedName[pos]).toString() + " "); |
| 735 |
} |
| 736 |
testTrace.printlnC("\n"); |
| 737 |
}*/ |
| 738 |
|
| 739 |
} |
| 740 |
|
| 741 |
} |
| 0 |
+ text/plain |
742 |
+ text/plain |