Fix for Timestamp normalize() of BIG_BANG and BIG_CRUNCH (bug 382135)
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.core / src / org / eclipse / linuxtools / internal / lttng / core / trace / LTTngTrace.java
CommitLineData
5d10d135 1/*******************************************************************************
a3767fd9 2 * Copyright (c) 2009, 2011 Ericsson, MontaVista Software
5d10d135
ASL
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
a3767fd9 11 * Yufen Kuo (ykuo@mvista.com) - add support to allow user specify trace library path
5d10d135
ASL
12 *******************************************************************************/
13
5945cec9 14package org.eclipse.linuxtools.internal.lttng.core.trace;
5d10d135 15
28b94d61
FC
16import java.util.HashMap;
17import java.util.Iterator;
18import java.util.Vector;
19
12c155f5 20import org.eclipse.core.resources.IProject;
25e48683 21import org.eclipse.core.resources.IResource;
5945cec9
FC
22import org.eclipse.linuxtools.internal.lttng.core.TraceHelper;
23import org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent;
24import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventContent;
25import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventType;
26import org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation;
27import org.eclipse.linuxtools.internal.lttng.core.event.LttngTimestamp;
28import org.eclipse.linuxtools.internal.lttng.core.exceptions.LttngException;
29import org.eclipse.linuxtools.internal.lttng.core.tracecontrol.utility.LiveTraceManager;
ce38c104 30import org.eclipse.linuxtools.internal.lttng.jni.common.JniTime;
5d10d135 31import org.eclipse.linuxtools.lttng.jni.JniEvent;
28b94d61 32import org.eclipse.linuxtools.lttng.jni.JniMarker;
5d10d135 33import org.eclipse.linuxtools.lttng.jni.JniTrace;
28b94d61 34import org.eclipse.linuxtools.lttng.jni.JniTracefile;
004f471b 35import org.eclipse.linuxtools.lttng.jni.factory.JniTraceFactory;
4df4581d 36import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
1b70b6dc 37import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
6c13869b
FC
38import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
39import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
b4f71e4a 40import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
1b70b6dc
PT
41import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
42import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
43import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
6c13869b 44import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
7e6347b0 45import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
6c13869b 46import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
a5f08d16 47import org.eclipse.linuxtools.tmf.core.trace.TmfCheckpointIndexer;
6c13869b 48import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
9e0640dc 49import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
6c13869b 50import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
5d10d135 51
3fbd810a 52class LTTngTraceException extends LttngException {
cbdacf03 53
12c155f5 54 static final long serialVersionUID = -1636648737081868146L;
3fbd810a 55
cbdacf03 56 public LTTngTraceException(final String errMsg) {
12c155f5
FC
57 super(errMsg);
58 }
3fbd810a
FC
59}
60
5d10d135 61/**
64fe8e8a
FC
62 * <b><u>LTTngTrace</u></b>
63 * <p>
07d9e2ee 64 *
cbdacf03
FC
65 * LTTng trace implementation. It accesses the C trace handling library
66 * (seeking, reading and parsing) through the JNI component.
5d10d135 67 */
7e6347b0 68public class LTTngTrace extends TmfTrace<LttngEvent> implements ITmfEventParser<LttngEvent> {
9b635e61 69
212550ba
FC
70 public final static boolean PRINT_DEBUG = false;
71 public final static boolean UNIQUE_EVENT = true;
12c155f5
FC
72
73 private final static boolean SHOW_LTT_DEBUG_DEFAULT = false;
212550ba 74 private final static boolean IS_PARSING_NEEDED_DEFAULT = !UNIQUE_EVENT;
12c155f5 75 private final static int CHECKPOINT_PAGE_SIZE = 50000;
1b70b6dc 76 private final static long LTTNG_STREAMING_INTERVAL = 2000; // in ms
12c155f5
FC
77
78 // Reference to our JNI trace
c5b45b39
FC
79 private JniTrace currentJniTrace;
80
81 LttngTimestamp eventTimestamp;
99005796 82 String eventSource;
c5b45b39 83 LttngEventContent eventContent;
4641c2f7 84 String eventReference;
12c155f5
FC
85
86 // The actual event
c5b45b39 87 LttngEvent currentLttngEvent;
12c155f5
FC
88
89 // The current location
c5b45b39
FC
90 LttngLocation previousLocation;
91
92 LttngEventType eventType;
12c155f5 93
12c155f5 94 // Hashmap of the possible types of events (Tracefile/CPU/Marker in the JNI)
c5b45b39 95 HashMap<Integer, LttngEventType> traceTypes;
cbdacf03 96
12c155f5 97 // This vector will be used to quickly find a marker name from a position
c5b45b39 98 Vector<Integer> traceTypeNames;
cbdacf03 99
c5b45b39 100 private String traceLibPath;
12c155f5
FC
101
102 public LTTngTrace() {
103 }
104
f4c52cea 105 @Override
cbdacf03 106 public boolean validate(final IProject project, final String path) {
2352aed9 107 if (fileExists(path)) {
cbdacf03 108 final String traceLibPath = TraceHelper.getTraceLibDirFromProject(project);
12c155f5 109 try {
cbdacf03 110 final LTTngTraceVersion version = new LTTngTraceVersion(path, traceLibPath);
12c155f5 111 return version.isValidLttngTrace();
cbdacf03 112 } catch (final LttngException e) {
12c155f5
FC
113 }
114 }
115 return false;
116 }
117
a5f08d16 118 @SuppressWarnings({ "unchecked", "rawtypes" })
f4c52cea 119 @Override
25e48683 120 public synchronized void initTrace(final IResource resource, final String path, final Class<LttngEvent> eventType)
b4f71e4a 121 throws TmfTraceException {
09e86496 122 super.initialize(resource, path, eventType);
a5f08d16 123 setIndexer(new TmfCheckpointIndexer(this, getCacheSize()));
09e86496
FC
124 initialize(resource, path, eventType);
125 }
126
127 @Override
128 protected synchronized void initialize(final IResource resource, final String path, final Class<LttngEvent> eventType)
b4f71e4a 129 throws TmfTraceException {
12c155f5 130 try {
527225f5
FC
131 IProject project = resource.getProject();
132 traceLibPath = (project != null) ? TraceHelper.getTraceLibDirFromProject(project) : null;
12c155f5 133 currentJniTrace = JniTraceFactory.getJniTrace(path, traceLibPath, SHOW_LTT_DEBUG_DEFAULT);
cbdacf03 134 } catch (final Exception e) {
b4f71e4a 135 throw new TmfTraceException(e.getMessage());
12c155f5
FC
136 }
137
138 // Export all the event types from the JNI side
139 traceTypes = new HashMap<Integer, LttngEventType>();
140 traceTypeNames = new Vector<Integer>();
141 initialiseEventTypes(currentJniTrace);
142
00641a97 143 // Build the re-used event structure
12c155f5 144 eventTimestamp = new LttngTimestamp();
4641c2f7 145 eventSource = ""; //$NON-NLS-1$
12c155f5
FC
146 this.eventType = new LttngEventType();
147 eventContent = new LttngEventContent(currentLttngEvent);
4641c2f7 148 eventReference = getName();
12c155f5
FC
149
150 // Create the skeleton event
151 currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, this.eventType, eventContent,
152 eventReference, null);
153
154 // Create a new current location
155 previousLocation = new LttngLocation();
156
157 // Set the currentEvent to the eventContent
158 eventContent.setEvent(currentLttngEvent);
159
0316808c
FC
160 setParser((ITmfEventParser<LttngEvent>) this);
161 setCacheSize(CHECKPOINT_PAGE_SIZE);
b4f71e4a 162
1b70b6dc
PT
163 initializeStreamingMonitor();
164 }
165
166 private void initializeStreamingMonitor() {
cbdacf03
FC
167 final JniTrace jniTrace = getCurrentJniTrace();
168 if (jniTrace == null
169 || (!jniTrace.isLiveTraceSupported() || !LiveTraceManager.isLiveTrace(jniTrace.getTracepath()))) {
1b70b6dc 170 // Set the time range of the trace
07671572 171 final ITmfContext context = seekEvent(0);
c32744d6 172 final LttngEvent event = getNext(context);
cbdacf03
FC
173 final LttngTimestamp startTime = new LttngTimestamp(event.getTimestamp());
174 final LttngTimestamp endTime = new LttngTimestamp(currentJniTrace.getEndTime().getTime());
1b70b6dc 175 setTimeRange(new TmfTimeRange(startTime, endTime));
cbdacf03 176 final TmfTraceUpdatedSignal signal = new TmfTraceUpdatedSignal(this, this, getTimeRange());
1b70b6dc
PT
177 broadcast(signal);
178 return;
179 }
180
12c155f5 181 // Set the time range of the trace
07671572 182 final ITmfContext context = seekEvent(0);
c32744d6 183 final LttngEvent event = getNext(context);
a4115405
FC
184 setEndTime(TmfTimestamp.BIG_BANG);
185 final long startTime = event != null ? event.getTimestamp().getValue() : TmfTimestamp.BIG_BANG.getValue();
0316808c 186 setStreamingInterval(LTTNG_STREAMING_INTERVAL);
1b70b6dc
PT
187
188 final Thread thread = new Thread("Streaming Monitor for trace " + getName()) { //$NON-NLS-1$
cbdacf03 189
1b70b6dc
PT
190 LttngTimestamp safeTimestamp = null;
191 TmfTimeRange timeRange = null;
192
8fd82db5 193 @SuppressWarnings({ "unchecked", "restriction" })
1b70b6dc
PT
194 @Override
195 public void run() {
196 while (!fExecutor.isShutdown()) {
cbdacf03 197 final TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
1b70b6dc 198 if (experiment != null) {
f4c52cea 199 @SuppressWarnings("rawtypes")
cbdacf03
FC
200 final TmfEventRequest request = new TmfEventRequest<TmfEvent>(TmfEvent.class,
201 TmfTimeRange.ETERNITY, 0, ExecutionType.FOREGROUND) {
202
1b70b6dc
PT
203 @Override
204 public void handleCompleted() {
205 updateJniTrace();
206 }
207 };
208 synchronized (experiment) {
209 experiment.sendRequest(request);
210 }
211 try {
212 request.waitForCompletion();
cbdacf03 213 } catch (final InterruptedException e) {
1b70b6dc 214 }
cbdacf03 215 } else
1b70b6dc 216 updateJniTrace();
1b70b6dc
PT
217 try {
218 Thread.sleep(LTTNG_STREAMING_INTERVAL);
cbdacf03 219 } catch (final InterruptedException e) {
1b70b6dc
PT
220 }
221 }
222 }
cbdacf03 223
1b70b6dc 224 private void updateJniTrace() {
cbdacf03 225 final JniTrace jniTrace = getCurrentJniTrace();
1b70b6dc 226 currentJniTrace.updateTrace();
cbdacf03
FC
227 final long endTime = jniTrace.getEndTime().getTime();
228 final LttngTimestamp startTimestamp = new LttngTimestamp(startTime);
229 final LttngTimestamp endTimestamp = new LttngTimestamp(endTime);
230 if (safeTimestamp != null && safeTimestamp.compareTo(getTimeRange().getEndTime(), false) > 0)
1b70b6dc 231 timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
cbdacf03 232 else
1b70b6dc 233 timeRange = null;
1b70b6dc 234 safeTimestamp = endTimestamp;
cbdacf03 235 if (timeRange != null)
1b70b6dc 236 setTimeRange(timeRange);
1b70b6dc
PT
237 }
238 };
239 thread.start();
240 }
c5b45b39 241
12c155f5
FC
242 /**
243 * Default Constructor.
244 * <p>
12c155f5 245 *
cbdacf03
FC
246 * @param name Name of the trace
247 * @param path Path to a <b>directory</b> that contain an LTTng trace.
248 *
249 * @exception Exception (most likely LTTngTraceException or
250 * FileNotFoundException)
12c155f5 251 */
25e48683 252 public LTTngTrace(final IResource resource, final String path) throws Exception {
12c155f5 253 // Call with "wait for completion" true and "skip indexing" false
25e48683 254 this(resource, path, null, true, false);
12c155f5
FC
255 }
256
257 /**
258 * Constructor, with control over the indexing.
259 * <p>
260 *
cbdacf03
FC
261 * @param name Name of the trace
262 * @param path Path to a <b>directory</b> that contain an LTTng trace.
263 * @param waitForCompletion Should we wait for indexign to complete before
264 * moving on.
12c155f5 265 *
cbdacf03
FC
266 * @exception Exception (most likely LTTngTraceException or
267 * FileNotFoundException)
12c155f5 268 */
25e48683 269 public LTTngTrace(final IResource resource, final String path, final boolean waitForCompletion) throws Exception {
12c155f5 270 // Call with "skip indexing" false
25e48683 271 this(resource, path, null, waitForCompletion, true);
12c155f5
FC
272 }
273
274 /**
cbdacf03
FC
275 * Default constructor, with control over the indexing and possibility to
276 * bypass indexation
12c155f5
FC
277 * <p>
278 *
cbdacf03
FC
279 * @param name Name of the trace
280 * @param path Path to a <b>directory</b> that contain an LTTng trace.
281 * @param traceLibPath Path to a <b>directory</b> that contains LTTng trace
282 * libraries.
283 * @param waitForCompletion Should we wait for indexign to complete before
284 * moving on.
285 * @param bypassIndexing Should we bypass indexing completly? This is should
286 * only be useful for unit testing.
12c155f5 287 *
cbdacf03
FC
288 * @exception Exception (most likely LTTngTraceException or
289 * FileNotFoundException)
12c155f5
FC
290 *
291 */
25e48683 292 public LTTngTrace(final IResource resource, final String path, final String traceLibPath, final boolean waitForCompletion,
cbdacf03 293 final boolean bypassIndexing)
f17b2f70 294 throws Exception {
09e86496
FC
295 // super(resource, LttngEvent.class, path, CHECKPOINT_PAGE_SIZE, false);
296 super(resource, LttngEvent.class, path, CHECKPOINT_PAGE_SIZE);
297 initialize(resource, path, LttngEvent.class);
20658947
FC
298// if (!bypassIndexing)
299// indexTrace(false);
12c155f5 300 this.traceLibPath = traceLibPath;
12c155f5
FC
301 }
302
303 /*
304 * Copy constructor is forbidden for LttngEvenmStream
305 */
cbdacf03 306 public LTTngTrace(final LTTngTrace other) throws Exception {
25e48683 307 this(other.getResource(), other.getPath(), other.getTraceLibPath(), false, true);
00641a97 308 setTimeRange(new TmfTimeRange(new LttngTimestamp(other.getStartTime()), new LttngTimestamp(other.getEndTime())));
12c155f5
FC
309 }
310
12c155f5
FC
311 public String getTraceLibPath() {
312 return traceLibPath;
313 }
314
315 /*
316 * Fill out the HashMap with "Type" (Tracefile/Marker)
317 *
318 * This should be called at construction once the trace is open
319 */
cbdacf03 320 private void initialiseEventTypes(final JniTrace trace) {
12c155f5
FC
321 // Work variables
322 LttngEventType tmpType = null;
323 String[] markerFieldsLabels = null;
324
325 String newTracefileKey = null;
326 Integer newMarkerKey = null;
327
328 JniTracefile newTracefile = null;
329 JniMarker newMarker = null;
330
331 // First, obtain an iterator on TRACEFILES of owned by the TRACE
cbdacf03 332 final Iterator<String> tracefileItr = trace.getTracefilesMap().keySet().iterator();
12c155f5
FC
333
334 while (tracefileItr.hasNext()) {
335 newTracefileKey = tracefileItr.next();
336 newTracefile = trace.getTracefilesMap().get(newTracefileKey);
337
338 // From the TRACEFILE read, obtain its MARKER
cbdacf03 339 final Iterator<Integer> markerItr = newTracefile.getTracefileMarkersMap().keySet().iterator();
12c155f5
FC
340 while (markerItr.hasNext()) {
341 newMarkerKey = markerItr.next();
342 newMarker = newTracefile.getTracefileMarkersMap().get(newMarkerKey);
343
344 // From the MARKER we can obtain the MARKERFIELDS keys (i.e.
345 // labels)
346 markerFieldsLabels = newMarker.getMarkerFieldsHashMap().keySet()
347 .toArray(new String[newMarker.getMarkerFieldsHashMap().size()]);
348
349 tmpType = new LttngEventType(newTracefile.getTracefileName(), newTracefile.getCpuNumber(),
350 newMarker.getName(), newMarkerKey.intValue(), markerFieldsLabels);
351
352 // Add the type to the map/vector
353 addEventTypeToMap(tmpType);
354 }
355 }
356 }
357
358 /*
359 * Add a new type to the HashMap
360 *
cbdacf03
FC
361 * As the hashmap use a key format that is a bit dangerous to use, we should
362 * always add using this function.
12c155f5 363 */
cbdacf03
FC
364 private void addEventTypeToMap(final LttngEventType newEventType) {
365 final int newTypeKey = EventTypeKey.getEventTypeHash(newEventType);
12c155f5
FC
366
367 this.traceTypes.put(newTypeKey, newEventType);
368 this.traceTypeNames.add(newTypeKey);
369 }
370
12c155f5 371 /**
cbdacf03
FC
372 * Return the latest saved location. Note : Modifying the returned location
373 * may result in buggy positionning!
12c155f5
FC
374 *
375 * @return The LttngLocation as it was after the last operation.
376 *
5945cec9 377 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation
12c155f5
FC
378 */
379 @Override
380 public synchronized ITmfLocation<?> getCurrentLocation() {
381 return previousLocation;
382 }
383
384 /**
385 * Position the trace to the event at the given location.
386 * <p>
cbdacf03
FC
387 * NOTE : Seeking by location is very fast compare to seeking by position
388 * but is still slower than "ReadNext", avoid using it for small interval.
12c155f5 389 *
cbdacf03
FC
390 * @param location Location of the event in the trace. If no event available
391 * at this exact location, we will position ourself to the next
392 * one.
12c155f5
FC
393 *
394 * @return The TmfContext that point to this event
395 *
5945cec9 396 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation
6c13869b 397 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext
12c155f5
FC
398 */
399 @Override
07671572 400 public synchronized ITmfContext seekEvent(final ITmfLocation<?> location) {
12c155f5 401
cbdacf03 402 if (PRINT_DEBUG)
12c155f5 403 System.out.println("seekLocation(location) location -> " + location); //$NON-NLS-1$
12c155f5
FC
404
405 // If the location in context is null, create a new one
12c155f5 406 if (location == null) {
07671572
FC
407 LttngLocation curLocation = new LttngLocation();
408 final ITmfContext context = seekEvent(curLocation.getOperationTime());
2352aed9 409 context.setRank(0);
12c155f5 410 return context;
07671572
FC
411 }
412
12c155f5
FC
413 // The only seek valid in LTTng is with the time, we call
414 // seekEvent(timestamp)
07671572
FC
415 LttngLocation curLocation = (LttngLocation) location;
416 final ITmfContext context = seekEvent(curLocation.getOperationTime());
12c155f5 417
655bf113
PT
418 // If the location is marked with the read next flag
419 // then it is pointing to the next event following the operation time
cbdacf03 420 if (curLocation.isLastOperationReadNext())
c32744d6 421 getNext(context);
655bf113 422
12c155f5
FC
423 return context;
424 }
425
426 /**
427 * Position the trace to the event at the given time.
428 * <p>
cbdacf03
FC
429 * NOTE : Seeking by time is very fast compare to seeking by position but is
430 * still slower than "ReadNext", avoid using it for small interval.
12c155f5 431 *
cbdacf03
FC
432 * @param timestamp Time of the event in the trace. If no event available at
433 * this exact time, we will position ourself to the next one.
12c155f5
FC
434 *
435 * @return The TmfContext that point to this event
436 *
5945cec9 437 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation
6c13869b 438 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext
12c155f5
FC
439 */
440 @Override
cbdacf03 441 public synchronized TmfContext seekEvent(final ITmfTimestamp timestamp) {
12c155f5 442
cbdacf03 443 if (PRINT_DEBUG)
12c155f5 444 System.out.println("seekEvent(timestamp) timestamp -> " + timestamp); //$NON-NLS-1$
12c155f5
FC
445
446 // Call JNI to seek
447 currentJniTrace.seekToTime(new JniTime(timestamp.getValue()));
448
449 // Save the time at which we seeked
450 previousLocation.setOperationTime(timestamp.getValue());
451 // Set the operation marker as seek, to be able to detect we did "seek"
452 // this event
453 previousLocation.setLastOperationSeek();
454
cbdacf03 455 final LttngLocation curLocation = new LttngLocation(previousLocation);
12c155f5
FC
456
457 return new TmfContext(curLocation);
458 }
459
460 /**
461 * Position the trace to the event at the given position (rank).
462 * <p>
cbdacf03
FC
463 * NOTE : Seeking by position is very slow in LTTng, consider seeking by
464 * timestamp.
12c155f5 465 *
cbdacf03 466 * @param rank Position (or rank) of the event in the trace, starting at 0.
12c155f5
FC
467 *
468 * @return The TmfContext that point to this event
469 *
5945cec9 470 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation
6c13869b 471 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext
12c155f5
FC
472 */
473 @Override
cbdacf03 474 public synchronized TmfContext seekEvent(final long rank) {
12c155f5 475
cbdacf03
FC
476 if (PRINT_DEBUG)
477 System.out.println("seekEvent(rank) rank -> " + rank); //$NON-NLS-1$
12c155f5 478
d337369a 479 // Position the trace at the checkpoint
0316808c 480 final ITmfContext checkpointContext = getIndexer().seekIndex(rank);
d337369a
FC
481 LttngLocation location = (LttngLocation) checkpointContext.getLocation();
482 ITmfTimestamp timestamp = location.getLocation();
20658947 483 long index = rank / getCacheSize();
12c155f5 484
12c155f5 485 // Seek to the found time
cbdacf03 486 final TmfContext tmpContext = seekEvent(timestamp);
0316808c 487 tmpContext.setRank((index + 1) * getCacheSize());
12c155f5
FC
488 previousLocation = (LttngLocation) tmpContext.getLocation();
489
490 // Ajust the index of the event we found at this check point position
20658947 491 Long currentPosition = index * getCacheSize();
12c155f5
FC
492
493 Long lastTimeValueRead = 0L;
494
495 // Get the event at current position. This won't move to the next one
496 JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
497 // Now that we are positionned at the checkpoint,
498 // we need to "readNext" (Position - CheckpointPosition) times or until
499 // trace "run out"
cbdacf03 500 while ((tmpJniEvent != null) && (currentPosition < rank)) {
12c155f5
FC
501 tmpJniEvent = currentJniTrace.readNextEvent();
502 currentPosition++;
503 }
504
505 // If we found our event, save its timestamp
cbdacf03 506 if (tmpJniEvent != null)
12c155f5 507 lastTimeValueRead = tmpJniEvent.getEventTime().getTime();
12c155f5
FC
508
509 // Set the operation marker as seek, to be able to detect we did "seek"
510 // this event
511 previousLocation.setLastOperationSeek();
512 // Save read event time
513 previousLocation.setOperationTime(lastTimeValueRead);
514
515 // *** VERIFY ***
516 // Is that too paranoid?
517 //
518 // We don't trust what upper level could do with our internal location
519 // so we create a new one to return instead
cbdacf03 520 final LttngLocation curLocation = new LttngLocation(previousLocation);
12c155f5 521
cbdacf03 522 return new TmfContext(curLocation, rank);
12c155f5
FC
523 }
524
525 @Override
7e6347b0 526 public TmfContext seekEvent(final double ratio) {
12c155f5
FC
527 // TODO Auto-generated method stub
528 return null;
529 }
530
531 @Override
cbdacf03 532 public double getLocationRatio(final ITmfLocation<?> location) {
12c155f5
FC
533 // TODO Auto-generated method stub
534 return 0;
535 }
536
537 /**
cbdacf03
FC
538 * Return the event in the trace according to the given context. Read it if
539 * necessary.
12c155f5 540 * <p>
cbdacf03
FC
541 * Similar (same?) as ParseEvent except that calling GetNext twice read the
542 * next one the second time.
12c155f5 543 *
cbdacf03 544 * @param context Current TmfContext where to get the event
12c155f5
FC
545 *
546 * @return The LttngEvent we read of null if no event are available
547 *
5945cec9 548 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation
6c13869b 549 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext
12c155f5
FC
550 */
551
552 public int nbEventsRead = 0;
553
554 @Override
c32744d6 555 public synchronized LttngEvent getNext(final ITmfContext context) {
12c155f5 556
cbdacf03 557 if (PRINT_DEBUG)
12c155f5
FC
558 System.out.println("getNextEvent(context) context.getLocation() -> " //$NON-NLS-1$
559 + context.getLocation());
12c155f5
FC
560
561 LttngEvent returnedEvent = null;
562 LttngLocation curLocation = null;
563
564 curLocation = (LttngLocation) context.getLocation();
565 // If the location in context is null, create a new one
cbdacf03 566 if (curLocation == null)
12c155f5 567 curLocation = getCurrentLocation(context);
12c155f5 568
12c155f5
FC
569 // *** Positioning trick :
570 // GetNextEvent only read the trace if :
571 // 1- The last operation was NOT a ParseEvent --> A read is required
572 // OR
573 // 2- The time of the previous location is different from the current
574 // one --> A seek + a read is required
575 if ((!(curLocation.isLastOperationParse()))
576 || (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue())) {
577 if (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue()) {
cbdacf03 578 if (PRINT_DEBUG)
12c155f5
FC
579 System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " //$NON-NLS-1$
580 + previousLocation.getOperationTimeValue() + " CurrentTime" //$NON-NLS-1$
581 + curLocation.getOperationTimeValue() + " ]"); //$NON-NLS-1$
12c155f5
FC
582 seekEvent(curLocation.getOperationTime());
583 }
584 // Read the next event from the trace. The last one will NO LONGER
585 // BE VALID.
586 returnedEvent = readNextEvent(curLocation);
587
588 } else {
589 // No event was read, just return the one currently loaded (the last
590 // one we read)
591 returnedEvent = currentLttngEvent;
592
61d428bd
PT
593 // Set the operation marker as read to both locations, to be able to
594 // detect we need to read the next event
595 previousLocation.setLastOperationReadNext();
596 curLocation.setLastOperationReadNext();
12c155f5
FC
597 }
598
599 // If we read an event, set it's time to the locations (both previous
600 // and current)
cbdacf03 601 if (returnedEvent != null)
12c155f5 602 setPreviousAndCurrentTimes(context, returnedEvent, curLocation);
12c155f5
FC
603
604 return returnedEvent;
605 }
606
607 // this method was extracted for profiling purposes
cbdacf03
FC
608 private synchronized void setPreviousAndCurrentTimes(final ITmfContext context, final LttngEvent returnedEvent,
609 final LttngLocation curLocation) {
12c155f5 610
cbdacf03 611 final ITmfTimestamp eventTimestamp = returnedEvent.getTimestamp();
12c155f5
FC
612 // long eventTime = eventTimestamp.getValue();
613 previousLocation.setOperationTime(eventTimestamp.getValue());
614 curLocation.setOperationTime(eventTimestamp.getValue());
d337369a 615 updateAttributes(context, eventTimestamp);
cbdacf03 616 context.increaseRank();
12c155f5
FC
617 }
618
12c155f5 619 // this method was extracted for profiling purposes
cbdacf03 620 private synchronized LttngEvent readNextEvent(final LttngLocation curLocation) {
12c155f5
FC
621 LttngEvent returnedEvent;
622 // Read the next event from the trace. The last one will NO LONGER BE
623 // VALID.
624 returnedEvent = readEvent(curLocation);
625 nbEventsRead++;
626
61d428bd
PT
627 // Set the operation marker as read to both locations, to be able to
628 // detect we need to read the next event
12c155f5
FC
629 previousLocation.setLastOperationReadNext();
630 curLocation.setLastOperationReadNext();
631 return returnedEvent;
632 }
633
634 // this method was extracted for profiling purposes
cbdacf03 635 private LttngLocation getCurrentLocation(final ITmfContext context) {
12c155f5
FC
636 LttngLocation curLocation;
637 curLocation = new LttngLocation();
638 context.setLocation(curLocation);
639 return curLocation;
640 }
641
642 /**
cbdacf03
FC
643 * Return the event in the trace according to the given context. Read it if
644 * necessary.
12c155f5 645 * <p>
cbdacf03
FC
646 * Similar (same?) as GetNextEvent except that calling ParseEvent twice will
647 * return the same event
12c155f5 648 *
cbdacf03 649 * @param context Current TmfContext where to get the event
12c155f5
FC
650 *
651 * @return The LttngEvent we read of null if no event are available
652 *
5945cec9 653 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngLocation
6c13869b 654 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext
12c155f5
FC
655 */
656 @Override
cbdacf03 657 public synchronized LttngEvent parseEvent(final ITmfContext context) {
12c155f5 658
cbdacf03 659 if (PRINT_DEBUG)
12c155f5
FC
660 System.out.println("parseEvent(context) context.getLocation() -> " //$NON-NLS-1$
661 + context.getLocation());
12c155f5
FC
662
663 LttngEvent returnedEvent = null;
664 LttngLocation curLocation = null;
665
666 // If the location in context is null, create a new one
667 if (context.getLocation() == null) {
668 curLocation = new LttngLocation();
669 context.setLocation(curLocation);
cbdacf03 670 } else
12c155f5 671 curLocation = (LttngLocation) context.getLocation();
12c155f5
FC
672
673 // *** HACK ***
674 // TMF assumes it is possible to read (GetNextEvent) to the next Event
675 // once ParseEvent() is called
676 // In LTTNG, there is not difference between "Parsing" and "Reading" an
677 // event.
678 // So, before "Parsing" an event, we have to make sure we didn't "Read"
679 // it alreafy.
680 // Also, "Reading" invalidate the previous Event in LTTNG and seek back
681 // is very costly,
682 // so calling twice "Parse" will return the same event, giving a way to
683 // get the "Currently loaded" event
684
685 // *** Positionning trick :
686 // ParseEvent only read the trace if :
61d428bd 687 // 1- The last operation was NOT a ParseEvent --> A read is required
12c155f5
FC
688 // OR
689 // 2- The time of the previous location is different from the current
690 // one --> A seek + a read is required
61d428bd 691 if (!curLocation.isLastOperationParse()
12c155f5
FC
692 || (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue())) {
693 // Previous time != Current time : We need to reposition to the
694 // current time
695 if (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue()) {
cbdacf03 696 if (PRINT_DEBUG)
12c155f5
FC
697 System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " //$NON-NLS-1$
698 + previousLocation.getOperationTimeValue() + " CurrentTime" //$NON-NLS-1$
699 + curLocation.getOperationTimeValue() + " ]"); //$NON-NLS-1$
12c155f5
FC
700 seekEvent(curLocation.getOperationTime());
701 }
702
703 // Read the next event from the trace. The last one will NO LONGER
704 // BE VALID.
705 returnedEvent = readEvent(curLocation);
cbdacf03 706 } else
12c155f5
FC
707 // No event was read, just return the one currently loaded (the last
708 // one we read)
709 returnedEvent = currentLttngEvent;
12c155f5
FC
710
711 // If we read an event, set it's time to the locations (both previous
712 // and current)
713 if (returnedEvent != null) {
714 previousLocation.setOperationTime((LttngTimestamp) returnedEvent.getTimestamp());
715 curLocation.setOperationTime((LttngTimestamp) returnedEvent.getTimestamp());
716 }
717
718 // Set the operation marker as parse to both location, to be able to
719 // detect we already "read" this event
720 previousLocation.setLastOperationParse();
721 curLocation.setLastOperationParse();
722
723 return returnedEvent;
724 }
725
726 /*
727 * Read the next event from the JNI and convert it as Lttng Event<p>
728 *
cbdacf03
FC
729 * @param location Current LttngLocation that to be updated with the event
730 * timestamp
12c155f5
FC
731 *
732 * @return The LttngEvent we read of null if no event are available
733 *
734 * @see org.eclipse.linuxtools.lttng.event.LttngLocation
735 *
736 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
737 */
cbdacf03 738 private synchronized LttngEvent readEvent(final LttngLocation location) {
12c155f5
FC
739 LttngEvent returnedEvent = null;
740 JniEvent tmpEvent = null;
741
742 // Read the next event from JNI. THIS WILL INVALIDATE THE CURRENT LTTNG
743 // EVENT.
744 tmpEvent = currentJniTrace.readNextEvent();
745
746 if (tmpEvent != null) {
747 // *** NOTE
748 // Convert will update the currentLttngEvent
749 returnedEvent = convertJniEventToTmf(tmpEvent);
750
751 location.setOperationTime((LttngTimestamp) returnedEvent.getTimestamp());
cbdacf03 752 } else
12c155f5 753 location.setOperationTime(getEndTime().getValue() + 1);
12c155f5
FC
754
755 return returnedEvent;
756 }
757
758 /**
759 * Method to convert a JniEvent into a LttngEvent.
760 * <p>
761 *
cbdacf03
FC
762 * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent,
763 * boolean) with a default value for isParsingNeeded
12c155f5 764 *
cbdacf03 765 * @param newEvent The JniEvent to convert into LttngEvent
12c155f5
FC
766 *
767 * @return The converted LttngEvent
768 *
769 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
5945cec9 770 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent
12c155f5 771 */
cbdacf03 772 public synchronized LttngEvent convertJniEventToTmf(final JniEvent newEvent) {
12c155f5
FC
773 currentLttngEvent = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT);
774
775 return currentLttngEvent;
776 }
777
778 /**
779 * Method to convert a JniEvent into a LttngEvent
780 *
cbdacf03
FC
781 * @param jniEvent The JniEvent to convert into LttngEvent
782 * @param isParsingNeeded A boolean value telling if the event should be
783 * parsed or not.
12c155f5
FC
784 *
785 * @return The converted LttngEvent
786 *
787 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
5945cec9 788 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent
12c155f5 789 */
cbdacf03 790 public synchronized LttngEvent convertJniEventToTmf(final JniEvent jniEvent, final boolean isParsingNeeded) {
12c155f5 791
212550ba 792 if (UNIQUE_EVENT) {
12c155f5
FC
793
794 // ***
795 // UNHACKED : We can no longer do that because TCF need to maintain
796 // several events at once.
797 // This is very slow to do so in LTTng, this has to be temporary.
798 // *** HACK ***
799 // To save time here, we only set value instead of allocating new
800 // object
801 // This give an HUGE performance improvement
802 // all allocation done in the LttngTrace constructor
803 // ***
804 eventTimestamp.setValue(jniEvent.getEventTime().getTime());
99005796 805 eventSource = jniEvent.requestEventSource();
12c155f5
FC
806
807 eventType = traceTypes.get(EventTypeKey.getEventTypeHash(jniEvent));
808
cbdacf03
FC
809 final String fullTracePath = getName();
810 final String reference = fullTracePath.substring(fullTracePath.lastIndexOf('/') + 1);
4641c2f7 811 currentLttngEvent.setReference(reference);
12c155f5
FC
812
813 eventContent.emptyContent();
814
815 currentLttngEvent.setType(eventType);
816 // Save the jni reference
817 currentLttngEvent.updateJniEventReference(jniEvent);
818
819 // Parse now if was asked
820 // Warning : THIS IS SLOW
cbdacf03 821 if (isParsingNeeded)
12c155f5 822 eventContent.getFields();
12c155f5
FC
823
824 return currentLttngEvent;
cbdacf03 825 } else
12c155f5 826 return convertJniEventToTmfMultipleEventEvilFix(jniEvent, isParsingNeeded);
12c155f5
FC
827
828 }
829
830 /**
cbdacf03
FC
831 * This method is a temporary fix to support multiple events at once in TMF
832 * This is expected to be slow and should be fixed in another way. See
833 * comment in convertJniEventToTmf();
12c155f5 834 *
cbdacf03 835 * @param jniEvent The current JNI Event
12c155f5
FC
836 * @return Current Lttng Event fully parsed
837 */
cbdacf03
FC
838 private synchronized LttngEvent convertJniEventToTmfMultipleEventEvilFix(final JniEvent jniEvent,
839 final boolean isParsingNeeded) {
12c155f5
FC
840 // *** HACK ***
841 // Below : the "fix" with all the new and the full-parse
842 // Allocating new memory is slow.
843 // Parsing every events is very slow.
844 eventTimestamp = new LttngTimestamp(jniEvent.getEventTime().getTime());
99005796 845 eventSource = jniEvent.requestEventSource();
4641c2f7 846 eventReference = getName();
12c155f5
FC
847 eventType = new LttngEventType(traceTypes.get(EventTypeKey.getEventTypeHash(jniEvent)));
848 eventContent = new LttngEventContent(currentLttngEvent);
849 currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference,
850 null);
851
852 // The jni reference is no longer reliable but we will keep it anyhow
853 currentLttngEvent.updateJniEventReference(jniEvent);
854 // Ensure that the content is correctly set
855 eventContent.setEvent(currentLttngEvent);
856
857 // Parse the event if it was needed
858 // *** WARNING ***
859 // ONLY for testing, NOT parsing events with non-unique events WILL
860 // result in segfault in the JVM
cbdacf03 861 if (isParsingNeeded)
12c155f5 862 eventContent.getFields();
12c155f5
FC
863
864 return currentLttngEvent;
865 }
866
867 /**
868 * Reference to the current LttngTrace we are reading from.
869 * <p>
870 *
cbdacf03
FC
871 * Note : This bypass the framework and should not be use, except for
872 * testing!
12c155f5
FC
873 *
874 * @return Reference to the current LttngTrace
875 *
876 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
877 */
878 public JniTrace getCurrentJniTrace() {
879 return currentJniTrace;
880 }
881
882 /**
883 * Return a reference to the current LttngEvent we have in memory.
884 *
885 * @return The current (last read) LttngEvent
886 *
5945cec9 887 * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent
12c155f5
FC
888 */
889 public synchronized LttngEvent getCurrentEvent() {
890 return currentLttngEvent;
891 }
892
893 /**
894 * Get the major version number for the current trace
895 *
896 * @return Version major or -1 if unknown
897 *
898 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
899 *
900 */
901 public short getVersionMajor() {
cbdacf03 902 if (currentJniTrace != null)
12c155f5 903 return currentJniTrace.getLttMajorVersion();
cbdacf03 904 else
12c155f5 905 return -1;
12c155f5
FC
906 }
907
908 /**
909 * Get the minor version number for the current trace
910 *
911 * @return Version minor or -1 if unknown
912 *
913 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
914 *
915 */
916 public short getVersionMinor() {
cbdacf03 917 if (currentJniTrace != null)
12c155f5 918 return currentJniTrace.getLttMinorVersion();
cbdacf03 919 else
12c155f5 920 return -1;
12c155f5
FC
921 }
922
923 /**
924 * Get the number of CPU for this trace
925 *
926 * @return Number of CPU or -1 if unknown
927 *
928 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
929 *
930 */
931 public int getCpuNumber() {
cbdacf03 932 if (currentJniTrace != null)
12c155f5 933 return currentJniTrace.getCpuNumber();
cbdacf03 934 else
12c155f5 935 return -1;
12c155f5
FC
936 }
937
12c155f5
FC
938 @Override
939 public synchronized void dispose() {
940 if (currentJniTrace != null)
941 currentJniTrace.closeTrace();
942 super.dispose();
943 }
944
945 /**
946 * Return a String identifying this trace.
947 *
948 * @return String that identify this trace
949 */
950 @Override
3b38ea61 951 @SuppressWarnings("nls")
12c155f5
FC
952 public String toString() {
953 String returnedData = "";
64fe8e8a 954
12c155f5
FC
955 returnedData += "Path :" + getPath() + " ";
956 returnedData += "Trace:" + currentJniTrace + " ";
957 returnedData += "Event:" + currentLttngEvent;
64fe8e8a 958
12c155f5
FC
959 return returnedData;
960 }
cb866e08 961
28b94d61
FC
962}
963
964/*
965 * EventTypeKey inner class
966 *
cbdacf03
FC
967 * This class is used to make the process of generating the HashMap key more
968 * transparent and so less error prone to use
28b94d61 969 */
64fe8e8a 970final class EventTypeKey {
cbdacf03 971
12c155f5
FC
972 // *** WARNING ***
973 // These two getEventTypeKey() functions should ALWAYS construct the key the
974 // same ways!
975 // Otherwise, every type search will fail!
64fe8e8a 976
12c155f5
FC
977 // added final to encourage inlining.
978
979 // generating a hash code by hand to avoid a string creation
cbdacf03 980 final static public int getEventTypeHash(final LttngEventType newEventType) {
12c155f5
FC
981 return generateHash(newEventType.getTracefileName(), newEventType.getCpuId(), newEventType.getMarkerName());
982 }
983
cbdacf03 984 final private static int generateHash(final String traceFileName, final long cpuNumber, final String markerName) {
12c155f5
FC
985 // 0x1337 is a prime number. The number of CPUs is always under 8192 on
986 // the current kernel, so this will work with the current linux kernel.
cbdacf03 987 final int cpuHash = (int) (cpuNumber * (0x1337));
12c155f5
FC
988 return traceFileName.hashCode() ^ (cpuHash) ^ markerName.hashCode();
989 }
990
991 // generating a hash code by hand to avoid a string creation
cbdacf03 992 final static public int getEventTypeHash(final JniEvent newEvent) {
12c155f5
FC
993 return generateHash(newEvent.getParentTracefile().getTracefileName(), newEvent.getParentTracefile()
994 .getCpuNumber(), newEvent.requestEventMarker().getName());
995 }
64fe8e8a 996
a3767fd9 997}
This page took 0.099934 seconds and 5 git commands to generate.