OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/debug/trace_event_system.h" |
| 6 |
| 7 #include "base/debug/leak_annotations.h" |
| 8 #include "base/debug/trace_event.h" |
| 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/message_loop.h" |
| 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_util.h" |
| 15 #include "base/threading/thread_local_storage.h" |
| 16 |
| 17 // TODO(jwmak): Windows support for system tracing. |
| 18 #if !defined(NO_TCMALLOC) && !defined(OS_NACL) && \ |
| 19 (defined(OS_LINUX) || defined(OS_ANDROID)) |
| 20 #define TRACE_SYSTEM_SUPPORTED 1 |
| 21 #endif |
| 22 |
| 23 |
| 24 namespace base { |
| 25 namespace debug { |
| 26 |
| 27 namespace { |
| 28 |
| 29 ///////////////////////////////////////////////////////////////////////////// |
| 30 // Holds profiled system stats until the tracing system needs to serialize it. |
| 31 class SystemProfilingStats : public base::debug::ConvertableToTraceFormat { |
| 32 public: |
| 33 SystemProfilingStats() { } |
| 34 virtual ~SystemProfilingStats() { |
| 35 #ifdef OS_LINUX |
| 36 delete meminfo; |
| 37 #endif |
| 38 } |
| 39 |
| 40 // Fills meminfo with system memory profiled stats. |
| 41 bool GetSystemProfilingStats(); |
| 42 |
| 43 // base::debug::ConvertableToTraceFormat overrides: |
| 44 virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE { |
| 45 #ifdef OS_LINUX |
| 46 AppendSystemProfileAsTraceFormat(meminfo, out); |
| 47 #endif |
| 48 } |
| 49 |
| 50 private: |
| 51 |
| 52 #ifdef OS_LINUX |
| 53 SystemMemoryInfoKB *meminfo; |
| 54 #endif |
| 55 |
| 56 DISALLOW_COPY_AND_ASSIGN(SystemProfilingStats); |
| 57 }; |
| 58 |
| 59 bool SystemProfilingStats::GetSystemProfilingStats() { |
| 60 #ifdef OS_LINUX |
| 61 meminfo = new SystemMemoryInfoKB(); |
| 62 if ((!GetSystemMemoryInfo(meminfo))) { |
| 63 DLOG(WARNING) << "Could not retrieve meminfo"; |
| 64 return false; |
| 65 } |
| 66 #endif |
| 67 |
| 68 return true; |
| 69 } |
| 70 |
| 71 // If system tracing is enabled, dumps a profile to the tracing system. |
| 72 void DumpSystemProfile() { |
| 73 DVLOG(1) << "DumpSystemProfile"; |
| 74 |
| 75 // Check to see if system tracing is enabled. |
| 76 bool enabled; |
| 77 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("system"), |
| 78 &enabled); |
| 79 if (!enabled) |
| 80 return; |
| 81 |
| 82 scoped_ptr<SystemProfilingStats> dump_holder(new SystemProfilingStats()); |
| 83 if (!dump_holder->GetSystemProfilingStats()) { |
| 84 return; |
| 85 } |
| 86 const int kSnapshotId = 1; |
| 87 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
| 88 TRACE_DISABLED_BY_DEFAULT("system"), |
| 89 "memory::Heap", |
| 90 kSnapshotId, |
| 91 dump_holder.PassAs<base::debug::ConvertableToTraceFormat>()); |
| 92 } |
| 93 } // namespace |
| 94 |
| 95 ////////////////////////////////////////////////////////////////////////////// |
| 96 |
| 97 TraceSystemController::TraceSystemController( |
| 98 scoped_refptr<MessageLoopProxy> message_loop_proxy) |
| 99 : message_loop_proxy_(message_loop_proxy), |
| 100 weak_factory_(this) { |
| 101 // Force the "system" category to show up in the trace viewer. |
| 102 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("system"), "init"); |
| 103 // Allow this to be instantiated on unsupported platforms, but don't run. |
| 104 #if defined(TRACE_SYSTEM_SUPPORTED) |
| 105 TraceLog::GetInstance()->AddEnabledStateObserver(this); |
| 106 #endif |
| 107 } |
| 108 |
| 109 TraceSystemController::~TraceSystemController() { |
| 110 #if defined(TRACE_SYSTEM_SUPPORTED) |
| 111 if (dump_timer_.IsRunning()) |
| 112 StopProfiling(); |
| 113 TraceLog::GetInstance()->RemoveEnabledStateObserver(this); |
| 114 #endif |
| 115 } |
| 116 |
| 117 // base::debug::TraceLog::EnabledStateChangedObserver overrides: |
| 118 void TraceSystemController::OnTraceLogEnabled() { |
| 119 DVLOG(1) << "OnTraceLogEnabled"; |
| 120 message_loop_proxy_->PostTask( |
| 121 FROM_HERE, |
| 122 base::Bind(&TraceSystemController::StartProfiling, |
| 123 weak_factory_.GetWeakPtr())); |
| 124 } |
| 125 |
| 126 void TraceSystemController::OnTraceLogDisabled() { |
| 127 DVLOG(1) << "OnTraceLogDisabled"; |
| 128 message_loop_proxy_->PostTask( |
| 129 FROM_HERE, |
| 130 base::Bind(&TraceSystemController::StopProfiling, |
| 131 weak_factory_.GetWeakPtr())); |
| 132 } |
| 133 |
| 134 void TraceSystemController::StartProfiling() { |
| 135 // Watch for the tracing framework sending enabling more than once. |
| 136 if (dump_timer_.IsRunning()) |
| 137 return; |
| 138 const int kDumpIntervalSeconds = 5; |
| 139 dump_timer_.Start(FROM_HERE, |
| 140 TimeDelta::FromSeconds(kDumpIntervalSeconds), |
| 141 base::Bind(&DumpSystemProfile)); |
| 142 } |
| 143 |
| 144 void TraceSystemController::StopProfiling() { |
| 145 dump_timer_.Stop(); |
| 146 } |
| 147 |
| 148 bool TraceSystemController::IsTimerRunningForTest() const { |
| 149 return dump_timer_.IsRunning(); |
| 150 } |
| 151 |
| 152 #if defined(OS_LINUX) |
| 153 void AppendSystemProfileAsTraceFormat(SystemMemoryInfoKB *meminfo, |
| 154 std::string* output) { |
| 155 // Handle the initial summary line. |
| 156 output->append("["); |
| 157 output->append("{\"mem_free\": "); |
| 158 |
| 159 // Used memory is: total - free - buffers - caches |
| 160 output->append(IntToString(meminfo->free + meminfo->buffers |
| 161 + meminfo->cached)); |
| 162 output->append(", \"current_bytes\": "); |
| 163 output->append(IntToString(meminfo->buffers)); |
| 164 output->append(", \"cached\": "); |
| 165 output->append(IntToString(meminfo->cached)); |
| 166 output->append(", \"active anon\": "); |
| 167 output->append(IntToString(meminfo->active_anon)); |
| 168 output->append(", \"inactive anon\": "); |
| 169 output->append(IntToString(meminfo->inactive_anon)); |
| 170 output->append(", \"active file\": "); |
| 171 output->append(IntToString(meminfo->active_file)); |
| 172 output->append(", \"inactive file\": "); |
| 173 output->append(IntToString(meminfo->inactive_file)); |
| 174 output->append(", \"dirty\": "); |
| 175 output->append(IntToString(meminfo->dirty)); |
| 176 output->append(", \"swap_used\": "); |
| 177 output->append(IntToString(meminfo->swap_total - meminfo->swap_free)); |
| 178 |
| 179 #if defined(OS_CHROMEOS) |
| 180 output->append("{, \"shmem\": "); |
| 181 output->append(IntToString(meminfo->shmem)); |
| 182 output->append("{, \"slab\": "); |
| 183 output->append(IntToString(meminfo->slab)); |
| 184 #endif // defined(OS_CHROMEOS) |
| 185 |
| 186 |
| 187 output->append(", \"trace\": \"\"}"); |
| 188 output->append("]\n"); |
| 189 |
| 190 // printf("output:\n%s",output->c_str()); |
| 191 } |
| 192 #endif |
| 193 |
| 194 } // namespace debug |
| 195 } // namespace base |
OLD | NEW |