Monster merge from the integration branch. Still some problems left and JUnits failing.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / control / LttngSyntheticEventProvider.java
CommitLineData
5d10d135
ASL
1/*******************************************************************************
2 * Copyright (c) 2010 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 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.lttng.control;
14
15import java.util.HashMap;
16import java.util.Map;
17
18import org.eclipse.linuxtools.lttng.TraceDebug;
19import org.eclipse.linuxtools.lttng.event.LttngEvent;
20import org.eclipse.linuxtools.lttng.event.LttngEventType;
21import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
22import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
23import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
24import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
25import org.eclipse.linuxtools.lttng.request.LttngBaseEventRequest;
26import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor;
27import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory;
28import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
29import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager;
30import org.eclipse.linuxtools.tmf.component.TmfEventProvider;
31import org.eclipse.linuxtools.tmf.event.TmfEventSource;
32import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
33import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
34import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
35import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
36import org.eclipse.linuxtools.tmf.request.ITmfEventRequest;
5d10d135
ASL
37import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
38import org.eclipse.linuxtools.tmf.trace.ITmfContext;
39import org.eclipse.linuxtools.tmf.trace.TmfContext;
40import org.eclipse.linuxtools.tmf.trace.TmfTrace;
41
42/**
43 * @author alvaro
44 *
45 */
46public class LttngSyntheticEventProvider extends
47 TmfEventProvider<LttngSyntheticEvent> {
48
49 // ========================================================================
50 // Data
51 // ========================================================================
52 public static final int BLOCK_SIZE = 1;
53 public static final int NB_EVENTS = 1;
54 public static final int QUEUE_SIZE = 1; // lttng specific, one event at a
55 // time
56
57 // TmfDataProvider<LttngEvent> fExtProvider = null;
58 private ITmfDataRequest<LttngSyntheticEvent> fmainRequest = null;
550d787e 59 private final Map<IStateTraceManager, LttngBaseEventRequest> fEventProviderRequests = new HashMap<IStateTraceManager, LttngBaseEventRequest>();
5d10d135
ASL
60 private final LttngSyntheticEvent fStatusEvent;
61 private final LttngSyntheticEvent fStatusEventAck;
550d787e 62 private int fMainReqEventCount = 0;
5d10d135
ASL
63 volatile boolean startIndSent = false;
64 private LTTngTreeNode fExperiment = null;
65 private ITransEventProcessor fstateUpdateProcessor = StateEventToHandlerFactory
66 .getInstance();
67 private boolean waitForRequest = false;
68
69 // ========================================================================
70 // Constructor
71 // ========================================================================
72 /**
73 * Accessibility to package - use factory instead of this constructor
74 *
75 * @param type
76 */
77 LttngSyntheticEventProvider(Class<LttngSyntheticEvent> type) {
78 super("LttngSyntheticEventProvider", type, QUEUE_SIZE);
79
80 // prepare empty instance status indicators and allow them to travel via
81 // the framework
82 TmfEventSource source = new TmfEventSource(this);
83 LttngEventType dtype = new LttngEventType();
84 LttngTimestamp statusTimeStamp = new LttngTimestamp(
85 TmfTimestamp.BigBang);
86
87 fStatusEvent = new LttngSyntheticEvent(null, statusTimeStamp, source,
88 dtype, null, null, null);
89 fStatusEvent.setSequenceInd(SequenceInd.STARTREQ);
90
91 fStatusEventAck = new LttngSyntheticEvent(null, statusTimeStamp,
92 source, dtype, null, null, null);
93 fStatusEventAck.setSequenceInd(SequenceInd.ACK);
94 }
95
96 // ========================================================================
97 // Methods
98 // ========================================================================
550d787e 99
5d10d135
ASL
100 @SuppressWarnings("unchecked")
101 @Override
102 public ITmfContext armRequest(
103 final ITmfDataRequest<LttngSyntheticEvent> request) {
104 // validate
105 // make sure we have the right type of request
106 if (!(request instanceof ITmfEventRequest<?>)) {
107 request.cancel();
108 TraceDebug.debug("Request is not an instance of ITmfEventRequest");
109 return null;
110 }
111
112 if (fExperiment == null) {
113 TraceDebug.debug("Experiment is null");
114 request.cancel();
115 return null;
116 }
117
118 // get ready to start processing
119 reset(fExperiment);
120
121 // At least one base provider shall be available
550d787e 122 if (fEventProviderRequests.size() < 1) {
5d10d135
ASL
123 request.cancel();
124 TraceDebug.debug("No Base event providers available");
125 return null;
126 }
127
128 fmainRequest = request;
129 // define event data handling
130 ITmfEventRequest<LttngSyntheticEvent> eventRequest = (ITmfEventRequest<LttngSyntheticEvent>) fmainRequest;
131 TmfTimeRange reqWindow = eventRequest.getRange();
550d787e 132
5d10d135
ASL
133 TraceDebug.debug("Main Synthethic event request started on thread: " + Thread.currentThread().getName());
134
135 // loop for every traceManager in current experiment
550d787e
FC
136 boolean subRequestQueued = false;
137 for (IStateTraceManager traceManager : fEventProviderRequests.keySet()) {
5d10d135
ASL
138
139 // restore trace state system to nearest check point
140 TmfTimestamp checkPoint = traceManager
141 .restoreCheckPointByTimestamp(reqWindow.getStartTime());
550d787e
FC
142
143 // adjust start time bound to check point
144
5d10d135
ASL
145 // validate so checkpoint restore is within requested bounds
146 TmfTimeRange traceRange = traceManager.getTrace().getTimeRange();
550d787e
FC
147 if ((checkPoint != null) && !(
148 checkPoint.getValue() >= traceRange.getStartTime().getValue() &&
149 checkPoint.getValue() <= traceRange.getEndTime().getValue() &&
150 checkPoint.getValue() < reqWindow.getEndTime().getValue())
151 ) {
5d10d135
ASL
152 // checkpoint is out of trace bounds
153 continue;
154 }
550d787e
FC
155 TmfTimeRange adjustedRange = reqWindow;
156 if (checkPoint != null) {
157 adjustedRange = new TmfTimeRange(checkPoint, reqWindow.getEndTime());
158 }
5d10d135 159
736aecd5 160 LttngTraceState traceModel = traceManager.getStateModel();
5d10d135
ASL
161 // create sub-request for one trace within experiment
162 final LttngBaseEventRequest subRequest = new LttngBaseEventRequest(
163 adjustedRange, reqWindow.getStartTime(), 0,
550d787e 164 TmfEventRequest.ALL_DATA, BLOCK_SIZE, traceModel, ITmfDataRequest.ExecutionType.SHORT) {
5d10d135
ASL
165
166 private LttngSyntheticEvent syntheticEvent = null;
167 private LttngSyntheticEvent syntheticAckIndicator = null;
168 long subEventCount = 0L;
169
170 private final long fDispatchTime = getDispatchTime().getValue();
171 private final LttngTraceState fTraceModel = getTraceModel();
172
173 /*
174 * (non-Javadoc)
175 *
176 * @see
177 * org.eclipse.linuxtools.lttng.control.LttngEventRequest#handleData
178 * ()
179 */
180 @Override
181 public void handleData() {
182 LttngEvent[] events = getData();
183 if (events.length > 0) {
184 for (LttngEvent e : events) {
185 handleIncomingData(e);
186 }
187 } else {
188 TraceDebug.debug("handle data received with no data");
550d787e
FC
189// handleProviderDone(getTraceModel());
190// done();
5d10d135
ASL
191 }
192 }
193
194 /*
195 * (non-Javadoc)
196 *
197 * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#done()
198 */
199 @Override
200 public void done() {
201 // mark this sub-request as completed
202 super.done();
203 handleProviderDone(getTraceModel());
550d787e 204// super.done();
5d10d135
ASL
205 }
206
207 /**
208 * Trigger the Analysis and sequential control of the events.
209 *
210 * @param e
211 */
212 private void handleIncomingData(LttngEvent e) {
213 long eventTime = e.getTimestamp().getValue();
214
215 // if (eventTime == 13589777932952L) {
216 // // syscall entry id 78 expected
217 // System.out.println("debug mark at 13589777932952L");
218 // }
219
220 // queue the new event data and an ACK
221 updateSynEvent(e);
222
5d10d135 223 // If time at or above requested time, update application
550d787e
FC
224 try {
225 if (eventTime >= fDispatchTime) {
226 // Before update
227 syntheticEvent.setSequenceInd(SequenceInd.BEFORE);
228 queueResult(syntheticEvent);
229 queueResult(syntheticAckIndicator);
230
231 // Update state locally
232 syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
233 fstateUpdateProcessor.process(syntheticEvent, fTraceModel);
234
235 // After Update
236 syntheticEvent.setSequenceInd(SequenceInd.AFTER);
237 queueResult(syntheticEvent);
238 queueResult(syntheticAckIndicator);
239
240 // increment once per dispatch
241 incrementSynEvenCount();
242 subEventCount++;
243 } else {
244 // event time is between checkpoint adjusted time and
245 // requested time i.e. application does not expect the
246 // event, however the state system needs to be re-built
247 // to the dispatch point
248 syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
249 fstateUpdateProcessor.process(syntheticEvent, fTraceModel);
250 }
251 } catch (InterruptedException e1) {
252 e1.printStackTrace();
5d10d135
ASL
253 }
254 }
255
256 /**
257 * Create a synthetic event from the received new reference, if
258 * the reference is the same there is no need for a new instance
259 *
260 * if this is the first event for this request, call start
261 * handler
262 *
263 * @param e
264 * @return
265 */
266 private LttngSyntheticEvent updateSynEvent(LttngEvent e) {
267 if (syntheticEvent == null
268 || syntheticEvent.getBaseEvent() != e) {
269 syntheticEvent = new LttngSyntheticEvent(e);
270 syntheticAckIndicator = new LttngSyntheticEvent(e);
271 syntheticAckIndicator.setSequenceInd(SequenceInd.ACK);
272 }
273
274 // Trace model needed by application handlers
275 syntheticEvent.setTraceModel(fTraceModel);
276
277 // send the start request indication once per request thread
278 if (!startIndSent) {
279 TraceDebug.debug("Thread started: " + Thread.currentThread().getName());
280 handleProviderStarted(getTraceModel());
281 startIndSent = true;
282 }
283
284 return syntheticEvent;
285 }
286 };
550d787e 287
5d10d135
ASL
288 // preserve the associated sub request to control it e.g.
289 // cancellation
550d787e 290 fEventProviderRequests.put(traceManager, subRequest);
5d10d135
ASL
291
292 // start request
293 TmfTrace<LttngEvent> provider = (TmfTrace<LttngEvent>) traceManager
294 .getTrace();
550d787e 295 // provider.sendRequest(subRequest, ExecutionType.LONG);
8827c197 296 provider.sendRequest(subRequest);
550d787e 297 subRequestQueued = true;
5d10d135
ASL
298 }
299
300 // Return a dummy context, not used for relay provider
550d787e 301 return (subRequestQueued) ? new TmfContext() : null;
5d10d135
ASL
302 }
303
304 /**
305 * Notify listeners to prepare to receive data e.g. clean previous data etc.
306 */
307 public void handleProviderStarted(LttngTraceState traceModel) {
308 LttngSyntheticEvent startIndEvent = new LttngSyntheticEvent(
309 fStatusEvent);
310 startIndEvent.setSequenceInd(SequenceInd.STARTREQ);
311
312 // Notify application
550d787e
FC
313 try {
314 queueResult(startIndEvent);
315 queueResult(fStatusEventAck);
316 } catch (InterruptedException e) {
317 e.printStackTrace();
318 }
5d10d135
ASL
319
320 // Notify state event processor
321 fstateUpdateProcessor.process(startIndEvent, null);
322 }
323
324 /**
325 * Notify listeners, no more events for the current request will be
326 * distributed e.g. update view.
327 */
328 public synchronized void handleProviderDone(LttngTraceState traceModel) {
329 // TODO: The use of a thread per main request and thread per sub-request
330 // requires
331 // to make sure the proper main request is marked completed. So a
332 // relationship of sub-requests to parent needs to be established to
333 // handle completion and cancellations properly
334
335 // Close the main request when all sub-requests are marked completed
550d787e 336 for (LttngBaseEventRequest subRequest : fEventProviderRequests.values()) {
5d10d135
ASL
337 if (subRequest != null) {
338 if (!subRequest.isCompleted()) {
339 // Not ready to complete main request
340 return;
341 }
342 }
343 }
344
345 // All sub-requests are marked completed so the main request can be
346 // completed as well
347 // Notify application,
550d787e
FC
348// LttngSyntheticEvent finishEvent = new LttngSyntheticEvent(fStatusEvent);
349// finishEvent.setSequenceInd(SequenceInd.ENDREQ);
350// finishEvent.setTraceModel(traceModel);
351
352 try {
353// queueResult(finishEvent);
354// queueResult(fStatusEventAck);
355 // End the loop in the main request
356 queueResult(LttngSyntheticEvent.NullEvent);
357 } catch (InterruptedException e) {
358 // System.out.println(getName() +
359 // ":handleProviderDone() failed to queue request");
360 e.printStackTrace();
361 }
5d10d135
ASL
362 }
363
364 /**
365 * Increment the global event counter i.e. events from any sub requests
366 */
367 private synchronized void incrementSynEvenCount() {
550d787e 368 fMainReqEventCount++;
5d10d135
ASL
369 }
370
371 /**
372 * @return
373 */
374 public synchronized int getSynEvenCount() {
550d787e 375 return fMainReqEventCount;
5d10d135
ASL
376 }
377
378 /**
379 * Reset provider to a state ready to begin thread execution
380 *
381 * @param experimentNode
382 */
550d787e 383 public synchronized void reset(LTTngTreeNode experimentNode) {
5d10d135
ASL
384
385 fmainRequest = null;
386
387 // Make sure previous request are terminated
550d787e 388 for (LttngBaseEventRequest tmpRequest : fEventProviderRequests.values()) {
5d10d135
ASL
389 if (tmpRequest != null && !tmpRequest.isCompleted()) {
390 tmpRequest.cancel();
391 }
392 }
393
550d787e
FC
394 fEventProviderRequests.clear();
395 fMainReqEventCount = 0;
5d10d135
ASL
396 startIndSent = false;
397
398 // set of base event providers
399 if (fExperiment != null) {
400 LTTngTreeNode[] traces = fExperiment.getChildren();
401 for (LTTngTreeNode trace : traces) {
402 IStateTraceManager traceBaseEventProvider = (IStateTraceManager) trace;
550d787e 403 fEventProviderRequests.put(traceBaseEventProvider, null);
5d10d135
ASL
404 }
405 }
406
407 if (fExperiment != experimentNode) {
408 updateExperimentNode(experimentNode);
409 }
410 }
411
412 /**
413 * Point to a new experiment reference
414 *
415 * @param experiment
416 */
417 private synchronized void updateExperimentNode(LTTngTreeNode experiment) {
418 if (experiment != null
419 && experiment.getValue() instanceof TmfExperiment<?>) {
420 fExperiment = experiment;
421 } else {
422 TraceDebug
423 .debug("Experiment received is not instance of TmfExperiment: "
424 + experiment.getClass().getName());
425 }
426 }
427
428 /*
429 * (non-Javadoc)
430 *
431 * @see
432 * org.eclipse.linuxtools.tmf.component.TmfDataProvider#sendRequest(org.
433 * eclipse.linuxtools.tmf.request.TmfDataRequest)
434 */
550d787e 435 public void sendRequest(final ITmfDataRequest<LttngSyntheticEvent> request) {
5d10d135
ASL
436 super.sendRequest(request);
437 if (waitForRequest) {
438 try {
439 request.waitForCompletion();
440 } catch (InterruptedException e) {
441 e.printStackTrace();
442 }
443 }
444 }
445
446 /**
447 * @return the waitForRequest
448 */
449 public boolean isWaitForRequest() {
450 return waitForRequest;
451 }
452
453 /**
454 * @param waitForRequest
455 * configures the provider to wait for the request completion
456 */
457 public void setWaitForRequest(boolean waitForRequest) {
458 this.waitForRequest = waitForRequest;
459 }
460
461}
This page took 0.044678 seconds and 5 git commands to generate.