| 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
|
|
|