Commit 54ab6c56 authored by nednguyen's avatar nednguyen Committed by Commit bot

Add profiling_controller that manages profilers.

Remove StartProfiling & StopProfiling methods from browser.py.

profiling_controller is owned by platform, so this will allow decoupling lifetime of profilers from browser.
This cannot be achieved yet in this patch since we have some
profilers whose lifetime dependent on the browser, e.g: v8, tracing... To do
this, profilers' APIs should be modified for case browser_backend is optional if
they are not dependent on the browsers (e.g: monsoon, tcp_dump...).
For now, StartProfiling will explode if the number of running browsers is not 1.

BUG=

Review URL: https://codereview.chromium.org/511653002

Cr-Commit-Position: refs/heads/master@{#293618}
parent ab302628
......@@ -20,14 +20,15 @@ def _RunPrebuilt(options):
output_file = os.path.join(tempfile.mkdtemp(), options.profiler)
raw_input('Press enter to start profiling...')
print '>> Starting profiler', options.profiler
browser.StartProfiling(options.profiler, output_file)
browser.platform.profiling_controller.Start(
options.profiler, output_file)
print 'Press enter or CTRL+C to stop'
try:
raw_input()
except KeyboardInterrupt:
pass
finally:
browser.StopProfiling()
browser.platform.profiling_controller.Stop()
print '<< Stopped profiler ', options.profiler
......
......@@ -14,7 +14,6 @@ from telemetry.core import tab_list
from telemetry.core import wpr_modes
from telemetry.core import wpr_server
from telemetry.core.backends import browser_backend
from telemetry.core.platform.profiler import profiler_finder
class Browser(object):
......@@ -34,12 +33,9 @@ class Browser(object):
self._browser_backend = backend
self._platform_backend = platform_backend
self._wpr_server = None
self._active_profilers = []
self._profilers_states = {}
self._local_server_controller = local_server.LocalServerController(backend)
self._tabs = tab_list.TabList(backend.tab_list_backend)
self.credentials = browser_credentials.BrowserCredentials()
self._platform_backend.DidCreateBrowser(self, self._browser_backend)
def __enter__(self):
......@@ -93,10 +89,6 @@ class Browser(object):
'Extensions not supported')
return extension_dict.ExtensionDict(self._browser_backend.extension_backend)
def is_profiler_active(self, profiler_name):
return profiler_name in [profiler.name() for
profiler in self._active_profilers]
def _GetStatsCommon(self, pid_stats_function):
browser_pid = self._browser_backend.pid
result = {
......@@ -238,36 +230,6 @@ class Browser(object):
del result['ProcessCount']
return result
def StartProfiling(self, profiler_name, base_output_file):
"""Starts profiling using |profiler_name|. Results are saved to
|base_output_file|.<process_name>."""
assert not self._active_profilers, 'Already profiling. Must stop first.'
profiler_class = profiler_finder.FindProfiler(profiler_name)
if not profiler_class.is_supported(self._browser_backend.browser_type):
raise Exception('The %s profiler is not '
'supported on this platform.' % profiler_name)
if not profiler_class in self._profilers_states:
self._profilers_states[profiler_class] = {}
self._active_profilers.append(
profiler_class(self._browser_backend, self._platform_backend,
base_output_file, self._profilers_states[profiler_class]))
def StopProfiling(self):
"""Stops all active profilers and saves their results.
Returns:
A list of filenames produced by the profiler.
"""
output_files = []
for profiler in self._active_profilers:
output_files.extend(profiler.CollectProfile())
self._active_profilers = []
return output_files
def Start(self):
browser_options = self._browser_backend.browser_options
self.platform.FlushDnsCache()
......@@ -286,10 +248,6 @@ class Browser(object):
def Close(self):
"""Closes this browser."""
for profiler_class in self._profilers_states:
profiler_class.WillCloseBrowser(self._browser_backend,
self._platform_backend)
if self._browser_backend.IsBrowserRunning():
self._platform_backend.WillCloseBrowser(self, self._browser_backend)
......
......@@ -4,6 +4,7 @@
import sys
from telemetry.core.platform import profiling_controller
from telemetry.core.platform import tracing_controller
......@@ -47,11 +48,17 @@ class Platform(object):
self._platform_backend.SetPlatform(self)
self._tracing_controller = tracing_controller.TracingController(
self._platform_backend.tracing_controller_backend)
self._profiling_controller = profiling_controller.ProfilingController(
self._platform_backend.profiling_controller_backend)
@property
def tracing_controller(self):
return self._tracing_controller
@property
def profiling_controller(self):
return self._profiling_controller
def IsRawDisplayFrameRateSupported(self):
"""Platforms may be able to collect GL surface stats."""
return self._platform_backend.IsRawDisplayFrameRateSupported()
......
......@@ -4,6 +4,7 @@
import weakref
from telemetry.core.platform import profiling_controller_backend
from telemetry.core.platform import tracing_controller_backend
......@@ -46,8 +47,10 @@ class PlatformBackend(object):
def __init__(self):
self._platform = None
self._running_browser_backends = weakref.WeakSet()
self._tracing_controller_backend = \
tracing_controller_backend.TracingControllerBackend(self)
self._tracing_controller_backend = (
tracing_controller_backend.TracingControllerBackend(self))
self._profiling_controller_backend = (
profiling_controller_backend.ProfilingControllerBackend(self))
def SetPlatform(self, platform):
assert self._platform == None
......@@ -65,6 +68,10 @@ class PlatformBackend(object):
def tracing_controller_backend(self):
return self._tracing_controller_backend
@property
def profiling_controller_backend(self):
return self._profiling_controller_backend
def DidCreateBrowser(self, browser, browser_backend):
self.SetFullPerformanceModeEnabled(True)
......@@ -77,6 +84,8 @@ class PlatformBackend(object):
def WillCloseBrowser(self, browser, browser_backend):
self._tracing_controller_backend.WillCloseBrowser(
browser, browser_backend)
self._profiling_controller_backend.WillCloseBrowser(
browser_backend)
is_last_browser = len(self._running_browser_backends) == 1
if is_last_browser:
......
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
class ProfilingController(object):
def __init__(self, profiling_controller_backend):
self._profiling_controller_backend = profiling_controller_backend
def Start(self, profiler_name, base_output_file):
self._profiling_controller_backend.Start(
profiler_name, base_output_file)
def Stop(self):
return self._profiling_controller_backend.Stop()
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from telemetry.core.platform.profiler import profiler_finder
class ProfilingControllerBackend(object):
def __init__(self, platform_backend):
self._platform_backend = platform_backend
self._active_profilers = []
self._profilers_states = {}
def Start(self, profiler_name, base_output_file):
"""Starts profiling using |profiler_name|. Results are saved to
|base_output_file|.<process_name>."""
assert not self._active_profilers, 'Already profiling. Must stop first.'
browser_backend = None
# Note that many profilers doesn't rely on browser_backends, so the number
# of running_browser_backends may not matter for them.
if len(self._platform_backend.running_browser_backends) == 1:
browser_backend = self._platform_backend.running_browser_backends[0]
else:
raise NotImplementedError()
profiler_class = profiler_finder.FindProfiler(profiler_name)
if not profiler_class.is_supported(browser_backend.browser_type):
raise Exception('The %s profiler is not '
'supported on this platform.' % profiler_name)
if not profiler_class in self._profilers_states:
self._profilers_states[profiler_class] = {}
self._active_profilers.append(
profiler_class(browser_backend, self._platform_backend,
base_output_file, self._profilers_states[profiler_class]))
def Stop(self):
"""Stops all active profilers and saves their results.
Returns:
A list of filenames produced by the profiler.
"""
output_files = []
for profiler in self._active_profilers:
output_files.extend(profiler.CollectProfile())
self._active_profilers = []
return output_files
def WillCloseBrowser(self, browser_backend):
for profiler_class in self._profilers_states:
profiler_class.WillCloseBrowser(browser_backend, self._platform_backend)
......@@ -135,11 +135,12 @@ class _RunState(object):
finder_options.pageset_repeat != 1)
if is_repeating:
output_file = util.GetSequentialFileName(output_file)
self.browser.StartProfiling(finder_options.profiler, output_file)
self.browser.platform.profiling_controller.Start(
finder_options.profiler, output_file)
def StopProfiling(self):
if self.browser:
self.browser.StopProfiling()
self.browser.platform.profiling_controller.Stop()
class PageState(object):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment