from telemetry.core.timeline import importer
import telemetry.core.timeline.async_slice as tracing_async_slice
+import telemetry.core.timeline.flow_event as tracing_flow_event
class TraceEventTimelineImporter(importer.TimelineImporter):
def __init__(self, model, event_data):
self._events_were_from_string = False
self._all_async_events = []
self._all_object_events = []
+ self._all_flow_events = []
if type(event_data) is str:
# If the event data begins with a [, then we know it should end with a ].
event['ts'] / 1000.0,
event.get('args'))
+ def _ProcessFlowEvent(self, event):
+ thread = (self._GetOrCreateProcess(event['pid'])
+ .GetOrCreateThread(event['tid']))
+ self._all_flow_events.append({
+ 'event': event,
+ 'thread': thread})
+
def ImportEvents(self):
''' Walks through the events_ list and outputs the structures discovered to
model_.
elif phase == 'N' or phase == 'D' or phase == 'O':
self._ProcessObjectEvent(event)
elif phase == 's' or phase == 't' or phase == 'f':
- # NB: toss until there's proper support
- pass
+ self._ProcessFlowEvent(event)
else:
self._model.import_errors.append('Unrecognized event phase: ' +
phase + '(' + event['name'] + ')')
# We need to reupdate the bounds in case the minimum start time changes
self._model.UpdateBounds()
self._CreateAsyncSlices()
+ self._CreateFlowSlices()
self._CreateExplicitObjects()
self._CreateImplicitObjects()
def _CreateImplicitObjects(self):
# TODO(tengs): Implement object instance parsing
pass
+
+ def _CreateFlowSlices(self):
+ if len(self._all_flow_events) == 0:
+ return
+
+ self._all_flow_events.sort(
+ cmp=lambda x, y: int(x['event']['ts'] - y['event']['ts']))
+
+ flow_id_to_event = {}
+ for data in self._all_flow_events:
+ event = data['event']
+ thread = data['thread']
+ if 'name' not in event:
+ self._model.import_errors.append(
+ 'Flow events (ph: s, t or f) require a name parameter.')
+ continue
+ if 'id' not in event:
+ self._model.import_errors.append(
+ 'Flow events (ph: s, t or f) require an id parameter.')
+ continue
+
+ flow_event = tracing_flow_event.FlowEvent(
+ event['cat'],
+ event['id'],
+ event['name'],
+ event['ts'] / 1000.0,
+ event['args'])
+ thread.AddFlowEvent(flow_event)
+
+ if event['ph'] == 's':
+ if event['id'] in flow_id_to_event:
+ self._model.import_errors.append(
+ 'event id %s already seen when encountering start of'
+ 'flow event.' % event['id'])
+ continue
+ flow_id_to_event[event['id']] = flow_event
+ elif event['ph'] == 't' or event['ph'] == 'f':
+ if not event['id'] in flow_id_to_event:
+ self._model.import_errors.append(
+ 'Found flow phase %s for id: %s but no flow start found.' % (
+ event['ph'], event['id']))
+ continue
+ flow_position = flow_id_to_event[event['id']]
+ self._model.flow_events.append([flow_position, flow_event])
+
+ if event['ph'] == 'f':
+ del flow_id_to_event[event['id']]
+ else:
+ # Make this event the next start event in this flow.
+ flow_id_to_event[event['id']] = flow_event