summaryrefslogtreecommitdiffstats
path: root/chrome/common/profiling.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common/profiling.cc')
-rw-r--r--chrome/common/profiling.cc112
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();
+ }
+}