Chromium Code Reviews| 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/base_switches.h" | 9 #include "base/base_switches.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "base/strings/string_tokenizer.h" | 25 #include "base/strings/string_tokenizer.h" |
| 26 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
| 27 #include "base/strings/stringprintf.h" | 27 #include "base/strings/stringprintf.h" |
| 28 #include "base/strings/utf_string_conversions.h" | 28 #include "base/strings/utf_string_conversions.h" |
| 29 #include "base/synchronization/cancellation_flag.h" | 29 #include "base/synchronization/cancellation_flag.h" |
| 30 #include "base/synchronization/waitable_event.h" | 30 #include "base/synchronization/waitable_event.h" |
| 31 #include "base/sys_info.h" | 31 #include "base/sys_info.h" |
| 32 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 32 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 33 #include "base/threading/platform_thread.h" | 33 #include "base/threading/platform_thread.h" |
| 34 #include "base/threading/thread_id_name_manager.h" | 34 #include "base/threading/thread_id_name_manager.h" |
| 35 #include "base/threading/worker_pool.h" | |
| 35 #include "base/time/time.h" | 36 #include "base/time/time.h" |
| 36 | 37 |
| 37 #if defined(OS_WIN) | 38 #if defined(OS_WIN) |
| 38 #include "base/debug/trace_event_win.h" | 39 #include "base/debug/trace_event_win.h" |
| 39 #endif | 40 #endif |
| 40 | 41 |
| 41 class DeleteTraceLogForTesting { | 42 class DeleteTraceLogForTesting { |
| 42 public: | 43 public: |
| 43 static void Delete() { | 44 static void Delete() { |
| 44 Singleton<base::debug::TraceLog, | 45 Singleton<base::debug::TraceLog, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 66 const char kEnableSampling[] = "enable-sampling"; | 67 const char kEnableSampling[] = "enable-sampling"; |
| 67 const char kEnableSystrace[] = "enable-systrace"; | 68 const char kEnableSystrace[] = "enable-systrace"; |
| 68 | 69 |
| 69 // Controls the number of trace events we will buffer in-memory | 70 // Controls the number of trace events we will buffer in-memory |
| 70 // before throwing them away. | 71 // before throwing them away. |
| 71 const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize; | 72 const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize; |
| 72 const size_t kTraceEventVectorBigBufferChunks = | 73 const size_t kTraceEventVectorBigBufferChunks = |
| 73 512000000 / kTraceBufferChunkSize; | 74 512000000 / kTraceBufferChunkSize; |
| 74 const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize; | 75 const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize; |
| 75 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; | 76 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; |
| 76 const size_t kTraceEventBatchChunks = 1000 / kTraceBufferChunkSize; | 77 const size_t kTraceEventBufferSize = 10 * 1024 * 1024; |
|
yurys
2014/12/17 08:50:30
Can you rename it to kTraceEventBufferSizeInBytes
loislo
2014/12/17 08:56:45
Done.
| |
| 77 // Can store results for 30 seconds with 1 ms sampling interval. | 78 // Can store results for 30 seconds with 1 ms sampling interval. |
| 78 const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize; | 79 const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize; |
| 79 // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events. | 80 // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events. |
| 80 const size_t kEchoToConsoleTraceEventBufferChunks = 256; | 81 const size_t kEchoToConsoleTraceEventBufferChunks = 256; |
| 81 | 82 |
| 82 const int kThreadFlushTimeoutMs = 3000; | 83 const int kThreadFlushTimeoutMs = 3000; |
| 83 | 84 |
| 84 #if !defined(OS_NACL) | 85 #if !defined(OS_NACL) |
| 85 // These categories will cause deadlock when ECHO_TO_CONSOLE. crbug.com/325575. | 86 // These categories will cause deadlock when ECHO_TO_CONSOLE. crbug.com/325575. |
| 86 const char kEchoToConsoleCategoryFilter[] = "-ipc,-task"; | 87 const char kEchoToConsoleCategoryFilter[] = "-ipc,-task"; |
| (...skipping 1644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1731 flush_message_loop_proxy_->PostDelayedTask( | 1732 flush_message_loop_proxy_->PostDelayedTask( |
| 1732 FROM_HERE, | 1733 FROM_HERE, |
| 1733 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), | 1734 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), |
| 1734 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); | 1735 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); |
| 1735 return; | 1736 return; |
| 1736 } | 1737 } |
| 1737 | 1738 |
| 1738 FinishFlush(generation); | 1739 FinishFlush(generation); |
| 1739 } | 1740 } |
| 1740 | 1741 |
| 1742 // Usually it runs on a different thread. | |
| 1741 void TraceLog::ConvertTraceEventsToTraceFormat( | 1743 void TraceLog::ConvertTraceEventsToTraceFormat( |
| 1742 scoped_ptr<TraceBuffer> logged_events, | 1744 scoped_ptr<TraceBuffer> logged_events, |
| 1743 const TraceLog::OutputCallback& flush_output_callback) { | 1745 const TraceLog::OutputCallback& flush_output_callback) { |
| 1744 | 1746 |
| 1745 if (flush_output_callback.is_null()) | 1747 if (flush_output_callback.is_null()) |
| 1746 return; | 1748 return; |
| 1747 | 1749 |
| 1748 // The callback need to be called at least once even if there is no events | 1750 // The callback need to be called at least once even if there is no events |
| 1749 // to let the caller know the completion of flush. | 1751 // to let the caller know the completion of flush. |
| 1750 bool has_more_events = true; | 1752 bool has_more_events = true; |
| 1751 do { | 1753 do { |
| 1752 scoped_refptr<RefCountedString> json_events_str_ptr = | 1754 scoped_refptr<RefCountedString> json_events_str_ptr = |
| 1753 new RefCountedString(); | 1755 new RefCountedString(); |
| 1754 | 1756 |
| 1755 for (size_t i = 0; i < kTraceEventBatchChunks; ++i) { | 1757 while (json_events_str_ptr->size() < kTraceEventBufferSize) { |
| 1756 const TraceBufferChunk* chunk = logged_events->NextChunk(); | 1758 const TraceBufferChunk* chunk = logged_events->NextChunk(); |
| 1757 if (!chunk) { | 1759 has_more_events = chunk != NULL; |
| 1758 has_more_events = false; | 1760 if (!chunk) |
| 1759 break; | 1761 break; |
| 1760 } | |
| 1761 for (size_t j = 0; j < chunk->size(); ++j) { | 1762 for (size_t j = 0; j < chunk->size(); ++j) { |
| 1762 if (i > 0 || j > 0) | 1763 if (json_events_str_ptr->size()) |
| 1763 json_events_str_ptr->data().append(","); | 1764 json_events_str_ptr->data().append(","); |
| 1764 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); | 1765 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); |
| 1765 } | 1766 } |
| 1766 } | 1767 } |
| 1767 | |
| 1768 flush_output_callback.Run(json_events_str_ptr, has_more_events); | 1768 flush_output_callback.Run(json_events_str_ptr, has_more_events); |
|
yurys
2014/12/17 08:50:30
Is it OK to run this callback on a worker thread?
loislo
2014/12/17 08:56:45
Done.
| |
| 1769 } while (has_more_events); | 1769 } while (has_more_events); |
| 1770 } | 1770 } |
| 1771 | 1771 |
| 1772 void TraceLog::FinishFlush(int generation) { | 1772 void TraceLog::FinishFlush(int generation) { |
| 1773 scoped_ptr<TraceBuffer> previous_logged_events; | 1773 scoped_ptr<TraceBuffer> previous_logged_events; |
| 1774 OutputCallback flush_output_callback; | 1774 OutputCallback flush_output_callback; |
| 1775 | 1775 |
| 1776 if (!CheckGeneration(generation)) | 1776 if (!CheckGeneration(generation)) |
| 1777 return; | 1777 return; |
| 1778 | 1778 |
| 1779 { | 1779 { |
| 1780 AutoLock lock(lock_); | 1780 AutoLock lock(lock_); |
| 1781 | 1781 |
| 1782 previous_logged_events.swap(logged_events_); | 1782 previous_logged_events.swap(logged_events_); |
| 1783 UseNextTraceBuffer(); | 1783 UseNextTraceBuffer(); |
| 1784 thread_message_loops_.clear(); | 1784 thread_message_loops_.clear(); |
| 1785 | 1785 |
| 1786 flush_message_loop_proxy_ = NULL; | 1786 flush_message_loop_proxy_ = NULL; |
| 1787 flush_output_callback = flush_output_callback_; | 1787 flush_output_callback = flush_output_callback_; |
| 1788 flush_output_callback_.Reset(); | 1788 flush_output_callback_.Reset(); |
| 1789 } | 1789 } |
| 1790 | 1790 |
| 1791 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), | 1791 if (!WorkerPool::PostTask( |
| 1792 flush_output_callback); | 1792 FROM_HERE, |
| 1793 Bind(&TraceLog::ConvertTraceEventsToTraceFormat, | |
| 1794 Passed(&previous_logged_events), | |
| 1795 flush_output_callback), | |
| 1796 true)) { | |
| 1797 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), | |
| 1798 flush_output_callback); | |
| 1799 } | |
| 1793 } | 1800 } |
| 1794 | 1801 |
| 1795 // Run in each thread holding a local event buffer. | 1802 // Run in each thread holding a local event buffer. |
| 1796 void TraceLog::FlushCurrentThread(int generation) { | 1803 void TraceLog::FlushCurrentThread(int generation) { |
| 1797 { | 1804 { |
| 1798 AutoLock lock(lock_); | 1805 AutoLock lock(lock_); |
| 1799 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { | 1806 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { |
| 1800 // This is late. The corresponding flush has finished. | 1807 // This is late. The corresponding flush has finished. |
| 1801 return; | 1808 return; |
| 1802 } | 1809 } |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2585 } | 2592 } |
| 2586 | 2593 |
| 2587 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2594 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 2588 if (*category_group_enabled_) { | 2595 if (*category_group_enabled_) { |
| 2589 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2596 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
| 2590 name_, event_handle_); | 2597 name_, event_handle_); |
| 2591 } | 2598 } |
| 2592 } | 2599 } |
| 2593 | 2600 |
| 2594 } // namespace trace_event_internal | 2601 } // namespace trace_event_internal |
| OLD | NEW |