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 |