ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / base / trace_event / memory_dump_manager.cc
blobcbed2380039c78bea20c3dcc7c602000f59d61bf
1 // Copyright 2015 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.
5 #include "base/trace_event/memory_dump_manager.h"
7 #include <algorithm>
9 #include "base/atomic_sequence_num.h"
10 #include "base/compiler_specific.h"
11 #include "base/trace_event/memory_dump_provider.h"
12 #include "base/trace_event/process_memory_dump.h"
13 #include "base/trace_event/trace_event_argument.h"
15 namespace base {
16 namespace trace_event {
18 namespace {
20 MemoryDumpManager* g_instance_for_testing = nullptr;
21 const int kTraceEventNumArgs = 1;
22 const char* kTraceEventArgNames[] = {"dumps"};
23 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
24 StaticAtomicSequenceNumber g_next_guid;
26 const char* DumpPointTypeToString(const DumpPointType& dump_point_type) {
27 switch (dump_point_type) {
28 case DumpPointType::TASK_BEGIN:
29 return "TASK_BEGIN";
30 case DumpPointType::TASK_END:
31 return "TASK_END";
32 case DumpPointType::PERIODIC_INTERVAL:
33 return "PERIODIC_INTERVAL";
34 case DumpPointType::EXPLICITLY_TRIGGERED:
35 return "EXPLICITLY_TRIGGERED";
37 NOTREACHED();
38 return "UNKNOWN";
42 // TODO(primiano): this should be smarter and should do something similar to
43 // trace event synthetic delays.
44 const char MemoryDumpManager::kTraceCategory[] =
45 TRACE_DISABLED_BY_DEFAULT("memory-dumps");
47 // static
48 MemoryDumpManager* MemoryDumpManager::GetInstance() {
49 if (g_instance_for_testing)
50 return g_instance_for_testing;
52 return Singleton<MemoryDumpManager,
53 LeakySingletonTraits<MemoryDumpManager>>::get();
56 // static
57 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) {
58 g_instance_for_testing = instance;
61 MemoryDumpManager::MemoryDumpManager() : memory_tracing_enabled_(0) {
64 MemoryDumpManager::~MemoryDumpManager() {
65 base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
68 void MemoryDumpManager::Initialize() {
69 TRACE_EVENT0(kTraceCategory, "init"); // Add to trace-viewer category list.
70 trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
73 void MemoryDumpManager::RegisterDumpProvider(MemoryDumpProvider* mdp) {
74 AutoLock lock(lock_);
75 if (std::find(dump_providers_registered_.begin(),
76 dump_providers_registered_.end(),
77 mdp) != dump_providers_registered_.end()) {
78 return;
80 dump_providers_registered_.push_back(mdp);
83 void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) {
84 AutoLock lock(lock_);
86 // Remove from the registered providers list.
87 auto it = std::find(dump_providers_registered_.begin(),
88 dump_providers_registered_.end(), mdp);
89 if (it != dump_providers_registered_.end())
90 dump_providers_registered_.erase(it);
92 // Remove from the enabled providers list. This is to deal with the case that
93 // UnregisterDumpProvider is called while the trace is enabled.
94 it = std::find(dump_providers_enabled_.begin(), dump_providers_enabled_.end(),
95 mdp);
96 if (it != dump_providers_enabled_.end())
97 dump_providers_enabled_.erase(it);
100 void MemoryDumpManager::RequestDumpPoint(DumpPointType dump_point_type) {
101 // TODO(primiano): this will have more logic to coordinate dump points across
102 // multiple processes via IPC. See crbug.com/462930.
104 // Bail out immediately if tracing is not enabled at all.
105 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_)))
106 return;
108 // TODO(primiano): Make guid actually unique (cross-process) by hashing it
109 // with the PID. See crbug.com/462931 for details.
110 const uint64 guid = g_next_guid.GetNext();
111 CreateLocalDumpPoint(dump_point_type, guid);
114 void MemoryDumpManager::BroadcastDumpRequest() {
115 NOTREACHED(); // TODO(primiano): implement IPC synchronization.
118 // Creates a dump point for the current process and appends it to the trace.
119 void MemoryDumpManager::CreateLocalDumpPoint(DumpPointType dump_point_type,
120 uint64 guid) {
121 bool did_any_provider_dump = false;
122 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump());
124 // Serialize dump point generation so that memory dump providers don't have to
125 // deal with thread safety.
127 AutoLock lock(lock_);
128 for (auto it = dump_providers_enabled_.begin();
129 it != dump_providers_enabled_.end();) {
130 MemoryDumpProvider* dump_provider = *it;
131 if (dump_provider->DumpInto(pmd.get())) {
132 did_any_provider_dump = true;
133 ++it;
134 } else {
135 LOG(ERROR) << "The memory dumper " << dump_provider->GetFriendlyName()
136 << " failed, possibly due to sandboxing (crbug.com/461788), "
137 "disabling it for current process. Try restarting chrome "
138 "with the --no-sandbox switch.";
139 it = dump_providers_enabled_.erase(it);
144 // Don't create a dump point if all the dumpers failed.
145 if (!did_any_provider_dump)
146 return;
148 scoped_refptr<ConvertableToTraceFormat> event_value(new TracedValue());
149 pmd->AsValueInto(static_cast<TracedValue*>(event_value.get()));
150 const char* const event_name = DumpPointTypeToString(dump_point_type);
152 TRACE_EVENT_API_ADD_TRACE_EVENT(
153 TRACE_EVENT_PHASE_MEMORY_DUMP,
154 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, guid,
155 kTraceEventNumArgs, kTraceEventArgNames, kTraceEventArgTypes,
156 NULL /* arg_values */, &event_value, TRACE_EVENT_FLAG_HAS_ID);
159 void MemoryDumpManager::OnTraceLogEnabled() {
160 // TODO(primiano): at this point we query TraceLog::GetCurrentCategoryFilter
161 // to figure out (and cache) which dumpers should be enabled or not.
162 // For the moment piggy back everything on the generic "memory" category.
163 bool enabled;
164 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled);
166 AutoLock lock(lock_);
167 if (enabled) {
168 dump_providers_enabled_.assign(dump_providers_registered_.begin(),
169 dump_providers_registered_.end());
170 } else {
171 dump_providers_enabled_.clear();
173 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
176 void MemoryDumpManager::OnTraceLogDisabled() {
177 AutoLock lock(lock_);
178 dump_providers_enabled_.clear();
179 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
182 } // namespace trace_event
183 } // namespace base