process.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. import telemetry.timeline.counter as tracing_counter
  5. import telemetry.timeline.event as event_module
  6. import telemetry.timeline.event_container as event_container
  7. import telemetry.timeline.thread as tracing_thread
  8. from telemetry.timeline import memory_dump_event
  9. class Process(event_container.TimelineEventContainer):
  10. """The Process represents a single userland process in the trace.
  11. """
  12. def __init__(self, parent, pid):
  13. super(Process, self).__init__('process %s' % pid, parent)
  14. self.pid = pid
  15. self.labels = None
  16. self._threads = {}
  17. self._counters = {}
  18. self._trace_buffer_overflow_event = None
  19. self._memory_dump_events = {}
  20. @property
  21. def trace_buffer_did_overflow(self):
  22. return self._trace_buffer_overflow_event is not None
  23. @property
  24. def trace_buffer_overflow_event(self):
  25. return self._trace_buffer_overflow_event
  26. @property
  27. def threads(self):
  28. return self._threads
  29. @property
  30. def counters(self):
  31. return self._counters
  32. def IterChildContainers(self):
  33. for thread in self._threads.itervalues():
  34. yield thread
  35. for counter in self._counters.itervalues():
  36. yield counter
  37. def IterEventsInThisContainer(self, event_type_predicate, event_predicate):
  38. if (self.trace_buffer_did_overflow and
  39. event_type_predicate(event_module.TimelineEvent) and
  40. event_predicate(self._trace_buffer_overflow_event)):
  41. yield self._trace_buffer_overflow_event
  42. if (self._memory_dump_events and
  43. event_type_predicate(memory_dump_event.ProcessMemoryDumpEvent)):
  44. for memory_dump in self._memory_dump_events.itervalues():
  45. if event_predicate(memory_dump):
  46. yield memory_dump
  47. def GetOrCreateThread(self, tid):
  48. thread = self.threads.get(tid, None)
  49. if thread:
  50. return thread
  51. thread = tracing_thread.Thread(self, tid)
  52. self._threads[tid] = thread
  53. return thread
  54. def GetCounter(self, category, name):
  55. counter_id = category + '.' + name
  56. if counter_id in self.counters:
  57. return self.counters[counter_id]
  58. raise ValueError(
  59. 'Counter %s not found in process with id %s.' % (counter_id,
  60. self.pid))
  61. def GetOrCreateCounter(self, category, name):
  62. try:
  63. return self.GetCounter(category, name)
  64. except ValueError:
  65. ctr = tracing_counter.Counter(self, category, name)
  66. self._counters[ctr.full_name] = ctr
  67. return ctr
  68. def AutoCloseOpenSlices(self, max_timestamp, thread_time_bounds):
  69. for thread in self._threads.itervalues():
  70. thread.AutoCloseOpenSlices(max_timestamp, thread_time_bounds[thread].max)
  71. def SetTraceBufferOverflowTimestamp(self, timestamp):
  72. # TODO: use instant event for trace_buffer_overflow_event
  73. self._trace_buffer_overflow_event = event_module.TimelineEvent(
  74. "TraceBufferInfo", "trace_buffer_overflowed", timestamp, 0)
  75. def AddMemoryDumpEvent(self, memory_dump):
  76. """Add a ProcessMemoryDumpEvent to this process."""
  77. if memory_dump.dump_id in self._memory_dump_events:
  78. raise ValueError('Duplicate memory dump id %s in process with id %s.' % (
  79. memory_dump.dump_id, self.pid))
  80. self._memory_dump_events[memory_dump.dump_id] = memory_dump
  81. def FinalizeImport(self):
  82. for thread in self._threads.itervalues():
  83. thread.FinalizeImport()
  84. for counter in self._counters.itervalues():
  85. counter.FinalizeImport()