| 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/trace_event/trace_event_impl.h" | 5 #include "base/trace_event/trace_event_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> |
| 8 | 9 |
| 9 #include "base/base_switches.h" | 10 #include "base/base_switches.h" |
| 10 #include "base/bind.h" | 11 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/debug/leak_annotations.h" | 13 #include "base/debug/leak_annotations.h" |
| 13 #include "base/float_util.h" | |
| 14 #include "base/format_macros.h" | 14 #include "base/format_macros.h" |
| 15 #include "base/json/string_escape.h" | 15 #include "base/json/string_escape.h" |
| 16 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 17 #include "base/memory/singleton.h" | 17 #include "base/memory/singleton.h" |
| 18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
| 19 #include "base/process/process_metrics.h" | 19 #include "base/process/process_metrics.h" |
| 20 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 21 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/string_split.h" | 22 #include "base/strings/string_split.h" |
| 23 #include "base/strings/string_tokenizer.h" | 23 #include "base/strings/string_tokenizer.h" |
| 24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 25 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
| 26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
| 27 #include "base/synchronization/cancellation_flag.h" | 27 #include "base/synchronization/cancellation_flag.h" |
| 28 #include "base/synchronization/waitable_event.h" | 28 #include "base/synchronization/waitable_event.h" |
| 29 #include "base/sys_info.h" | 29 #include "base/sys_info.h" |
| 30 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 30 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 31 #include "base/threading/platform_thread.h" | 31 #include "base/threading/platform_thread.h" |
| 32 #include "base/threading/thread_id_name_manager.h" | 32 #include "base/threading/thread_id_name_manager.h" |
| 33 #include "base/threading/worker_pool.h" |
| 33 #include "base/time/time.h" | 34 #include "base/time/time.h" |
| 34 #include "base/trace_event/trace_event.h" | 35 #include "base/trace_event/trace_event.h" |
| 35 #include "base/trace_event/trace_event_synthetic_delay.h" | 36 #include "base/trace_event/trace_event_synthetic_delay.h" |
| 36 | 37 |
| 37 #if defined(OS_WIN) | 38 #if defined(OS_WIN) |
| 39 #include "base/trace_event/trace_event_etw_export_win.h" |
| 38 #include "base/trace_event/trace_event_win.h" | 40 #include "base/trace_event/trace_event_win.h" |
| 39 #endif | 41 #endif |
| 40 | 42 |
| 41 class DeleteTraceLogForTesting { | 43 class DeleteTraceLogForTesting { |
| 42 public: | 44 public: |
| 43 static void Delete() { | 45 static void Delete() { |
| 44 Singleton<base::trace_event::TraceLog, | 46 Singleton<base::trace_event::TraceLog, |
| 45 LeakySingletonTraits<base::trace_event::TraceLog>>::OnExit(0); | 47 LeakySingletonTraits<base::trace_event::TraceLog>>::OnExit(0); |
| 46 } | 48 } |
| 47 }; | 49 }; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 66 const char kEnableSampling[] = "enable-sampling"; | 68 const char kEnableSampling[] = "enable-sampling"; |
| 67 const char kEnableSystrace[] = "enable-systrace"; | 69 const char kEnableSystrace[] = "enable-systrace"; |
| 68 | 70 |
| 69 // Controls the number of trace events we will buffer in-memory | 71 // Controls the number of trace events we will buffer in-memory |
| 70 // before throwing them away. | 72 // before throwing them away. |
| 71 const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize; | 73 const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize; |
| 72 const size_t kTraceEventVectorBigBufferChunks = | 74 const size_t kTraceEventVectorBigBufferChunks = |
| 73 512000000 / kTraceBufferChunkSize; | 75 512000000 / kTraceBufferChunkSize; |
| 74 const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize; | 76 const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize; |
| 75 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; | 77 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; |
| 76 const size_t kTraceEventBatchChunks = 1000 / kTraceBufferChunkSize; | 78 const size_t kTraceEventBufferSizeInBytes = 100 * 1024; |
| 77 // Can store results for 30 seconds with 1 ms sampling interval. | 79 // Can store results for 30 seconds with 1 ms sampling interval. |
| 78 const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize; | 80 const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize; |
| 79 // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events. | 81 // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events. |
| 80 const size_t kEchoToConsoleTraceEventBufferChunks = 256; | 82 const size_t kEchoToConsoleTraceEventBufferChunks = 256; |
| 81 | 83 |
| 82 const int kThreadFlushTimeoutMs = 3000; | 84 const int kThreadFlushTimeoutMs = 3000; |
| 83 | 85 |
| 84 #if !defined(OS_NACL) | 86 #if !defined(OS_NACL) |
| 85 // These categories will cause deadlock when ECHO_TO_CONSOLE. crbug.com/325575. | 87 // These categories will cause deadlock when ECHO_TO_CONSOLE. crbug.com/325575. |
| 86 const char kEchoToConsoleCategoryFilter[] = "-ipc,-task"; | 88 const char kEchoToConsoleCategoryFilter[] = "-ipc,-task"; |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 StringAppendF(out, "%" PRIu64, static_cast<uint64>(value.as_uint)); | 640 StringAppendF(out, "%" PRIu64, static_cast<uint64>(value.as_uint)); |
| 639 break; | 641 break; |
| 640 case TRACE_VALUE_TYPE_INT: | 642 case TRACE_VALUE_TYPE_INT: |
| 641 StringAppendF(out, "%" PRId64, static_cast<int64>(value.as_int)); | 643 StringAppendF(out, "%" PRId64, static_cast<int64>(value.as_int)); |
| 642 break; | 644 break; |
| 643 case TRACE_VALUE_TYPE_DOUBLE: { | 645 case TRACE_VALUE_TYPE_DOUBLE: { |
| 644 // FIXME: base/json/json_writer.cc is using the same code, | 646 // FIXME: base/json/json_writer.cc is using the same code, |
| 645 // should be made into a common method. | 647 // should be made into a common method. |
| 646 std::string real; | 648 std::string real; |
| 647 double val = value.as_double; | 649 double val = value.as_double; |
| 648 if (IsFinite(val)) { | 650 if (std::isfinite(val)) { |
| 649 real = DoubleToString(val); | 651 real = DoubleToString(val); |
| 650 // Ensure that the number has a .0 if there's no decimal or 'e'. This | 652 // Ensure that the number has a .0 if there's no decimal or 'e'. This |
| 651 // makes sure that when we read the JSON back, it's interpreted as a | 653 // makes sure that when we read the JSON back, it's interpreted as a |
| 652 // real rather than an int. | 654 // real rather than an int. |
| 653 if (real.find('.') == std::string::npos && | 655 if (real.find('.') == std::string::npos && |
| 654 real.find('e') == std::string::npos && | 656 real.find('e') == std::string::npos && |
| 655 real.find('E') == std::string::npos) { | 657 real.find('E') == std::string::npos) { |
| 656 real.append(".0"); | 658 real.append(".0"); |
| 657 } | 659 } |
| 658 // The JSON spec requires that non-integer values in the range (-1,1) | 660 // The JSON spec requires that non-integer values in the range (-1,1) |
| 659 // have a zero before the decimal point - ".52" is not valid, "0.52" is. | 661 // have a zero before the decimal point - ".52" is not valid, "0.52" is. |
| 660 if (real[0] == '.') { | 662 if (real[0] == '.') { |
| 661 real.insert(0, "0"); | 663 real.insert(0, "0"); |
| 662 } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { | 664 } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { |
| 663 // "-.1" bad "-0.1" good | 665 // "-.1" bad "-0.1" good |
| 664 real.insert(1, "0"); | 666 real.insert(1, "0"); |
| 665 } | 667 } |
| 666 } else if (IsNaN(val)){ | 668 } else if (std::isnan(val)){ |
| 667 // The JSON spec doesn't allow NaN and Infinity (since these are | 669 // The JSON spec doesn't allow NaN and Infinity (since these are |
| 668 // objects in EcmaScript). Use strings instead. | 670 // objects in EcmaScript). Use strings instead. |
| 669 real = "\"NaN\""; | 671 real = "\"NaN\""; |
| 670 } else if (val < 0) { | 672 } else if (val < 0) { |
| 671 real = "\"-Infinity\""; | 673 real = "\"-Infinity\""; |
| 672 } else { | 674 } else { |
| 673 real = "\"Infinity\""; | 675 real = "\"Infinity\""; |
| 674 } | 676 } |
| 675 StringAppendF(out, "%s", real.c_str()); | 677 StringAppendF(out, "%s", real.c_str()); |
| 676 break; | 678 break; |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 process_sort_index_(0), | 1203 process_sort_index_(0), |
| 1202 process_id_hash_(0), | 1204 process_id_hash_(0), |
| 1203 process_id_(0), | 1205 process_id_(0), |
| 1204 watch_category_(0), | 1206 watch_category_(0), |
| 1205 trace_options_(kInternalRecordUntilFull), | 1207 trace_options_(kInternalRecordUntilFull), |
| 1206 sampling_thread_handle_(0), | 1208 sampling_thread_handle_(0), |
| 1207 category_filter_(CategoryFilter::kDefaultCategoryFilterString), | 1209 category_filter_(CategoryFilter::kDefaultCategoryFilterString), |
| 1208 event_callback_category_filter_( | 1210 event_callback_category_filter_( |
| 1209 CategoryFilter::kDefaultCategoryFilterString), | 1211 CategoryFilter::kDefaultCategoryFilterString), |
| 1210 thread_shared_chunk_index_(0), | 1212 thread_shared_chunk_index_(0), |
| 1211 generation_(0) { | 1213 generation_(0), |
| 1214 use_worker_thread_(false) { |
| 1212 // Trace is enabled or disabled on one thread while other threads are | 1215 // Trace is enabled or disabled on one thread while other threads are |
| 1213 // accessing the enabled flag. We don't care whether edge-case events are | 1216 // accessing the enabled flag. We don't care whether edge-case events are |
| 1214 // traced or not, so we allow races on the enabled flag to keep the trace | 1217 // traced or not, so we allow races on the enabled flag to keep the trace |
| 1215 // macros fast. | 1218 // macros fast. |
| 1216 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 1219 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
| 1217 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, | 1220 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, |
| 1218 // sizeof(g_category_group_enabled), | 1221 // sizeof(g_category_group_enabled), |
| 1219 // "trace_event category enabled"); | 1222 // "trace_event category enabled"); |
| 1220 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { | 1223 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { |
| 1221 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], | 1224 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1283 const char* category_group = g_category_groups[category_index]; | 1286 const char* category_group = g_category_groups[category_index]; |
| 1284 if (mode_ == RECORDING_MODE && | 1287 if (mode_ == RECORDING_MODE && |
| 1285 category_filter_.IsCategoryGroupEnabled(category_group)) | 1288 category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1286 enabled_flag |= ENABLED_FOR_RECORDING; | 1289 enabled_flag |= ENABLED_FOR_RECORDING; |
| 1287 else if (mode_ == MONITORING_MODE && | 1290 else if (mode_ == MONITORING_MODE && |
| 1288 category_filter_.IsCategoryGroupEnabled(category_group)) | 1291 category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1289 enabled_flag |= ENABLED_FOR_MONITORING; | 1292 enabled_flag |= ENABLED_FOR_MONITORING; |
| 1290 if (event_callback_ && | 1293 if (event_callback_ && |
| 1291 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) | 1294 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1292 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; | 1295 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; |
| 1296 #if defined(OS_WIN) |
| 1297 if (base::trace_event::TraceEventETWExport::isETWExportEnabled()) |
| 1298 enabled_flag |= ENABLED_FOR_ETW_EXPORT; |
| 1299 #endif |
| 1300 |
| 1293 g_category_group_enabled[category_index] = enabled_flag; | 1301 g_category_group_enabled[category_index] = enabled_flag; |
| 1294 } | 1302 } |
| 1295 | 1303 |
| 1296 void TraceLog::UpdateCategoryGroupEnabledFlags() { | 1304 void TraceLog::UpdateCategoryGroupEnabledFlags() { |
| 1297 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); | 1305 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); |
| 1298 for (size_t i = 0; i < category_index; i++) | 1306 for (size_t i = 0; i < category_index; i++) |
| 1299 UpdateCategoryGroupEnabledFlag(i); | 1307 UpdateCategoryGroupEnabledFlag(i); |
| 1300 } | 1308 } |
| 1301 | 1309 |
| 1302 void TraceLog::UpdateSyntheticDelaysFromCategoryFilter() { | 1310 void TraceLog::UpdateSyntheticDelaysFromCategoryFilter() { |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 // Flush() works as the following: | 1682 // Flush() works as the following: |
| 1675 // 1. Flush() is called in threadA whose message loop is saved in | 1683 // 1. Flush() is called in threadA whose message loop is saved in |
| 1676 // flush_message_loop_proxy_; | 1684 // flush_message_loop_proxy_; |
| 1677 // 2. If thread_message_loops_ is not empty, threadA posts task to each message | 1685 // 2. If thread_message_loops_ is not empty, threadA posts task to each message |
| 1678 // loop to flush the thread local buffers; otherwise finish the flush; | 1686 // loop to flush the thread local buffers; otherwise finish the flush; |
| 1679 // 3. FlushCurrentThread() deletes the thread local event buffer: | 1687 // 3. FlushCurrentThread() deletes the thread local event buffer: |
| 1680 // - The last batch of events of the thread are flushed into the main buffer; | 1688 // - The last batch of events of the thread are flushed into the main buffer; |
| 1681 // - The message loop will be removed from thread_message_loops_; | 1689 // - The message loop will be removed from thread_message_loops_; |
| 1682 // If this is the last message loop, finish the flush; | 1690 // If this is the last message loop, finish the flush; |
| 1683 // 4. If any thread hasn't finish its flush in time, finish the flush. | 1691 // 4. If any thread hasn't finish its flush in time, finish the flush. |
| 1684 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { | 1692 void TraceLog::Flush(const TraceLog::OutputCallback& cb, |
| 1693 bool use_worker_thread) { |
| 1694 use_worker_thread_ = use_worker_thread; |
| 1685 if (IsEnabled()) { | 1695 if (IsEnabled()) { |
| 1686 // Can't flush when tracing is enabled because otherwise PostTask would | 1696 // Can't flush when tracing is enabled because otherwise PostTask would |
| 1687 // - generate more trace events; | 1697 // - generate more trace events; |
| 1688 // - deschedule the calling thread on some platforms causing inaccurate | 1698 // - deschedule the calling thread on some platforms causing inaccurate |
| 1689 // timing of the trace events. | 1699 // timing of the trace events. |
| 1690 scoped_refptr<RefCountedString> empty_result = new RefCountedString; | 1700 scoped_refptr<RefCountedString> empty_result = new RefCountedString; |
| 1691 if (!cb.is_null()) | 1701 if (!cb.is_null()) |
| 1692 cb.Run(empty_result, false); | 1702 cb.Run(empty_result, false); |
| 1693 LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled"; | 1703 LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled"; |
| 1694 return; | 1704 return; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 flush_message_loop_proxy_->PostDelayedTask( | 1738 flush_message_loop_proxy_->PostDelayedTask( |
| 1729 FROM_HERE, | 1739 FROM_HERE, |
| 1730 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), | 1740 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), |
| 1731 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); | 1741 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); |
| 1732 return; | 1742 return; |
| 1733 } | 1743 } |
| 1734 | 1744 |
| 1735 FinishFlush(generation); | 1745 FinishFlush(generation); |
| 1736 } | 1746 } |
| 1737 | 1747 |
| 1748 // Usually it runs on a different thread. |
| 1738 void TraceLog::ConvertTraceEventsToTraceFormat( | 1749 void TraceLog::ConvertTraceEventsToTraceFormat( |
| 1739 scoped_ptr<TraceBuffer> logged_events, | 1750 scoped_ptr<TraceBuffer> logged_events, |
| 1740 const TraceLog::OutputCallback& flush_output_callback) { | 1751 const TraceLog::OutputCallback& flush_output_callback) { |
| 1741 | 1752 |
| 1742 if (flush_output_callback.is_null()) | 1753 if (flush_output_callback.is_null()) |
| 1743 return; | 1754 return; |
| 1744 | 1755 |
| 1745 // The callback need to be called at least once even if there is no events | 1756 // The callback need to be called at least once even if there is no events |
| 1746 // to let the caller know the completion of flush. | 1757 // to let the caller know the completion of flush. |
| 1747 bool has_more_events = true; | 1758 bool has_more_events = true; |
| 1748 do { | 1759 do { |
| 1749 scoped_refptr<RefCountedString> json_events_str_ptr = | 1760 scoped_refptr<RefCountedString> json_events_str_ptr = |
| 1750 new RefCountedString(); | 1761 new RefCountedString(); |
| 1751 | 1762 |
| 1752 for (size_t i = 0; i < kTraceEventBatchChunks; ++i) { | 1763 while (json_events_str_ptr->size() < kTraceEventBufferSizeInBytes) { |
| 1753 const TraceBufferChunk* chunk = logged_events->NextChunk(); | 1764 const TraceBufferChunk* chunk = logged_events->NextChunk(); |
| 1754 if (!chunk) { | 1765 has_more_events = chunk != NULL; |
| 1755 has_more_events = false; | 1766 if (!chunk) |
| 1756 break; | 1767 break; |
| 1757 } | |
| 1758 for (size_t j = 0; j < chunk->size(); ++j) { | 1768 for (size_t j = 0; j < chunk->size(); ++j) { |
| 1759 if (i > 0 || j > 0) | 1769 if (json_events_str_ptr->size()) |
| 1760 json_events_str_ptr->data().append(",\n"); | 1770 json_events_str_ptr->data().append(",\n"); |
| 1761 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); | 1771 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); |
| 1762 } | 1772 } |
| 1763 } | 1773 } |
| 1764 | |
| 1765 flush_output_callback.Run(json_events_str_ptr, has_more_events); | 1774 flush_output_callback.Run(json_events_str_ptr, has_more_events); |
| 1766 } while (has_more_events); | 1775 } while (has_more_events); |
| 1767 } | 1776 } |
| 1768 | 1777 |
| 1769 void TraceLog::FinishFlush(int generation) { | 1778 void TraceLog::FinishFlush(int generation) { |
| 1770 scoped_ptr<TraceBuffer> previous_logged_events; | 1779 scoped_ptr<TraceBuffer> previous_logged_events; |
| 1771 OutputCallback flush_output_callback; | 1780 OutputCallback flush_output_callback; |
| 1772 | 1781 |
| 1773 if (!CheckGeneration(generation)) | 1782 if (!CheckGeneration(generation)) |
| 1774 return; | 1783 return; |
| 1775 | 1784 |
| 1776 { | 1785 { |
| 1777 AutoLock lock(lock_); | 1786 AutoLock lock(lock_); |
| 1778 | 1787 |
| 1779 previous_logged_events.swap(logged_events_); | 1788 previous_logged_events.swap(logged_events_); |
| 1780 UseNextTraceBuffer(); | 1789 UseNextTraceBuffer(); |
| 1781 thread_message_loops_.clear(); | 1790 thread_message_loops_.clear(); |
| 1782 | 1791 |
| 1783 flush_message_loop_proxy_ = NULL; | 1792 flush_message_loop_proxy_ = NULL; |
| 1784 flush_output_callback = flush_output_callback_; | 1793 flush_output_callback = flush_output_callback_; |
| 1785 flush_output_callback_.Reset(); | 1794 flush_output_callback_.Reset(); |
| 1786 } | 1795 } |
| 1787 | 1796 |
| 1797 if (use_worker_thread_ && |
| 1798 WorkerPool::PostTask( |
| 1799 FROM_HERE, |
| 1800 Bind(&TraceLog::ConvertTraceEventsToTraceFormat, |
| 1801 Passed(&previous_logged_events), |
| 1802 flush_output_callback), |
| 1803 true)) { |
| 1804 return; |
| 1805 } |
| 1806 |
| 1788 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), | 1807 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), |
| 1789 flush_output_callback); | 1808 flush_output_callback); |
| 1790 } | 1809 } |
| 1791 | 1810 |
| 1792 // Run in each thread holding a local event buffer. | 1811 // Run in each thread holding a local event buffer. |
| 1793 void TraceLog::FlushCurrentThread(int generation) { | 1812 void TraceLog::FlushCurrentThread(int generation) { |
| 1794 { | 1813 { |
| 1795 AutoLock lock(lock_); | 1814 AutoLock lock(lock_); |
| 1796 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { | 1815 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { |
| 1797 // This is late. The corresponding flush has finished. | 1816 // This is late. The corresponding flush has finished. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ... | 1920 // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ... |
| 1902 if (thread_is_in_trace_event_.Get()) | 1921 if (thread_is_in_trace_event_.Get()) |
| 1903 return handle; | 1922 return handle; |
| 1904 | 1923 |
| 1905 AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_); | 1924 AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_); |
| 1906 | 1925 |
| 1907 DCHECK(name); | 1926 DCHECK(name); |
| 1908 DCHECK(!timestamp.is_null()); | 1927 DCHECK(!timestamp.is_null()); |
| 1909 | 1928 |
| 1910 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) | 1929 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) |
| 1911 id ^= process_id_hash_; | 1930 id = MangleEventId(id); |
| 1912 | 1931 |
| 1913 TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp); | 1932 TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp); |
| 1914 TimeTicks now = flags & TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP ? | 1933 TimeTicks now = flags & TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP ? |
| 1915 OffsetNow() : offset_event_timestamp; | 1934 OffsetNow() : offset_event_timestamp; |
| 1916 TimeTicks thread_now = ThreadNow(); | 1935 TimeTicks thread_now = ThreadNow(); |
| 1917 | 1936 |
| 1918 ThreadLocalEventBuffer* thread_local_event_buffer = NULL; | 1937 ThreadLocalEventBuffer* thread_local_event_buffer = NULL; |
| 1919 // A ThreadLocalEventBuffer needs the message loop | 1938 // A ThreadLocalEventBuffer needs the message loop |
| 1920 // - to know when the thread exits; | 1939 // - to know when the thread exits; |
| 1921 // - to handle the final flush. | 1940 // - to handle the final flush. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1964 new_name) != existing_names.end(); | 1983 new_name) != existing_names.end(); |
| 1965 if (!found) { | 1984 if (!found) { |
| 1966 if (existing_names.size()) | 1985 if (existing_names.size()) |
| 1967 existing_name->second.push_back(','); | 1986 existing_name->second.push_back(','); |
| 1968 existing_name->second.append(new_name); | 1987 existing_name->second.append(new_name); |
| 1969 } | 1988 } |
| 1970 } | 1989 } |
| 1971 } | 1990 } |
| 1972 } | 1991 } |
| 1973 | 1992 |
| 1993 #if defined(OS_WIN) |
| 1994 // This is done sooner rather than later, to avoid creating the event and |
| 1995 // acquiring the lock, which is not needed for ETW as it's already threadsafe. |
| 1996 if (*category_group_enabled & ENABLED_FOR_ETW_EXPORT) |
| 1997 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id, |
| 1998 num_args, arg_names, arg_types, arg_values, |
| 1999 convertable_values); |
| 2000 #endif // OS_WIN |
| 2001 |
| 1974 std::string console_message; | 2002 std::string console_message; |
| 1975 if (*category_group_enabled & | 2003 if (*category_group_enabled & |
| 1976 (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { | 2004 (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { |
| 1977 OptionalAutoLock lock(&lock_); | 2005 OptionalAutoLock lock(&lock_); |
| 1978 | 2006 |
| 1979 TraceEvent* trace_event = NULL; | 2007 TraceEvent* trace_event = NULL; |
| 1980 if (thread_local_event_buffer) { | 2008 if (thread_local_event_buffer) { |
| 1981 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 2009 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
| 1982 } else { | 2010 } else { |
| 1983 lock.EnsureAcquired(); | 2011 lock.EnsureAcquired(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2170 watch_event_callback_ = callback; | 2198 watch_event_callback_ = callback; |
| 2171 } | 2199 } |
| 2172 | 2200 |
| 2173 void TraceLog::CancelWatchEvent() { | 2201 void TraceLog::CancelWatchEvent() { |
| 2174 AutoLock lock(lock_); | 2202 AutoLock lock(lock_); |
| 2175 subtle::NoBarrier_Store(&watch_category_, 0); | 2203 subtle::NoBarrier_Store(&watch_category_, 0); |
| 2176 watch_event_name_ = ""; | 2204 watch_event_name_ = ""; |
| 2177 watch_event_callback_.Reset(); | 2205 watch_event_callback_.Reset(); |
| 2178 } | 2206 } |
| 2179 | 2207 |
| 2208 uint64 TraceLog::MangleEventId(uint64 id) { |
| 2209 return id ^ process_id_hash_; |
| 2210 } |
| 2211 |
| 2180 void TraceLog::AddMetadataEventsWhileLocked() { | 2212 void TraceLog::AddMetadataEventsWhileLocked() { |
| 2181 lock_.AssertAcquired(); | 2213 lock_.AssertAcquired(); |
| 2182 | 2214 |
| 2183 #if !defined(OS_NACL) // NaCl shouldn't expose the process id. | 2215 #if !defined(OS_NACL) // NaCl shouldn't expose the process id. |
| 2184 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), | 2216 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), |
| 2185 0, | 2217 0, |
| 2186 "num_cpus", "number", | 2218 "num_cpus", "number", |
| 2187 base::SysInfo::NumberOfProcessors()); | 2219 base::SysInfo::NumberOfProcessors()); |
| 2188 #endif | 2220 #endif |
| 2189 | 2221 |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 } | 2634 } |
| 2603 | 2635 |
| 2604 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2636 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 2605 if (*category_group_enabled_) { | 2637 if (*category_group_enabled_) { |
| 2606 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2638 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
| 2607 name_, event_handle_); | 2639 name_, event_handle_); |
| 2608 } | 2640 } |
| 2609 } | 2641 } |
| 2610 | 2642 |
| 2611 } // namespace trace_event_internal | 2643 } // namespace trace_event_internal |
| OLD | NEW |