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