Index: base/debug/trace_event_system.cc |
diff --git a/base/debug/trace_event_system.cc b/base/debug/trace_event_system.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ef3abf36d699c7616ece2837f6a1a4705fd10a8f |
--- /dev/null |
+++ b/base/debug/trace_event_system.cc |
@@ -0,0 +1,195 @@ |
+// Copyright 2013 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 "base/debug/trace_event_system.h" |
+ |
+#include "base/debug/leak_annotations.h" |
+#include "base/debug/trace_event.h" |
+#include "base/lazy_instance.h" |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_util.h" |
+#include "base/threading/thread_local_storage.h" |
+ |
+// TODO(jwmak): Windows support for system tracing. |
+#if !defined(NO_TCMALLOC) && !defined(OS_NACL) && \ |
+ (defined(OS_LINUX) || defined(OS_ANDROID)) |
+#define TRACE_SYSTEM_SUPPORTED 1 |
+#endif |
+ |
+ |
+namespace base { |
+namespace debug { |
+ |
+namespace { |
+ |
+///////////////////////////////////////////////////////////////////////////// |
+// Holds profiled system stats until the tracing system needs to serialize it. |
+class SystemProfilingStats : public base::debug::ConvertableToTraceFormat { |
+ public: |
+ SystemProfilingStats() { } |
+ virtual ~SystemProfilingStats() { |
+#ifdef OS_LINUX |
+ delete meminfo; |
+#endif |
+ } |
+ |
+ // Fills meminfo with system memory profiled stats. |
+ bool GetSystemProfilingStats(); |
+ |
+ // base::debug::ConvertableToTraceFormat overrides: |
+ virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE { |
+#ifdef OS_LINUX |
+ AppendSystemProfileAsTraceFormat(meminfo, out); |
+#endif |
+ } |
+ |
+ private: |
+ |
+#ifdef OS_LINUX |
+ SystemMemoryInfoKB *meminfo; |
+#endif |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SystemProfilingStats); |
+}; |
+ |
+bool SystemProfilingStats::GetSystemProfilingStats() { |
+#ifdef OS_LINUX |
+ meminfo = new SystemMemoryInfoKB(); |
+ if ((!GetSystemMemoryInfo(meminfo))) { |
+ DLOG(WARNING) << "Could not retrieve meminfo"; |
+ return false; |
+ } |
+#endif |
+ |
+ return true; |
+} |
+ |
+// If system tracing is enabled, dumps a profile to the tracing system. |
+void DumpSystemProfile() { |
+ DVLOG(1) << "DumpSystemProfile"; |
+ |
+ // Check to see if system tracing is enabled. |
+ bool enabled; |
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("system"), |
+ &enabled); |
+ if (!enabled) |
+ return; |
+ |
+ scoped_ptr<SystemProfilingStats> dump_holder(new SystemProfilingStats()); |
+ if (!dump_holder->GetSystemProfilingStats()) { |
+ return; |
+ } |
+ const int kSnapshotId = 1; |
+ TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
+ TRACE_DISABLED_BY_DEFAULT("system"), |
+ "memory::Heap", |
+ kSnapshotId, |
+ dump_holder.PassAs<base::debug::ConvertableToTraceFormat>()); |
+} |
+} // namespace |
+ |
+////////////////////////////////////////////////////////////////////////////// |
+ |
+TraceSystemController::TraceSystemController( |
+ scoped_refptr<MessageLoopProxy> message_loop_proxy) |
+ : message_loop_proxy_(message_loop_proxy), |
+ weak_factory_(this) { |
+ // Force the "system" category to show up in the trace viewer. |
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("system"), "init"); |
+ // Allow this to be instantiated on unsupported platforms, but don't run. |
+#if defined(TRACE_SYSTEM_SUPPORTED) |
+ TraceLog::GetInstance()->AddEnabledStateObserver(this); |
+#endif |
+} |
+ |
+TraceSystemController::~TraceSystemController() { |
+#if defined(TRACE_SYSTEM_SUPPORTED) |
+ if (dump_timer_.IsRunning()) |
+ StopProfiling(); |
+ TraceLog::GetInstance()->RemoveEnabledStateObserver(this); |
+#endif |
+} |
+ |
+ // base::debug::TraceLog::EnabledStateChangedObserver overrides: |
+void TraceSystemController::OnTraceLogEnabled() { |
+ DVLOG(1) << "OnTraceLogEnabled"; |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&TraceSystemController::StartProfiling, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+void TraceSystemController::OnTraceLogDisabled() { |
+ DVLOG(1) << "OnTraceLogDisabled"; |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&TraceSystemController::StopProfiling, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+void TraceSystemController::StartProfiling() { |
+ // Watch for the tracing framework sending enabling more than once. |
+ if (dump_timer_.IsRunning()) |
+ return; |
+ const int kDumpIntervalSeconds = 5; |
+ dump_timer_.Start(FROM_HERE, |
+ TimeDelta::FromSeconds(kDumpIntervalSeconds), |
+ base::Bind(&DumpSystemProfile)); |
+} |
+ |
+void TraceSystemController::StopProfiling() { |
+ dump_timer_.Stop(); |
+} |
+ |
+bool TraceSystemController::IsTimerRunningForTest() const { |
+ return dump_timer_.IsRunning(); |
+} |
+ |
+#if defined(OS_LINUX) |
+void AppendSystemProfileAsTraceFormat(SystemMemoryInfoKB *meminfo, |
+ std::string* output) { |
+ // Handle the initial summary line. |
+ output->append("["); |
+ output->append("{\"mem_free\": "); |
+ |
+ // Used memory is: total - free - buffers - caches |
+ output->append(IntToString(meminfo->free + meminfo->buffers |
+ + meminfo->cached)); |
+ output->append(", \"current_bytes\": "); |
+ output->append(IntToString(meminfo->buffers)); |
+ output->append(", \"cached\": "); |
+ output->append(IntToString(meminfo->cached)); |
+ output->append(", \"active anon\": "); |
+ output->append(IntToString(meminfo->active_anon)); |
+ output->append(", \"inactive anon\": "); |
+ output->append(IntToString(meminfo->inactive_anon)); |
+ output->append(", \"active file\": "); |
+ output->append(IntToString(meminfo->active_file)); |
+ output->append(", \"inactive file\": "); |
+ output->append(IntToString(meminfo->inactive_file)); |
+ output->append(", \"dirty\": "); |
+ output->append(IntToString(meminfo->dirty)); |
+ output->append(", \"swap_used\": "); |
+ output->append(IntToString(meminfo->swap_total - meminfo->swap_free)); |
+ |
+#if defined(OS_CHROMEOS) |
+ output->append("{, \"shmem\": "); |
+ output->append(IntToString(meminfo->shmem)); |
+ output->append("{, \"slab\": "); |
+ output->append(IntToString(meminfo->slab)); |
+#endif // defined(OS_CHROMEOS) |
+ |
+ |
+ output->append(", \"trace\": \"\"}"); |
+ output->append("]\n"); |
+ |
+// printf("output:\n%s",output->c_str()); |
+} |
+#endif |
+ |
+} // namespace debug |
+} // namespace base |