1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import telemetry.timeline.counter as tracing_counter 6import telemetry.timeline.event as event_module 7import telemetry.timeline.event_container as event_container 8import telemetry.timeline.thread as tracing_thread 9 10 11class Process(event_container.TimelineEventContainer): 12 ''' The Process represents a single userland process in the trace. 13 ''' 14 def __init__(self, parent, pid): 15 super(Process, self).__init__('process %s' % pid, parent) 16 self.pid = pid 17 self._threads = {} 18 self._counters = {} 19 self._trace_buffer_overflow_event = None 20 21 @property 22 def trace_buffer_did_overflow(self): 23 return self._trace_buffer_overflow_event is not None 24 25 @property 26 def trace_buffer_overflow_event(self): 27 return self._trace_buffer_overflow_event 28 29 @property 30 def threads(self): 31 return self._threads 32 33 @property 34 def counters(self): 35 return self._counters 36 37 def IterChildContainers(self): 38 for thread in self._threads.itervalues(): 39 yield thread 40 for counter in self._counters.itervalues(): 41 yield counter 42 43 def IterEventsInThisContainer(self, event_type_predicate, event_predicate): 44 if (not self.trace_buffer_did_overflow or 45 not event_type_predicate(event_module.TimelineEvent) or 46 not event_predicate(self._trace_buffer_overflow_event)): 47 return 48 yield # pylint: disable=W0101 49 yield self._trace_buffer_overflow_event 50 51 def GetOrCreateThread(self, tid): 52 thread = self.threads.get(tid, None) 53 if thread: 54 return thread 55 thread = tracing_thread.Thread(self, tid) 56 self._threads[tid] = thread 57 return thread 58 59 def GetCounter(self, category, name): 60 counter_id = category + '.' + name 61 if counter_id in self.counters: 62 return self.counters[counter_id] 63 raise ValueError( 64 'Counter %s not found in process with id %s.' % (counter_id, 65 self.pid)) 66 def GetOrCreateCounter(self, category, name): 67 try: 68 return self.GetCounter(category, name) 69 except ValueError: 70 ctr = tracing_counter.Counter(self, category, name) 71 self._counters[ctr.full_name] = ctr 72 return ctr 73 74 def AutoCloseOpenSlices(self, max_timestamp, thread_time_bounds): 75 for thread in self._threads.itervalues(): 76 thread.AutoCloseOpenSlices(max_timestamp, thread_time_bounds[thread].max) 77 78 def SetTraceBufferOverflowTimestamp(self, timestamp): 79 # TODO: use instant event for trace_buffer_overflow_event 80 self._trace_buffer_overflow_event = event_module.TimelineEvent( 81 "TraceBufferInfo", "trace_buffer_overflowed", timestamp, 0) 82 83 def FinalizeImport(self): 84 for thread in self._threads.itervalues(): 85 thread.FinalizeImport() 86 for counter in self._counters.itervalues(): 87 counter.FinalizeImport() 88