Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/trace_event/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 | 31 |
| 32 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
| 33 #include "base/trace_event/winheap_dump_provider_win.h" | 33 #include "base/trace_event/winheap_dump_provider_win.h" |
| 34 #endif | 34 #endif |
| 35 | 35 |
| 36 namespace base { | 36 namespace base { |
| 37 namespace trace_event { | 37 namespace trace_event { |
| 38 | 38 |
| 39 namespace { | 39 namespace { |
| 40 | 40 |
| 41 // Throttle mmaps at a rate of once every kHeavyMmapsDumpsRate standard dumps. | |
| 42 const int kHeavyDumpsRate = 8; // 250 ms * 8 = 2000 ms. | |
| 43 const int kDumpIntervalMs = 250; | |
| 44 const int kTraceEventNumArgs = 1; | 41 const int kTraceEventNumArgs = 1; |
| 45 const char* kTraceEventArgNames[] = {"dumps"}; | 42 const char* kTraceEventArgNames[] = {"dumps"}; |
| 46 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | 43 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; |
| 47 | 44 |
| 48 StaticAtomicSequenceNumber g_next_guid; | 45 StaticAtomicSequenceNumber g_next_guid; |
| 49 uint32 g_periodic_dumps_count = 0; | 46 uint32 g_periodic_dumps_count = 0; |
| 47 uint32 g_shortest_dump_interval_ms; | |
| 50 MemoryDumpManager* g_instance_for_testing = nullptr; | 48 MemoryDumpManager* g_instance_for_testing = nullptr; |
| 51 | 49 |
| 52 void RequestPeriodicGlobalDump() { | 50 void RequestPeriodicGlobalDump() { |
| 53 MemoryDumpArgs::LevelOfDetail dump_level_of_detail = | 51 MemoryDumpArgs dump_args = {MemoryDumpArgs::LevelOfDetail::LOW}; |
| 54 g_periodic_dumps_count == 0 ? MemoryDumpArgs::LevelOfDetail::HIGH | 52 TraceConfig trace_config = TraceLog::GetInstance()->GetCurrentTraceConfig(); |
| 55 : MemoryDumpArgs::LevelOfDetail::LOW; | |
| 56 if (++g_periodic_dumps_count == kHeavyDumpsRate) | |
| 57 g_periodic_dumps_count = 0; | |
| 58 | 53 |
| 59 MemoryDumpArgs dump_args = {dump_level_of_detail}; | 54 // Assign the highest dump args among the periodic dump triggers whose |
| 55 // interval end at current time. | |
| 56 for (const TraceConfig::MemoryDumpTriggerConfig& config : | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
All this seems way too complex. I don't like the i
| |
| 57 trace_config.memory_dump_config()) { | |
| 58 if (g_periodic_dumps_count % | |
| 59 (config.periodic_interval_ms / g_shortest_dump_interval_ms) == | |
| 60 0) { | |
| 61 if (dump_args.level_of_detail < config.level_of_detail) | |
| 62 dump_args.level_of_detail = config.level_of_detail; | |
| 63 } | |
| 64 } | |
| 65 g_periodic_dumps_count++; | |
| 66 | |
| 60 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 67 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
| 61 MemoryDumpType::PERIODIC_INTERVAL, dump_args); | 68 MemoryDumpType::PERIODIC_INTERVAL, dump_args); |
| 62 } | 69 } |
| 63 | 70 |
| 64 } // namespace | 71 } // namespace |
| 65 | 72 |
| 66 // TODO(ssid): Start using TraceConfig and remove this. | |
| 67 // static | 73 // static |
| 68 const char* const MemoryDumpManager::kTraceCategory = | 74 const char* const MemoryDumpManager::kTraceCategory = |
| 69 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 75 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
| 70 | 76 |
| 71 // static | 77 // static |
| 72 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; | 78 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; |
| 73 | 79 |
| 74 // static | 80 // static |
| 75 const uint64 MemoryDumpManager::kInvalidTracingProcessId = 0; | 81 const uint64 MemoryDumpManager::kInvalidTracingProcessId = 0; |
| 76 | 82 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 // invoking the callback while holding the lock_. | 393 // invoking the callback while holding the lock_. |
| 388 task_runner->PostTask(FROM_HERE, | 394 task_runner->PostTask(FROM_HERE, |
| 389 Bind(callback, dump_guid, false /* success */)); | 395 Bind(callback, dump_guid, false /* success */)); |
| 390 } | 396 } |
| 391 | 397 |
| 392 void MemoryDumpManager::OnTraceLogEnabled() { | 398 void MemoryDumpManager::OnTraceLogEnabled() { |
| 393 // TODO(primiano): at this point we query TraceLog::GetCurrentCategoryFilter | 399 // TODO(primiano): at this point we query TraceLog::GetCurrentCategoryFilter |
| 394 // to figure out (and cache) which dumpers should be enabled or not. | 400 // to figure out (and cache) which dumpers should be enabled or not. |
| 395 // For the moment piggy back everything on the generic "memory" category. | 401 // For the moment piggy back everything on the generic "memory" category. |
| 396 bool enabled; | 402 bool enabled; |
| 397 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled); | 403 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled); |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
You don't need this check anymore right?
| |
| 398 | 404 |
| 399 // Initialize the TraceLog for the current thread. This is to avoid that the | 405 // Initialize the TraceLog for the current thread. This is to avoid that the |
| 400 // TraceLog memory dump provider is registered lazily in the PostTask() below | 406 // TraceLog memory dump provider is registered lazily in the PostTask() below |
| 401 // while the |lock_| is taken; | 407 // while the |lock_| is taken; |
| 402 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); | 408 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); |
| 403 | 409 |
| 404 AutoLock lock(lock_); | 410 AutoLock lock(lock_); |
| 405 | 411 |
| 406 // There is no point starting the tracing without a delegate. | 412 // There is no point starting the tracing without a delegate. |
| 407 if (!enabled || !delegate_) { | 413 if (!enabled || !delegate_) { |
| 408 // Disable all the providers. | 414 // Disable all the providers. |
| 409 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) | 415 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) |
| 410 it->disabled = true; | 416 it->disabled = true; |
| 411 return; | 417 return; |
| 412 } | 418 } |
| 413 | 419 |
| 414 session_state_ = new MemoryDumpSessionState(); | 420 session_state_ = new MemoryDumpSessionState(); |
| 415 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) { | 421 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) { |
| 416 it->disabled = false; | 422 it->disabled = false; |
| 417 it->consecutive_failures = 0; | 423 it->consecutive_failures = 0; |
| 418 } | 424 } |
| 419 | 425 |
| 420 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); | 426 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
| 421 | 427 |
| 422 // TODO(primiano): This is a temporary hack to disable periodic memory dumps | 428 // TODO(primiano): This is a temporary hack to disable periodic memory dumps |
| 423 // when running memory benchmarks until they can be enabled/disabled in | 429 // when running memory benchmarks until they can be enabled/disabled in |
| 424 // base::trace_event::TraceConfig. See https://goo.gl/5Hj3o0. | 430 // base::trace_event::TraceConfig. See https://goo.gl/5Hj3o0. |
| 425 // The same mechanism should be used to disable periodic dumps in tests. | 431 // The same mechanism should be used to disable periodic dumps in tests. |
| 426 if (delegate_->IsCoordinatorProcess() && | 432 if (!delegate_->IsCoordinatorProcess() || |
| 427 !CommandLine::ForCurrentProcess()->HasSwitch( | 433 CommandLine::ForCurrentProcess()->HasSwitch( |
| 428 "enable-memory-benchmarking") && | 434 "enable-memory-benchmarking") || |
| 429 !disable_periodic_dumps_for_testing_) { | 435 disable_periodic_dumps_for_testing_) { |
| 430 g_periodic_dumps_count = 0; | 436 return; |
| 431 periodic_dump_timer_.Start(FROM_HERE, | |
| 432 TimeDelta::FromMilliseconds(kDumpIntervalMs), | |
| 433 base::Bind(&RequestPeriodicGlobalDump)); | |
| 434 } | 437 } |
| 438 | |
| 439 g_periodic_dumps_count = 0; | |
| 440 const TraceConfig trace_config = | |
| 441 TraceLog::GetInstance()->GetCurrentTraceConfig(); | |
| 442 const TraceConfig::MemoryDumpConfig& config_list = | |
| 443 trace_config.memory_dump_config(); | |
| 444 if (!config_list.size()) | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
if (config_list.empty()) ?
| |
| 445 return; | |
| 446 | |
| 447 g_shortest_dump_interval_ms = std::numeric_limits<uint32>::max(); | |
| 448 for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) { | |
| 449 if (g_shortest_dump_interval_ms > config.periodic_interval_ms) | |
| 450 g_shortest_dump_interval_ms = config.periodic_interval_ms; | |
| 451 } | |
| 452 DCHECK_NE(g_shortest_dump_interval_ms, std::numeric_limits<uint32>::max()); | |
| 453 | |
| 454 // It does not make sense to have dumps at varying intervals. | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
Is not that it doesnt' make sense.
The deal is tha
| |
| 455 for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) | |
| 456 DCHECK_EQ(0u, config.periodic_interval_ms % g_shortest_dump_interval_ms); | |
| 457 | |
| 458 periodic_dump_timer_.Start( | |
| 459 FROM_HERE, TimeDelta::FromMilliseconds(g_shortest_dump_interval_ms), | |
| 460 base::Bind(&RequestPeriodicGlobalDump)); | |
| 435 } | 461 } |
| 436 | 462 |
| 437 void MemoryDumpManager::OnTraceLogDisabled() { | 463 void MemoryDumpManager::OnTraceLogDisabled() { |
| 438 AutoLock lock(lock_); | 464 AutoLock lock(lock_); |
| 439 periodic_dump_timer_.Stop(); | 465 periodic_dump_timer_.Stop(); |
| 440 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); | 466 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); |
| 441 session_state_ = nullptr; | 467 session_state_ = nullptr; |
| 442 } | 468 } |
| 443 | 469 |
| 444 uint64 MemoryDumpManager::GetTracingProcessId() const { | 470 uint64 MemoryDumpManager::GetTracingProcessId() const { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 474 next_dump_provider(next_dump_provider), | 500 next_dump_provider(next_dump_provider), |
| 475 callback(callback), | 501 callback(callback), |
| 476 task_runner(MessageLoop::current()->task_runner()) { | 502 task_runner(MessageLoop::current()->task_runner()) { |
| 477 } | 503 } |
| 478 | 504 |
| 479 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { | 505 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { |
| 480 } | 506 } |
| 481 | 507 |
| 482 } // namespace trace_event | 508 } // namespace trace_event |
| 483 } // namespace base | 509 } // namespace base |
| OLD | NEW |