diff options
Diffstat (limited to 'chrome/common/profiling.cc')
-rw-r--r-- | chrome/common/profiling.cc | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/chrome/common/profiling.cc b/chrome/common/profiling.cc new file mode 100644 index 0000000..bf67885 --- /dev/null +++ b/chrome/common/profiling.cc @@ -0,0 +1,112 @@ +// Copyright (c) 2010 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. + +#include "chrome/common/profiling.h" + +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/debug/profiler.h" +#include "base/message_loop.h" +#include "base/string_util.h" +#include "chrome/common/chrome_switches.h" + +namespace { +std::string GetProfileName() { + static const char kDefaultProfileName[] = "chrome-profile-{pid}"; + static std::string profile_name; + + if (profile_name.empty()) { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kProfilingFile)) + profile_name = command_line.GetSwitchValueASCII(switches::kProfilingFile); + else + profile_name = std::string(kDefaultProfileName); + std::string process_type = + command_line.GetSwitchValueASCII(switches::kProcessType); + std::string type = process_type.empty() ? + std::string("browser") : std::string(process_type); + ReplaceSubstringsAfterOffset(&profile_name, 0, "{type}", type.c_str()); + } + return profile_name; +} + +void FlushProfilingData() { + static const int kProfilingFlushSeconds = 10; + + if (!Profiling::BeingProfiled()) + return; + + base::debug::FlushProfiling(); + static int flush_seconds = 0; + if (!flush_seconds) { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + std::string profiling_flush = + command_line.GetSwitchValueASCII(switches::kProfilingFlush); + if (!profiling_flush.empty()) { + flush_seconds = atoi(profiling_flush.c_str()); + DCHECK(flush_seconds > 0); + } else { + flush_seconds = kProfilingFlushSeconds; + } + } + MessageLoop::current()->PostDelayedTask(FROM_HERE, + NewRunnableFunction(FlushProfilingData), + flush_seconds * 1000); +} + +} // namespace + +// static +void Profiling::ProcessStarted() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + std::string process_type = + command_line.GetSwitchValueASCII(switches::kProcessType); + + if (command_line.HasSwitch(switches::kProfilingAtStart)) { + std::string process_type_to_start = + command_line.GetSwitchValueASCII(switches::kProfilingAtStart); + if (process_type == process_type_to_start) + Start(); + } +} + +// static +void Profiling::Start() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + bool flush = command_line.HasSwitch(switches::kProfilingFlush); + base::debug::StartProfiling(GetProfileName()); + + // Schedule profile data flushing for single process because it doesn't + // get written out correctly on exit. + if (flush && MessageLoop::current()) + FlushProfilingData(); +} + +// static +void Profiling::Stop() { + base::debug::StopProfiling(); +} + +// static +bool Profiling::BeingProfiled() { + return base::debug::BeingProfiled(); +} + +// static +void Profiling::Toggle() { + if (BeingProfiled()) + Stop(); + else + Start(); +} + +// static +void Profiling::MainMessageLoopStarted() { + if (BeingProfiled()) { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + bool flush = command_line.HasSwitch(switches::kProfilingFlush); + if (flush) + FlushProfilingData(); + } +} |