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): ...@@ -20,14 +20,15 @@ def _RunPrebuilt(options):
output_file = os.path.join(tempfile.mkdtemp(), options.profiler) output_file = os.path.join(tempfile.mkdtemp(), options.profiler)
raw_input('Press enter to start profiling...') raw_input('Press enter to start profiling...')
print '>> Starting profiler', options.profiler 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' print 'Press enter or CTRL+C to stop'
try: try:
raw_input() raw_input()
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
finally: finally:
browser.StopProfiling() browser.platform.profiling_controller.Stop()
print '<< Stopped profiler ', options.profiler print '<< Stopped profiler ', options.profiler
......
...@@ -14,7 +14,6 @@ from telemetry.core import tab_list ...@@ -14,7 +14,6 @@ from telemetry.core import tab_list
from telemetry.core import wpr_modes from telemetry.core import wpr_modes
from telemetry.core import wpr_server from telemetry.core import wpr_server
from telemetry.core.backends import browser_backend from telemetry.core.backends import browser_backend
from telemetry.core.platform.profiler import profiler_finder
class Browser(object): class Browser(object):
...@@ -34,12 +33,9 @@ class Browser(object): ...@@ -34,12 +33,9 @@ class Browser(object):
self._browser_backend = backend self._browser_backend = backend
self._platform_backend = platform_backend self._platform_backend = platform_backend
self._wpr_server = None self._wpr_server = None
self._active_profilers = []
self._profilers_states = {}
self._local_server_controller = local_server.LocalServerController(backend) self._local_server_controller = local_server.LocalServerController(backend)
self._tabs = tab_list.TabList(backend.tab_list_backend) self._tabs = tab_list.TabList(backend.tab_list_backend)
self.credentials = browser_credentials.BrowserCredentials() self.credentials = browser_credentials.BrowserCredentials()
self._platform_backend.DidCreateBrowser(self, self._browser_backend) self._platform_backend.DidCreateBrowser(self, self._browser_backend)
def __enter__(self): def __enter__(self):
...@@ -93,10 +89,6 @@ class Browser(object): ...@@ -93,10 +89,6 @@ class Browser(object):
'Extensions not supported') 'Extensions not supported')
return extension_dict.ExtensionDict(self._browser_backend.extension_backend) 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): def _GetStatsCommon(self, pid_stats_function):
browser_pid = self._browser_backend.pid browser_pid = self._browser_backend.pid
result = { result = {
...@@ -238,36 +230,6 @@ class Browser(object): ...@@ -238,36 +230,6 @@ class Browser(object):
del result['ProcessCount'] del result['ProcessCount']
return result 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): def Start(self):
browser_options = self._browser_backend.browser_options browser_options = self._browser_backend.browser_options
self.platform.FlushDnsCache() self.platform.FlushDnsCache()
...@@ -286,10 +248,6 @@ class Browser(object): ...@@ -286,10 +248,6 @@ class Browser(object):
def Close(self): def Close(self):
"""Closes this browser.""" """Closes this browser."""
for profiler_class in self._profilers_states:
profiler_class.WillCloseBrowser(self._browser_backend,
self._platform_backend)
if self._browser_backend.IsBrowserRunning(): if self._browser_backend.IsBrowserRunning():
self._platform_backend.WillCloseBrowser(self, self._browser_backend) self._platform_backend.WillCloseBrowser(self, self._browser_backend)
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import sys import sys
from telemetry.core.platform import profiling_controller
from telemetry.core.platform import tracing_controller from telemetry.core.platform import tracing_controller
...@@ -47,11 +48,17 @@ class Platform(object): ...@@ -47,11 +48,17 @@ class Platform(object):
self._platform_backend.SetPlatform(self) self._platform_backend.SetPlatform(self)
self._tracing_controller = tracing_controller.TracingController( self._tracing_controller = tracing_controller.TracingController(
self._platform_backend.tracing_controller_backend) self._platform_backend.tracing_controller_backend)
self._profiling_controller = profiling_controller.ProfilingController(
self._platform_backend.profiling_controller_backend)
@property @property
def tracing_controller(self): def tracing_controller(self):
return self._tracing_controller return self._tracing_controller
@property
def profiling_controller(self):
return self._profiling_controller
def IsRawDisplayFrameRateSupported(self): def IsRawDisplayFrameRateSupported(self):
"""Platforms may be able to collect GL surface stats.""" """Platforms may be able to collect GL surface stats."""
return self._platform_backend.IsRawDisplayFrameRateSupported() return self._platform_backend.IsRawDisplayFrameRateSupported()
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import weakref import weakref
from telemetry.core.platform import profiling_controller_backend
from telemetry.core.platform import tracing_controller_backend from telemetry.core.platform import tracing_controller_backend
...@@ -46,8 +47,10 @@ class PlatformBackend(object): ...@@ -46,8 +47,10 @@ class PlatformBackend(object):
def __init__(self): def __init__(self):
self._platform = None self._platform = None
self._running_browser_backends = weakref.WeakSet() self._running_browser_backends = weakref.WeakSet()
self._tracing_controller_backend = \ self._tracing_controller_backend = (
tracing_controller_backend.TracingControllerBackend(self) tracing_controller_backend.TracingControllerBackend(self))
self._profiling_controller_backend = (
profiling_controller_backend.ProfilingControllerBackend(self))
def SetPlatform(self, platform): def SetPlatform(self, platform):
assert self._platform == None assert self._platform == None
...@@ -65,6 +68,10 @@ class PlatformBackend(object): ...@@ -65,6 +68,10 @@ class PlatformBackend(object):
def tracing_controller_backend(self): def tracing_controller_backend(self):
return self._tracing_controller_backend return self._tracing_controller_backend
@property
def profiling_controller_backend(self):
return self._profiling_controller_backend
def DidCreateBrowser(self, browser, browser_backend): def DidCreateBrowser(self, browser, browser_backend):
self.SetFullPerformanceModeEnabled(True) self.SetFullPerformanceModeEnabled(True)
...@@ -77,6 +84,8 @@ class PlatformBackend(object): ...@@ -77,6 +84,8 @@ class PlatformBackend(object):
def WillCloseBrowser(self, browser, browser_backend): def WillCloseBrowser(self, browser, browser_backend):
self._tracing_controller_backend.WillCloseBrowser( self._tracing_controller_backend.WillCloseBrowser(
browser, browser_backend) browser, browser_backend)
self._profiling_controller_backend.WillCloseBrowser(
browser_backend)
is_last_browser = len(self._running_browser_backends) == 1 is_last_browser = len(self._running_browser_backends) == 1
if is_last_browser: 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): ...@@ -135,11 +135,12 @@ class _RunState(object):
finder_options.pageset_repeat != 1) finder_options.pageset_repeat != 1)
if is_repeating: if is_repeating:
output_file = util.GetSequentialFileName(output_file) 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): def StopProfiling(self):
if self.browser: if self.browser:
self.browser.StopProfiling() self.browser.platform.profiling_controller.Stop()
class PageState(object): 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