| Index: tools/telemetry/telemetry/core/timeline/thread.py
|
| diff --git a/tools/telemetry/telemetry/core/timeline/tracing/thread.py b/tools/telemetry/telemetry/core/timeline/thread.py
|
| similarity index 73%
|
| rename from tools/telemetry/telemetry/core/timeline/tracing/thread.py
|
| rename to tools/telemetry/telemetry/core/timeline/thread.py
|
| index 8bb184a8b4f905bed5ddca79568e9185132311a4..fa6b6f43498fe72f1796155ed9fb44683c6ad221 100644
|
| --- a/tools/telemetry/telemetry/core/timeline/tracing/thread.py
|
| +++ b/tools/telemetry/telemetry/core/timeline/thread.py
|
| @@ -2,53 +2,83 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -import telemetry.core.timeline.event as timeline_event
|
| -import telemetry.core.timeline.tracing.sample as tracing_sample
|
| -import telemetry.core.timeline.tracing.slice as tracing_slice
|
| +import telemetry.core.timeline.event_container as event_container
|
| +import telemetry.core.timeline.sample as tracing_sample
|
| +import telemetry.core.timeline.slice as tracing_slice
|
|
|
| -class Thread(timeline_event.TimelineEvent):
|
| +class Thread(event_container.TimelineEventContainer):
|
| ''' A Thread stores all the trace events collected for a particular
|
| thread. We organize the synchronous slices on a thread by "subrows," where
|
| subrow 0 has all the root slices, subrow 1 those nested 1 deep, and so on.
|
| The asynchronous slices are stored in an AsyncSliceGroup object.
|
| '''
|
| def __init__(self, process, tid):
|
| - super(Thread, self).__init__('thread %s' % tid, 0, 0, parent=process)
|
| + super(Thread, self).__init__('thread %s' % tid, parent=process)
|
| self.tid = tid
|
| - self._open_slices = []
|
| self._async_slices = []
|
| self._samples = []
|
| - self._slices = []
|
| + self._toplevel_slices = []
|
| +
|
| + # State only valid during import.
|
| + self._open_slices = []
|
| + self._newly_added_slices = []
|
|
|
| @property
|
| - def slices(self):
|
| - return self._slices
|
| + def toplevel_slices(self):
|
| + return self._toplevel_slices
|
| +
|
| + @property
|
| + def all_slices(self):
|
| + return list(self.IterAllSlices())
|
|
|
| @property
|
| def samples(self):
|
| return self._samples
|
|
|
| @property
|
| + def async_slices(self):
|
| + return self._async_slices
|
| +
|
| + @property
|
| def open_slice_count(self):
|
| return len(self._open_slices)
|
|
|
| - @property
|
| - def async_slices(self):
|
| - return self._async_slices
|
| + def IterChildContainers(self):
|
| + return
|
| + yield # pylint: disable=W0101
|
| +
|
| + def IterAllSlices(self):
|
| + for s in self._toplevel_slices:
|
| + yield s
|
| + for sub_slice in s.IterEventsInThisContainerRecrusively():
|
| + yield sub_slice
|
| +
|
| + def IterEventsInThisContainer(self):
|
| + for s in self._open_slices:
|
| + yield s
|
| + for s in self._newly_added_slices:
|
| + yield s
|
| +
|
| + for async_slice in self._async_slices:
|
| + yield async_slice
|
| + for sub_slice in async_slice.IterEventsInThisContainerRecrusively():
|
| + yield sub_slice
|
| + for s in self.IterAllSlices():
|
| + yield s
|
| + for sample in self._samples:
|
| + yield sample
|
|
|
| def AddSample(self, category, name, timestamp, args=None):
|
| if len(self._samples) and timestamp < self._samples[-1].start:
|
| raise ValueError(
|
| 'Samples must be added in increasing timestamp order')
|
| - sample = tracing_sample.Sample(
|
| - category, name, timestamp, args=args, parent=self)
|
| + sample = tracing_sample.Sample(self,
|
| + category, name, timestamp, args=args)
|
| self._samples.append(sample)
|
| - self.children.append(sample)
|
|
|
| def AddAsyncSlice(self, async_slice):
|
| self._async_slices.append(async_slice)
|
| async_slice.parent = self
|
| - self.children.append(async_slice)
|
|
|
| def BeginSlice(self, category, name, timestamp, args=None):
|
| """Opens a new slice for the thread.
|
| @@ -66,7 +96,7 @@ class Thread(timeline_event.TimelineEvent):
|
| raise ValueError(
|
| 'Slices must be added in increasing timestamp order')
|
| self._open_slices.append(
|
| - tracing_slice.Slice(category, name, timestamp, args=args, parent=self))
|
| + tracing_slice.Slice(self, category, name, timestamp, args=args))
|
|
|
| def EndSlice(self, end_timestamp):
|
| """ Ends the last begun slice in this group and pushes it onto the slice
|
| @@ -87,14 +117,10 @@ class Thread(timeline_event.TimelineEvent):
|
| return self.PushSlice(curr_slice)
|
|
|
| def PushSlice(self, new_slice):
|
| - self._slices.append(new_slice)
|
| - self.children.append(new_slice)
|
| + self._newly_added_slices.append(new_slice)
|
| return new_slice
|
|
|
| - def AutoCloseOpenSlices(self, max_timestamp=None):
|
| - if max_timestamp is None:
|
| - self.UpdateBounds()
|
| - max_timestamp = self.end
|
| + def AutoCloseOpenSlices(self, max_timestamp):
|
| while len(self._open_slices) > 0:
|
| curr_slice = self.EndSlice(max_timestamp)
|
| curr_slice.did_not_finish = True
|
| @@ -104,16 +130,6 @@ class Thread(timeline_event.TimelineEvent):
|
| return True
|
| return timestamp >= self._open_slices[-1].start
|
|
|
| - def UpdateBounds(self):
|
| - super(Thread, self).UpdateBounds()
|
| -
|
| - # Take open slices into account for the start and duration of thread event
|
| - if len(self._open_slices) > 0:
|
| - if not len(self.slices) or self.start > self._open_slices[0].start:
|
| - self.start = self._open_slices[0].start
|
| - if not len(self.slices) or self.end < self._open_slices[-1].start:
|
| - self.duration = self._open_slices[-1].start - self.start
|
| -
|
| def FinalizeImport(self):
|
| self._BuildSliceSubRows()
|
|
|
| @@ -155,14 +171,18 @@ class Thread(timeline_event.TimelineEvent):
|
| return cmp(s2.end, s1.end)
|
| return cmp(s1.start, s2.start)
|
|
|
| - if not len(self._slices):
|
| + assert len(self._toplevel_slices) == 0
|
| + if not len(self._newly_added_slices):
|
| return
|
|
|
| - sorted_slices = sorted(self._slices, cmp=CompareSlices)
|
| + sorted_slices = sorted(self._newly_added_slices, cmp=CompareSlices)
|
| root_slice = sorted_slices[0]
|
| + self._toplevel_slices.append(root_slice)
|
| for s in sorted_slices[1:]:
|
| if not self._AddSliceIfBounds(root_slice, s):
|
| root_slice = s
|
| + self._toplevel_slices.append(root_slice)
|
| + self._newly_added_slices = []
|
|
|
| def _AddSliceIfBounds(self, root, child):
|
| ''' Adds a child slice to a root slice its proper row.
|
| @@ -177,6 +197,7 @@ class Thread(timeline_event.TimelineEvent):
|
| if len(root.sub_slices) > 0:
|
| if self._AddSliceIfBounds(root.sub_slices[-1], child):
|
| return True
|
| + child.parent_slice = root
|
| root.AddSubSlice(child)
|
| return True
|
| return False
|
|
|