Quick hack for multi-CPU traces (lib issue).
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / trace / LTTngTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * William Bourque (wbourque@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.lttng.trace;
14
15 import org.eclipse.linuxtools.lttng.LttngException;
16 import org.eclipse.linuxtools.lttng.event.LttngEvent;
17 import org.eclipse.linuxtools.lttng.event.LttngEventContent;
18 import org.eclipse.linuxtools.lttng.event.LttngEventField;
19 import org.eclipse.linuxtools.lttng.event.LttngEventFormat;
20 import org.eclipse.linuxtools.lttng.event.LttngEventReference;
21 import org.eclipse.linuxtools.lttng.event.LttngEventType;
22 import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
23 import org.eclipse.linuxtools.lttng.jni.JniEvent;
24 import org.eclipse.linuxtools.lttng.jni.JniTime;
25 import org.eclipse.linuxtools.lttng.jni.JniTrace;
26 import org.eclipse.linuxtools.tmf.event.TmfEvent;
27 import org.eclipse.linuxtools.tmf.event.TmfEventSource;
28 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
29 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
30 import org.eclipse.linuxtools.tmf.trace.TmfTrace;
31 import org.eclipse.linuxtools.tmf.trace.TmfTraceContext;
32
33
34 class LTTngTraceException extends LttngException {
35 static final long serialVersionUID = -1636648737081868146L;
36
37 public LTTngTraceException(String errMsg) {
38 super(errMsg);
39 }
40 }
41
42 /**
43 * <b><u>LTTngTrace</u></b>
44 * <p>
45 * LTTng trace implementation. It accesses the C trace handling library
46 * (seeking, reading and parsing) through the JNI component.
47 */
48 public class LTTngTrace extends TmfTrace {
49
50 private final static boolean IS_PARSING_NEEDED_DEFAULT = true;
51 private final static int CHECKPOINT_PAGE_SIZE = 1000;
52
53 // Reference to the current LttngEvent
54 private LttngEvent currentLttngEvent = null;
55
56 // Reference to our JNI trace
57 private JniTrace currentJniTrace = null;
58
59 /**
60 * Default Constructor
61 * <p>
62 * @param path Path to a <b>directory</b> that contain an LTTng trace.
63 *
64 * @exception Exception Trace opening failed (most likely FileNotFoundException)
65 *
66 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
67 */
68 public LTTngTrace(String path) throws Exception {
69 this(path, true);
70 }
71
72 /**
73 * Default constructor, with control over the indexing
74 * <p>
75 * @param path Path to a <b>directory</b> that contain an LTTng trace.
76 * @param waitForCompletion Should we wait for indexign to complete before moving on.
77 *
78 * @exception Exception Trace opening failed (most likely FileNotFoundException)
79 *
80 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
81 */
82 public LTTngTrace(String path, boolean waitForCompletion) throws Exception {
83 super(path, CHECKPOINT_PAGE_SIZE, waitForCompletion);
84 try {
85 currentJniTrace = new JniTrace(path);
86 }
87 catch (Exception e) {
88 throw new LTTngTraceException(e.getMessage());
89 }
90 TmfTimestamp startTime = new LttngTimestamp(currentJniTrace.getStartTimeFromTimestampCurrentCounter().getTime());
91 setTimeRange(new TmfTimeRange(startTime, startTime));
92 indexStream();
93 }
94
95 /*
96 * Copy constructor is forbidden for LttngEvenmStream
97 *
98 * Events are only valid for a very limited period of time and
99 * JNI library does not support multiple access at once (yet?).
100 * For this reason, copy constructor should NEVER be used here.
101 */
102 private LTTngTrace(LTTngTrace oldStream) throws Exception {
103 super(null);
104 throw new Exception("Copy constructor should never be use with a LTTngTrace!");
105 }
106
107 /**
108 * Parse the next event in the trace
109 *
110 * @return TmfEvent The parsed event, or null if none available.
111 *
112 *
113 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
114 */
115 @Override
116 public TmfEvent parseEvent(TmfTraceContext context) {
117
118 JniEvent jniEvent;
119 LttngTimestamp timestamp = null;
120
121 synchronized (currentJniTrace) {
122 seekLocation(context.getLocation());
123 jniEvent = currentJniTrace.readNextEvent();
124 currentLttngEvent = (jniEvent != null) ? convertJniEventToTmf(jniEvent, true) : null;
125 timestamp = (LttngTimestamp) getCurrentLocation();
126 }
127 context.setLocation(timestamp);
128 context.setTimestamp(timestamp);
129 context.incrIndex();
130
131 return currentLttngEvent;
132 }
133
134 /*
135 * Method to convert a JniEvent into a LttngEvent.<br>
136 * <br>
137 * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean)
138 * with a default value for isParsingNeeded
139 *
140 * @param newEvent The JniEvent to convert
141 *
142 * @return LttngEvent The converted event
143 *
144 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
145 */
146 public LttngEvent convertJniEventToTmf(JniEvent newEvent) {
147 LttngEvent event = null;
148 if (newEvent != null)
149 event = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT);
150 return event;
151 }
152
153 /*
154 * Method tp convert a JniEvent into a LttngEvent
155 *
156 * @param jniEvent The JniEvent to convert
157 * @param isParsingNeeded A boolean value telling if the event should be parsed or not.
158 *
159 * @return LttngEvent The converted event
160 *
161 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
162 */
163 public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) {
164
165 // *** FIXME ***
166 // Format seems weird to me... we need to revisit Format/Fields/Content to find a better ways
167 //
168 // Generate fields
169 String[] labels = new String[jniEvent.requestEventMarker().getMarkerFieldsHashMap().size()];
170 labels = jniEvent.requestEventMarker().getMarkerFieldsHashMap().keySet().toArray( labels );
171
172 // We need a format for content and fields
173 LttngEventFormat eventFormat = new LttngEventFormat(labels);
174 String content = "";
175 LttngEventField[] fields = null;
176
177 if (isParsingNeeded == true) {
178 fields = eventFormat.parse(jniEvent.parseAllFields());
179 for (int y = 0; y < fields.length; y++) {
180 content += fields[y].toString() + " ";
181 }
182 }
183
184 LttngEvent event = null;
185 try {
186 event = new LttngEvent(
187 new LttngTimestamp(jniEvent.getEventTime().getTime()),
188 new TmfEventSource(jniEvent.requestEventSource() ),
189 new LttngEventType(jniEvent.getParentTracefile().getTracefileName(),
190 jniEvent.getParentTracefile().getCpuNumber(),
191 jniEvent.requestEventMarker().getName(),
192 eventFormat),
193 new LttngEventContent(eventFormat, content, fields),
194 new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName()),
195 jniEvent);
196 }
197 catch (LttngException e) {
198 System.out.println("ERROR : Event creation returned :" + e.getMessage() );
199 }
200
201 return event;
202 }
203
204 /**
205 * Seek (move) to a certain location in the trace.
206 * <p>
207 * WARNING : No event is read by this function, it just seek to a certain time.<br>
208 * Use "parseNextEvent()" or "readNextEvent()" to get the event we seeked to.
209 *
210 * @param location a TmfTimestamp of a position in the trace
211 *
212 * @return StreamContext pointing the position in the trace JUST AFTER the seek location
213 */
214 public TmfTraceContext seekLocation(Object location) {
215
216 LttngTimestamp timestamp = null;
217
218 // If location is null, interpret this as a request to get back to the beginning of the trace
219 // Change the location, the seek will happen below
220 if (location == null) {
221 location = getStartTime();
222 }
223
224 if (location instanceof TmfTimestamp) {
225 long value = ((TmfTimestamp) location).getValue();
226 if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) {
227 synchronized (currentJniTrace) {
228 currentJniTrace.seekToTime(new JniTime(value));
229 timestamp = (LttngTimestamp) getCurrentLocation();
230 }
231 }
232 }
233 else {
234 System.out.println("ERROR : Location not instance of TmfTimestamp");
235 }
236
237 return new TmfTraceContext(timestamp, timestamp, 0);
238 }
239
240 /**
241 * Return location (timestamp) of our current position in the trace.
242 *
243 * @return LttngTimestamp The time JUST AFTER the current event or AFTER endTime if no more event is available.
244 */
245 @Override
246 public Object getCurrentLocation() {
247
248 LttngTimestamp returnedLocation = null;
249 JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
250
251 if ( tmpJniEvent != null ) {
252 returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime());
253 }
254 else {
255 returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 );
256 }
257
258 return returnedLocation;
259 }
260
261 /**
262 * Return a reference to the current LttngTrace we are reading from.
263 *
264 * @return JniTrace
265 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
266 */
267 public JniTrace getCurrentJniTrace() {
268 return currentJniTrace;
269 }
270
271
272 /**
273 * Return a reference to the current LttngEvent we have in memory.
274 *
275 * @return LttngEvent
276 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
277 */
278 public LttngEvent getCurrentEvent() {
279 return currentLttngEvent;
280 }
281
282
283 @Override
284 public String toString() {
285 String returnedData="";
286
287 returnedData += "Path :" + getPath() + " ";
288 returnedData += "Trace:" + currentJniTrace + " ";
289 returnedData += "Event:" + currentLttngEvent;
290
291 return returnedData;
292 }
293
294
295 // // !!! THIS MAIN IS FOR TESTING ONLY !!!
296 // public static void main(String[] args) {
297 //
298 // LTTngTrace testStream = null;
299 // try {
300 //
301 // System.out.println("JAVA.LIBRARY.PATH : " + System.getProperty("java.library.path"));
302 //
303 // Map<String,String> testEnv = System.getenv();
304 //
305 // String new_key = null;
306 // String new_data = null;
307 // Iterator<String> iterator = testEnv.keySet().iterator();
308 //
309 // System.out.println("ENV : " );
310 // while (iterator.hasNext()) {
311 // new_key = iterator.next();
312 // new_data = testEnv.get(new_key);
313 // System.out.println(" " + new_key + ":" + new_data );
314 // }
315 //
316 // testStream = new LTTngTrace("/home/william/trace1", true);
317 //
318 // System.out.println("NB Events : " + testStream.getNbEvents());
319 // System.out.println("Beginning test run parsing event");
320 //
321 // LttngEvent tmpEvent = null;
322 // Random generator = new Random();
323 //
324 // int number = 0;
325 // long execStartTime = System.currentTimeMillis();
326 // for (int x = 0; x < 10; x++) {
327 // number = generator.nextInt(testStream.getNbEvents());
328 //
329 // tmpEvent = (LttngEvent) testStream.getEvent(new TmfTraceContext(null), number);
330 //
331 //
332 // System.out.println("GETTING EVENT #" + number);
333 //
334 // // *****************
335 // // *** OLD EVIL WAY
336 // TmfEventField[] tmpJoieFields = tmpEvent.getContent().getFields();
337 // for ( int pos = 0; pos< tmpJoieFields.length; pos++ )
338 // {
339 // System.out.print(tmpJoieFields[pos].toString() + " ");
340 // }
341 // System.out.println("");
342 // // ***
343 // // *****************
344 //
345 //
346 // // *****************
347 // // *** NEW CAST-O-RAMA WAY
348 // TmfEventField[] tmpJoieFields2 = ( (LttngEventContent)tmpEvent.getContent()).getFields(tmpEvent);
349 // for ( int pos = 0; pos< tmpJoieFields2.length; pos++ )
350 // {
351 // System.out.print(tmpJoieFields2[pos].toString() + " ");
352 // }
353 // System.out.println("");
354 // // ***
355 // // *****************
356 // }
357 // long execEndTime = System.currentTimeMillis();
358 // System.out.println("Execution time: " + (execEndTime - execStartTime) + "ms");
359 //
360 //
361 // } catch (Exception e) {
362 // System.out.println("FAILED WITH : " + e.getMessage() + "\n");
363 // }
364 //
365 // }
366
367 }
This page took 0.038451 seconds and 5 git commands to generate.