| 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/trace_log.h" | 5 #include "base/trace_event/trace_log.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 TraceLogStatus::~TraceLogStatus() {} | 457 TraceLogStatus::~TraceLogStatus() {} |
| 458 | 458 |
| 459 // static | 459 // static |
| 460 TraceLog* TraceLog::GetInstance() { | 460 TraceLog* TraceLog::GetInstance() { |
| 461 return Singleton<TraceLog, LeakySingletonTraits<TraceLog>>::get(); | 461 return Singleton<TraceLog, LeakySingletonTraits<TraceLog>>::get(); |
| 462 } | 462 } |
| 463 | 463 |
| 464 TraceLog::TraceLog() | 464 TraceLog::TraceLog() |
| 465 : enabled_modes_(0), | 465 : enabled_modes_(0), |
| 466 num_traces_recorded_(0), | 466 num_traces_recorded_(0), |
| 467 event_callback_(0), | |
| 468 dispatching_to_observer_list_(false), | 467 dispatching_to_observer_list_(false), |
| 469 process_sort_index_(0), | 468 process_sort_index_(0), |
| 470 process_id_hash_(0), | 469 process_id_hash_(0), |
| 471 process_id_(0), | 470 process_id_(0), |
| 472 watch_category_(0), | 471 watch_category_(0), |
| 473 trace_options_(kInternalRecordUntilFull), | 472 trace_options_(kInternalRecordUntilFull), |
| 474 trace_config_(TraceConfig()), | 473 trace_config_(TraceConfig()), |
| 475 event_callback_trace_config_(TraceConfig()), | |
| 476 thread_shared_chunk_index_(0), | 474 thread_shared_chunk_index_(0), |
| 477 generation_(0), | 475 generation_(0), |
| 478 use_worker_thread_(false) { | 476 use_worker_thread_(false) { |
| 479 // Trace is enabled or disabled on one thread while other threads are | 477 // Trace is enabled or disabled on one thread while other threads are |
| 480 // accessing the enabled flag. We don't care whether edge-case events are | 478 // accessing the enabled flag. We don't care whether edge-case events are |
| 481 // traced or not, so we allow races on the enabled flag to keep the trace | 479 // traced or not, so we allow races on the enabled flag to keep the trace |
| 482 // macros fast. | 480 // macros fast. |
| 483 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 481 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
| 484 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, | 482 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, |
| 485 // sizeof(g_category_group_enabled), | 483 // sizeof(g_category_group_enabled), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 } | 556 } |
| 559 | 557 |
| 560 void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { | 558 void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { |
| 561 unsigned char enabled_flag = 0; | 559 unsigned char enabled_flag = 0; |
| 562 const char* category_group = g_category_groups[category_index]; | 560 const char* category_group = g_category_groups[category_index]; |
| 563 if (enabled_modes_ & RECORDING_MODE && | 561 if (enabled_modes_ & RECORDING_MODE && |
| 564 trace_config_.IsCategoryGroupEnabled(category_group)) { | 562 trace_config_.IsCategoryGroupEnabled(category_group)) { |
| 565 enabled_flag |= ENABLED_FOR_RECORDING; | 563 enabled_flag |= ENABLED_FOR_RECORDING; |
| 566 } | 564 } |
| 567 | 565 |
| 568 if (event_callback_ && | |
| 569 event_callback_trace_config_.IsCategoryGroupEnabled(category_group)) { | |
| 570 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; | |
| 571 } | |
| 572 | |
| 573 #if defined(OS_WIN) | 566 #if defined(OS_WIN) |
| 574 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled( | 567 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled( |
| 575 category_group)) { | 568 category_group)) { |
| 576 enabled_flag |= ENABLED_FOR_ETW_EXPORT; | 569 enabled_flag |= ENABLED_FOR_ETW_EXPORT; |
| 577 } | 570 } |
| 578 #endif | 571 #endif |
| 579 | 572 |
| 580 // TODO(primiano): this is a temporary workaround for catapult:#2341, | 573 // TODO(primiano): this is a temporary workaround for catapult:#2341, |
| 581 // to guarantee that metadata events are always added even if the category | 574 // to guarantee that metadata events are always added even if the category |
| 582 // filter is "-*". See crbug.com/618054 for more details and long-term fix. | 575 // filter is "-*". See crbug.com/618054 for more details and long-term fix. |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 void TraceLog::CheckIfBufferIsFullWhileLocked() { | 990 void TraceLog::CheckIfBufferIsFullWhileLocked() { |
| 998 lock_.AssertAcquired(); | 991 lock_.AssertAcquired(); |
| 999 if (logged_events_->IsFull()) { | 992 if (logged_events_->IsFull()) { |
| 1000 if (buffer_limit_reached_timestamp_.is_null()) { | 993 if (buffer_limit_reached_timestamp_.is_null()) { |
| 1001 buffer_limit_reached_timestamp_ = OffsetNow(); | 994 buffer_limit_reached_timestamp_ = OffsetNow(); |
| 1002 } | 995 } |
| 1003 SetDisabledWhileLocked(RECORDING_MODE); | 996 SetDisabledWhileLocked(RECORDING_MODE); |
| 1004 } | 997 } |
| 1005 } | 998 } |
| 1006 | 999 |
| 1007 void TraceLog::SetEventCallbackEnabled(const TraceConfig& trace_config, | |
| 1008 EventCallback cb) { | |
| 1009 AutoLock lock(lock_); | |
| 1010 subtle::NoBarrier_Store(&event_callback_, | |
| 1011 reinterpret_cast<subtle::AtomicWord>(cb)); | |
| 1012 event_callback_trace_config_ = trace_config; | |
| 1013 UpdateCategoryGroupEnabledFlags(); | |
| 1014 } | |
| 1015 | |
| 1016 void TraceLog::SetEventCallbackDisabled() { | |
| 1017 AutoLock lock(lock_); | |
| 1018 subtle::NoBarrier_Store(&event_callback_, 0); | |
| 1019 UpdateCategoryGroupEnabledFlags(); | |
| 1020 } | |
| 1021 | |
| 1022 // Flush() works as the following: | 1000 // Flush() works as the following: |
| 1023 // 1. Flush() is called in thread A whose task runner is saved in | 1001 // 1. Flush() is called in thread A whose task runner is saved in |
| 1024 // flush_task_runner_; | 1002 // flush_task_runner_; |
| 1025 // 2. If thread_message_loops_ is not empty, thread A posts task to each message | 1003 // 2. If thread_message_loops_ is not empty, thread A posts task to each message |
| 1026 // loop to flush the thread local buffers; otherwise finish the flush; | 1004 // loop to flush the thread local buffers; otherwise finish the flush; |
| 1027 // 3. FlushCurrentThread() deletes the thread local event buffer: | 1005 // 3. FlushCurrentThread() deletes the thread local event buffer: |
| 1028 // - The last batch of events of the thread are flushed into the main buffer; | 1006 // - The last batch of events of the thread are flushed into the main buffer; |
| 1029 // - The message loop will be removed from thread_message_loops_; | 1007 // - The message loop will be removed from thread_message_loops_; |
| 1030 // If this is the last message loop, finish the flush; | 1008 // If this is the last message loop, finish the flush; |
| 1031 // 4. If any thread hasn't finish its flush in time, finish the flush. | 1009 // 4. If any thread hasn't finish its flush in time, finish the flush. |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1509 AutoLock lock(lock_); | 1487 AutoLock lock(lock_); |
| 1510 event_name_matches = watch_event_name_ == name; | 1488 event_name_matches = watch_event_name_ == name; |
| 1511 watch_event_callback_copy = watch_event_callback_; | 1489 watch_event_callback_copy = watch_event_callback_; |
| 1512 } | 1490 } |
| 1513 if (event_name_matches) { | 1491 if (event_name_matches) { |
| 1514 if (!watch_event_callback_copy.is_null()) | 1492 if (!watch_event_callback_copy.is_null()) |
| 1515 watch_event_callback_copy.Run(); | 1493 watch_event_callback_copy.Run(); |
| 1516 } | 1494 } |
| 1517 } | 1495 } |
| 1518 | 1496 |
| 1519 if (*category_group_enabled & ENABLED_FOR_EVENT_CALLBACK) { | |
| 1520 EventCallback event_callback = reinterpret_cast<EventCallback>( | |
| 1521 subtle::NoBarrier_Load(&event_callback_)); | |
| 1522 if (event_callback) { | |
| 1523 event_callback( | |
| 1524 offset_event_timestamp, | |
| 1525 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, | |
| 1526 category_group_enabled, name, scope, id, num_args, arg_names, | |
| 1527 arg_types, arg_values, flags); | |
| 1528 } | |
| 1529 } | |
| 1530 | |
| 1531 return handle; | 1497 return handle; |
| 1532 } | 1498 } |
| 1533 | 1499 |
| 1534 void TraceLog::AddMetadataEvent( | 1500 void TraceLog::AddMetadataEvent( |
| 1535 const unsigned char* category_group_enabled, | 1501 const unsigned char* category_group_enabled, |
| 1536 const char* name, | 1502 const char* name, |
| 1537 int num_args, | 1503 int num_args, |
| 1538 const char** arg_names, | 1504 const char** arg_names, |
| 1539 const unsigned char* arg_types, | 1505 const unsigned char* arg_types, |
| 1540 const unsigned long long* arg_values, | 1506 const unsigned long long* arg_values, |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 | 1634 |
| 1669 if (trace_options() & kInternalEchoToConsole) { | 1635 if (trace_options() & kInternalEchoToConsole) { |
| 1670 console_message = | 1636 console_message = |
| 1671 EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event); | 1637 EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event); |
| 1672 } | 1638 } |
| 1673 } | 1639 } |
| 1674 | 1640 |
| 1675 if (!console_message.empty()) | 1641 if (!console_message.empty()) |
| 1676 LOG(ERROR) << console_message; | 1642 LOG(ERROR) << console_message; |
| 1677 | 1643 |
| 1678 if (category_group_enabled_local & ENABLED_FOR_EVENT_CALLBACK) { | |
| 1679 EventCallback event_callback = reinterpret_cast<EventCallback>( | |
| 1680 subtle::NoBarrier_Load(&event_callback_)); | |
| 1681 if (event_callback) { | |
| 1682 event_callback( | |
| 1683 now, TRACE_EVENT_PHASE_END, category_group_enabled, name, | |
| 1684 trace_event_internal::kGlobalScope, trace_event_internal::kNoId, 0, | |
| 1685 nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_NONE); | |
| 1686 } | |
| 1687 } | |
| 1688 | |
| 1689 if (category_group_enabled_local & ENABLED_FOR_FILTERING) | 1644 if (category_group_enabled_local & ENABLED_FOR_FILTERING) |
| 1690 EndFilteredEvent(category_group_enabled, name, handle); | 1645 EndFilteredEvent(category_group_enabled, name, handle); |
| 1691 } | 1646 } |
| 1692 | 1647 |
| 1693 void TraceLog::SetWatchEvent(const std::string& category_name, | 1648 void TraceLog::SetWatchEvent(const std::string& category_name, |
| 1694 const std::string& event_name, | 1649 const std::string& event_name, |
| 1695 const WatchEventCallback& callback) { | 1650 const WatchEventCallback& callback) { |
| 1696 const unsigned char* category = | 1651 const unsigned char* category = |
| 1697 GetCategoryGroupEnabled(category_name.c_str()); | 1652 GetCategoryGroupEnabled(category_name.c_str()); |
| 1698 AutoLock lock(lock_); | 1653 AutoLock lock(lock_); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1971 } | 1926 } |
| 1972 | 1927 |
| 1973 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 1928 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 1974 if (*category_group_enabled_) { | 1929 if (*category_group_enabled_) { |
| 1975 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, | 1930 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, |
| 1976 event_handle_); | 1931 event_handle_); |
| 1977 } | 1932 } |
| 1978 } | 1933 } |
| 1979 | 1934 |
| 1980 } // namespace trace_event_internal | 1935 } // namespace trace_event_internal |
| OLD | NEW |