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(); |
+ } |
+} |