OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 if (notification_) | 339 if (notification_) |
340 callback_copy_.Run(notification_); | 340 callback_copy_.Run(notification_); |
341 } | 341 } |
342 | 342 |
343 // static | 343 // static |
344 TraceLog* TraceLog::GetInstance() { | 344 TraceLog* TraceLog::GetInstance() { |
345 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); | 345 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); |
346 } | 346 } |
347 | 347 |
348 TraceLog::TraceLog() | 348 TraceLog::TraceLog() |
349 : enabled_(false), | 349 : enable_count_(0), |
350 dispatching_to_observer_list_(false), | 350 dispatching_to_observer_list_(false), |
351 watch_category_(NULL) { | 351 watch_category_(NULL) { |
352 // Trace is enabled or disabled on one thread while other threads are | 352 // Trace is enabled or disabled on one thread while other threads are |
353 // accessing the enabled flag. We don't care whether edge-case events are | 353 // accessing the enabled flag. We don't care whether edge-case events are |
354 // traced or not, so we allow races on the enabled flag to keep the trace | 354 // traced or not, so we allow races on the enabled flag to keep the trace |
355 // macros fast. | 355 // macros fast. |
356 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 356 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
357 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), | 357 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), |
358 // "trace_event category enabled"); | 358 // "trace_event category enabled"); |
359 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { | 359 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 "must increase TRACE_EVENT_MAX_CATEGORIES"; | 437 "must increase TRACE_EVENT_MAX_CATEGORIES"; |
438 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { | 438 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { |
439 int new_index = g_category_index++; | 439 int new_index = g_category_index++; |
440 // Don't hold on to the name pointer, so that we can create categories | 440 // Don't hold on to the name pointer, so that we can create categories |
441 // with strings not known at compile time (this is required by | 441 // with strings not known at compile time (this is required by |
442 // SetWatchEvent). | 442 // SetWatchEvent). |
443 const char* new_name = base::strdup(name); | 443 const char* new_name = base::strdup(name); |
444 ANNOTATE_LEAKING_OBJECT_PTR(new_name); | 444 ANNOTATE_LEAKING_OBJECT_PTR(new_name); |
445 g_categories[new_index] = new_name; | 445 g_categories[new_index] = new_name; |
446 DCHECK(!g_category_enabled[new_index]); | 446 DCHECK(!g_category_enabled[new_index]); |
447 if (enabled_) { | 447 if (enable_count_) { |
448 // Note that if both included and excluded_categories are empty, the | 448 // Note that if both included and excluded_categories are empty, the |
449 // else clause below excludes nothing, thereby enabling this category. | 449 // else clause below excludes nothing, thereby enabling this category. |
450 if (!included_categories_.empty()) { | 450 if (!included_categories_.empty()) { |
451 EnableMatchingCategory(new_index, included_categories_, | 451 EnableMatchingCategory(new_index, included_categories_, |
452 CATEGORY_ENABLED, 0); | 452 CATEGORY_ENABLED, 0); |
453 } else { | 453 } else { |
454 EnableMatchingCategory(new_index, excluded_categories_, | 454 EnableMatchingCategory(new_index, excluded_categories_, |
455 0, CATEGORY_ENABLED); | 455 0, CATEGORY_ENABLED); |
456 } | 456 } |
457 } else { | 457 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
470 | 470 |
471 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { | 471 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { |
472 AutoLock lock(lock_); | 472 AutoLock lock(lock_); |
473 for (int i = 0; i < g_category_index; i++) | 473 for (int i = 0; i < g_category_index; i++) |
474 categories->push_back(g_categories[i]); | 474 categories->push_back(g_categories[i]); |
475 } | 475 } |
476 | 476 |
477 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, | 477 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, |
478 const std::vector<std::string>& excluded_categories) { | 478 const std::vector<std::string>& excluded_categories) { |
479 AutoLock lock(lock_); | 479 AutoLock lock(lock_); |
480 if (enabled_) | 480 |
| 481 if (enable_count_++ > 0) { |
| 482 // Tracing is already enabled, so just merge in enabled categories. |
| 483 // We only expand the set of enabled categories upon nested SetEnable(). |
| 484 if (!included_categories_.empty() && !included_categories.empty()) { |
| 485 included_categories_.insert(included_categories_.end(), |
| 486 included_categories.begin(), |
| 487 included_categories.end()); |
| 488 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); |
| 489 } else { |
| 490 // If either old or new included categories are empty, allow all events. |
| 491 included_categories_.clear(); |
| 492 excluded_categories_.clear(); |
| 493 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); |
| 494 } |
481 return; | 495 return; |
| 496 } |
482 | 497 |
483 if (dispatching_to_observer_list_) { | 498 if (dispatching_to_observer_list_) { |
484 DLOG(ERROR) << | 499 DLOG(ERROR) << |
485 "Cannot manipulate TraceLog::Enabled state from an observer."; | 500 "Cannot manipulate TraceLog::Enabled state from an observer."; |
486 return; | 501 return; |
487 } | 502 } |
488 | 503 |
489 dispatching_to_observer_list_ = true; | 504 dispatching_to_observer_list_ = true; |
490 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 505 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
491 OnTraceLogWillEnable()); | 506 OnTraceLogWillEnable()); |
492 dispatching_to_observer_list_ = false; | 507 dispatching_to_observer_list_ = false; |
493 | 508 |
494 logged_events_.reserve(1024); | 509 logged_events_.reserve(1024); |
495 enabled_ = true; | |
496 included_categories_ = included_categories; | 510 included_categories_ = included_categories; |
497 excluded_categories_ = excluded_categories; | 511 excluded_categories_ = excluded_categories; |
498 // Note that if both included and excluded_categories are empty, the else | 512 // Note that if both included and excluded_categories are empty, the else |
499 // clause below excludes nothing, thereby enabling all categories. | 513 // clause below excludes nothing, thereby enabling all categories. |
500 if (!included_categories_.empty()) | 514 if (!included_categories_.empty()) |
501 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 515 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); |
502 else | 516 else |
503 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 517 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); |
504 } | 518 } |
505 | 519 |
(...skipping 15 matching lines...) Expand all Loading... |
521 else | 535 else |
522 excluded.push_back(category); | 536 excluded.push_back(category); |
523 } | 537 } |
524 SetEnabled(included, excluded); | 538 SetEnabled(included, excluded); |
525 } | 539 } |
526 | 540 |
527 void TraceLog::GetEnabledTraceCategories( | 541 void TraceLog::GetEnabledTraceCategories( |
528 std::vector<std::string>* included_out, | 542 std::vector<std::string>* included_out, |
529 std::vector<std::string>* excluded_out) { | 543 std::vector<std::string>* excluded_out) { |
530 AutoLock lock(lock_); | 544 AutoLock lock(lock_); |
531 if (enabled_) { | 545 if (enable_count_) { |
532 *included_out = included_categories_; | 546 *included_out = included_categories_; |
533 *excluded_out = excluded_categories_; | 547 *excluded_out = excluded_categories_; |
534 } | 548 } |
535 } | 549 } |
536 | 550 |
537 void TraceLog::SetDisabled() { | 551 void TraceLog::SetDisabled() { |
538 AutoLock lock(lock_); | 552 AutoLock lock(lock_); |
539 if (!enabled_) | 553 DCHECK(enable_count_ > 0); |
| 554 if (--enable_count_ != 0) |
540 return; | 555 return; |
541 | 556 |
542 if (dispatching_to_observer_list_) { | 557 if (dispatching_to_observer_list_) { |
543 DLOG(ERROR) | 558 DLOG(ERROR) |
544 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 559 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
545 return; | 560 return; |
546 } | 561 } |
547 | 562 |
548 dispatching_to_observer_list_ = true; | 563 dispatching_to_observer_list_ = true; |
549 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 564 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
550 OnTraceLogWillDisable()); | 565 OnTraceLogWillDisable()); |
551 dispatching_to_observer_list_ = false; | 566 dispatching_to_observer_list_ = false; |
552 | 567 |
553 enabled_ = false; | |
554 included_categories_.clear(); | 568 included_categories_.clear(); |
555 excluded_categories_.clear(); | 569 excluded_categories_.clear(); |
556 watch_category_ = NULL; | 570 watch_category_ = NULL; |
557 watch_event_name_ = ""; | 571 watch_event_name_ = ""; |
558 for (int i = 0; i < g_category_index; i++) | 572 for (int i = 0; i < g_category_index; i++) |
559 g_category_enabled[i] = 0; | 573 g_category_enabled[i] = 0; |
560 AddThreadNameMetadataEvents(); | 574 AddThreadNameMetadataEvents(); |
561 #if defined(OS_ANDROID) | 575 #if defined(OS_ANDROID) |
562 AddClockSyncMetadataEvents(); | 576 AddClockSyncMetadataEvents(); |
563 #endif | 577 #endif |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 unsigned long long pid = static_cast<unsigned long long>(process_id_); | 794 unsigned long long pid = static_cast<unsigned long long>(process_id_); |
781 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; | 795 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; |
782 } | 796 } |
783 | 797 |
784 void TraceLog::SetTimeOffset(TimeDelta offset) { | 798 void TraceLog::SetTimeOffset(TimeDelta offset) { |
785 time_offset_ = offset; | 799 time_offset_ = offset; |
786 } | 800 } |
787 | 801 |
788 } // namespace debug | 802 } // namespace debug |
789 } // namespace base | 803 } // namespace base |
OLD | NEW |