| Index: chrome/common/profiling.cc
|
| diff --git a/chrome/common/profiling.cc b/chrome/common/profiling.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bf67885206a8496fb52c28aec8896be8ee0625a9
|
| --- /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();
|
| + }
|
| +}
|
|
|