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