Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1472)

Unified Diff: base/trace_event/memory_dump_manager.cc

Issue 1995573003: [tracing] Introduce BACKGROUND mode in MemoryInfra (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: with periodic again. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/trace_event/memory_dump_manager.cc
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index b14d265f19ebbdc7945c141474957bece0aad403..26d8bc3e9c9f77325887c97b71fed33157989e41 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -16,6 +16,7 @@
#include "base/memory/ptr_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/timer/timer.h"
#include "base/trace_event/heap_profiler.h"
#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
@@ -46,26 +47,14 @@ const char* kTraceEventArgNames[] = {"dumps"};
const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
StaticAtomicSequenceNumber g_next_guid;
-uint32_t g_periodic_dumps_count = 0;
-uint32_t g_heavy_dumps_rate = 0;
MemoryDumpManager* g_instance_for_testing = nullptr;
-void RequestPeriodicGlobalDump() {
- MemoryDumpLevelOfDetail level_of_detail;
- if (g_heavy_dumps_rate == 0) {
- level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
- } else {
- level_of_detail = g_periodic_dumps_count == 0
- ? MemoryDumpLevelOfDetail::DETAILED
- : MemoryDumpLevelOfDetail::LIGHT;
-
- if (++g_periodic_dumps_count == g_heavy_dumps_rate)
- g_periodic_dumps_count = 0;
- }
-
- MemoryDumpManager::GetInstance()->RequestGlobalDump(
- MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
-}
+// The names of dump providers whitelisted for background tracing. Dump
+// providers can be added here only if the background mode dump has very
+// less performance and memory overhead.
+const char* const kDumpProviderWhitelist[] = {
+ "WhitelistedTestDumpProvider", // For testing.
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 I think a better approach is to: - Make this an em
ssid 2016/05/26 22:12:54 Yeah the problem was that i cannot get the array s
+};
// Callback wrapper to hook upon the completion of RequestGlobalDump() and
// inject trace markers.
@@ -109,8 +98,90 @@ struct SessionStateConvertableProxy : public ConvertableToTraceFormat {
GetterFunctPtr const getter_function;
};
+// Checks if the dump provider is in the whitelist.
+bool IsDumpProviderInWhitelist(const char* name) {
+ for (size_t i = 0; i < arraysize(kDumpProviderWhitelist); ++i) {
+ if (strcmp(name, kDumpProviderWhitelist[i]) == 0)
+ return true;
+ }
+ return false;
+}
+
} // namespace
+// Sets up periodic memory dump timers to start global dump requests based on
+// the dump triggers from trace config.
+class MemoryDumpManager::PeriodicGlobalDumpInvokeHelper {
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 nit: I think this should go after the constants be
ssid 2016/05/26 22:12:54 Added to the last.
+ public:
+ PeriodicGlobalDumpInvokeHelper(
+ const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list);
+ ~PeriodicGlobalDumpInvokeHelper();
+
+ // Periodically called by the timer.
+ void RequestPeriodicGlobalDump();
+
+ private:
+ RepeatingTimer periodic_dump_timer_;
+ uint32_t periodic_dumps_count_;
+ uint32_t light_dump_rate_;
+ uint32_t heavy_dump_rate_;
+};
+
+MemoryDumpManager::PeriodicGlobalDumpInvokeHelper::
+ PeriodicGlobalDumpInvokeHelper(
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 In general the constructor should not do actions,
ssid 2016/05/26 22:12:54 Makes sense.
+ const std::vector<TraceConfig::MemoryDumpConfig::Trigger>&
+ triggers_list)
+ : periodic_dumps_count_(0) {
+ uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max();
+ uint32_t light_dump_period_ms = 0;
+ uint32_t heavy_dump_period_ms = 0;
+ DCHECK(triggers_list.size());
+ DCHECK_LE(triggers_list.size(), 3u);
+ for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) {
+ if (config.level_of_detail == MemoryDumpLevelOfDetail::LIGHT) {
+ DCHECK_EQ(0u, light_dump_period_ms);
+ light_dump_period_ms = config.periodic_interval_ms;
+ } else if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
+ DCHECK_EQ(0u, heavy_dump_period_ms);
+ heavy_dump_period_ms = config.periodic_interval_ms;
+ }
+ min_timer_period_ms =
+ std::min(min_timer_period_ms, config.periodic_interval_ms);
+ }
+
+ // Do not start timer if period is 0 for any trigger.
+ if (!min_timer_period_ms)
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 Hmm this is a bit contra-intuitive. THis means tha
ssid 2016/05/26 22:12:54 Yeah, I was thinking it is useful to specify mode
+ return;
+
+ DCHECK_EQ(0u, light_dump_period_ms % min_timer_period_ms);
+ light_dump_rate_ = light_dump_period_ms / min_timer_period_ms;
+ DCHECK_EQ(0u, heavy_dump_rate_ % min_timer_period_ms);
+ heavy_dump_rate_ = heavy_dump_period_ms / min_timer_period_ms;
+
+ periodic_dump_timer_.Start(
+ FROM_HERE, TimeDelta::FromMilliseconds(min_timer_period_ms),
+ base::Bind(&PeriodicGlobalDumpInvokeHelper::RequestPeriodicGlobalDump,
+ base::Unretained(this)));
+}
+
+MemoryDumpManager::PeriodicGlobalDumpInvokeHelper::
+ ~PeriodicGlobalDumpInvokeHelper() {
+ periodic_dump_timer_.Stop();
+}
+
+void MemoryDumpManager::PeriodicGlobalDumpInvokeHelper::
+ RequestPeriodicGlobalDump() {
+ MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND;
+ if (light_dump_rate_ > 0 && periodic_dumps_count_ % light_dump_rate_ == 0)
+ level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
+ if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0)
+ level_of_detail = MemoryDumpLevelOfDetail::DETAILED;
+ ++periodic_dumps_count_;
+
+ MemoryDumpManager::GetInstance()->RequestGlobalDump(
+ MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
+}
+
// static
const char* const MemoryDumpManager::kTraceCategory =
TRACE_DISABLED_BY_DEFAULT("memory-infra");
@@ -449,6 +520,15 @@ void MemoryDumpManager::SetupNextMemoryDump(
MemoryDumpProviderInfo* mdpinfo =
pmd_async_state->pending_dump_providers.back().get();
+ // If we are in background tracing, we should invoke only the whitelisted
+ // providers. Ignore other providers and continue.
+ if (pmd_async_state->req_args.level_of_detail ==
+ MemoryDumpLevelOfDetail::BACKGROUND &&
+ mdpinfo->disabled_for_background_mode) {
+ pmd_async_state->pending_dump_providers.pop_back();
+ return SetupNextMemoryDump(std::move(pmd_async_state));
+ }
+
// If the dump provider did not specify a task runner affinity, dump on
// |dump_thread_| which is already checked above for presence.
SequencedTaskRunner* task_runner = mdpinfo->task_runner.get();
@@ -632,78 +712,64 @@ void MemoryDumpManager::OnTraceLogEnabled() {
return;
}
- AutoLock lock(lock_);
ssid 2016/05/23 18:17:03 This unnecessarily locks the whole function. I can
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 Where is the call to RequestGlobalDump? In the tim
ssid 2016/05/26 22:12:54 We currently do the first dump after 250ms of star
-
- DCHECK(delegate_); // At this point we must have a delegate.
- session_state_ = new MemoryDumpSessionState;
-
+ const TraceConfig trace_config =
+ TraceLog::GetInstance()->GetCurrentTraceConfig();
+ scoped_refptr<MemoryDumpSessionState> session_state =
+ new MemoryDumpSessionState;
if (heap_profiling_enabled_) {
// If heap profiling is enabled, the stack frame deduplicator and type name
// deduplicator will be in use. Add a metadata events to write the frames
// and type IDs.
- session_state_->SetStackFrameDeduplicator(
+ session_state->SetStackFrameDeduplicator(
WrapUnique(new StackFrameDeduplicator));
- session_state_->SetTypeNameDeduplicator(
+ session_state->SetTypeNameDeduplicator(
WrapUnique(new TypeNameDeduplicator));
TRACE_EVENT_API_ADD_METADATA_EVENT(
TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames",
"stackFrames",
- WrapUnique(
- new SessionStateConvertableProxy<StackFrameDeduplicator>(
- session_state_,
- &MemoryDumpSessionState::stack_frame_deduplicator)));
+ WrapUnique(new SessionStateConvertableProxy<StackFrameDeduplicator>(
+ session_state, &MemoryDumpSessionState::stack_frame_deduplicator)));
TRACE_EVENT_API_ADD_METADATA_EVENT(
TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames",
"typeNames",
WrapUnique(new SessionStateConvertableProxy<TypeNameDeduplicator>(
- session_state_, &MemoryDumpSessionState::type_name_deduplicator)));
+ session_state, &MemoryDumpSessionState::type_name_deduplicator)));
}
+ session_state->SetMemoryDumpConfig(trace_config.memory_dump_config());
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 nit: seems a bit more logical to have this after s
ssid 2016/05/26 22:12:54 Done.
- DCHECK(!dump_thread_);
- dump_thread_ = std::move(dump_thread);
- subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
+ {
+ AutoLock lock(lock_);
- // TODO(primiano): This is a temporary hack to disable periodic memory dumps
- // when running memory benchmarks until telemetry uses TraceConfig to
- // enable/disable periodic dumps. See crbug.com/529184 .
- if (!is_coordinator_ ||
- CommandLine::ForCurrentProcess()->HasSwitch(
- "enable-memory-benchmarking")) {
- return;
+ DCHECK(delegate_); // At this point we must have a delegate.
+ session_state_ = session_state;
+
+ DCHECK(!dump_thread_);
+ dump_thread_ = std::move(dump_thread);
+
+ subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
+
+ // TODO(primiano): This is a temporary hack to disable periodic memory dumps
+ // when running memory benchmarks until telemetry uses TraceConfig to
+ // enable/disable periodic dumps. See crbug.com/529184 .
+ if (!is_coordinator_ ||
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ "enable-memory-benchmarking")) {
+ return;
+ }
}
// Enable periodic dumps. At the moment the periodic support is limited to at
- // most one low-detail periodic dump and at most one high-detail periodic
- // dump. If both are specified the high-detail period must be an integer
- // multiple of the low-level one.
- g_periodic_dumps_count = 0;
- const TraceConfig trace_config =
- TraceLog::GetInstance()->GetCurrentTraceConfig();
- session_state_->SetMemoryDumpConfig(trace_config.memory_dump_config());
ssid 2016/05/23 18:17:03 I think this needs to be set before the check for
+ // most one periodic trigger per dump mode. All intervals should be an integer
+ // multiple of the smallest interval specified.
const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list =
trace_config.memory_dump_config().triggers;
- if (triggers_list.empty())
- return;
-
- uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max();
- uint32_t heavy_dump_period_ms = 0;
- DCHECK_LE(triggers_list.size(), 2u);
- for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) {
- DCHECK(config.periodic_interval_ms);
- if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED)
- heavy_dump_period_ms = config.periodic_interval_ms;
- min_timer_period_ms =
- std::min(min_timer_period_ms, config.periodic_interval_ms);
+ if (!triggers_list.empty()) {
Primiano Tucci (use gerrit) 2016/05/26 17:20:53 maybe just always pass the triggers and to this ch
ssid 2016/05/26 22:12:54 Done.
+ periodic_dump_helper_.reset(
+ new PeriodicGlobalDumpInvokeHelper(triggers_list));
}
- DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms);
- g_heavy_dumps_rate = heavy_dump_period_ms / min_timer_period_ms;
-
- periodic_dump_timer_.Start(FROM_HERE,
- TimeDelta::FromMilliseconds(min_timer_period_ms),
- base::Bind(&RequestPeriodicGlobalDump));
}
void MemoryDumpManager::OnTraceLogDisabled() {
@@ -720,7 +786,7 @@ void MemoryDumpManager::OnTraceLogDisabled() {
// Thread stops are blocking and must be performed outside of the |lock_|
// or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it).
- periodic_dump_timer_.Stop();
+ periodic_dump_helper_.reset();
if (dump_thread)
dump_thread->Stop();
}
@@ -739,7 +805,8 @@ MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo(
task_runner(std::move(task_runner)),
options(options),
consecutive_failures(0),
- disabled(false) {}
+ disabled(false),
+ disabled_for_background_mode(!IsDumpProviderInWhitelist(name)) {}
MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() {}

Powered by Google App Engine
This is Rietveld 408576698