Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: base/debug/trace_event_impl.cc

Issue 750183008: DevTools: Parallelize trace messages serialization. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« base/debug/trace_event_impl.h ('K') | « base/debug/trace_event_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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;
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 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
1741 void TraceLog::ConvertTraceEventsToTraceFormat( 1742 void TraceLog::ConvertTraceEventsToTraceFormat(
1742 scoped_ptr<TraceBuffer> logged_events,
1743 const TraceLog::OutputCallback& flush_output_callback) { 1743 const TraceLog::OutputCallback& flush_output_callback) {
1744 1744
1745 if (flush_output_callback.is_null()) 1745 scoped_ptr<TraceBuffer> events_for_serialization;
1746 return; 1746 {
1747 1747 AutoLock lock(lock_);
1748 events_for_serialization.swap(previous_logged_events_);
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 = new RefCountedString;
1753 new RefCountedString();
1754 1755
1755 for (size_t i = 0; i < kTraceEventBatchChunks; ++i) { 1756 while (json_events_str_ptr->size() < kTraceEventBufferSize) {
1756 const TraceBufferChunk* chunk = logged_events->NextChunk(); 1757 const TraceBufferChunk* chunk = events_for_serialization->NextChunk();
1757 if (!chunk) { 1758 has_more_events = chunk;
1758 has_more_events = false; 1759 if (!chunk)
1759 break; 1760 break;
1760 }
1761 for (size_t j = 0; j < chunk->size(); ++j) { 1761 for (size_t j = 0; j < chunk->size(); ++j) {
1762 if (i > 0 || j > 0) 1762 if (json_events_str_ptr->size())
1763 json_events_str_ptr->data().append(","); 1763 json_events_str_ptr->data().append(",");
1764 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); 1764 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()));
1765 } 1765 }
1766 } 1766 }
1767
1768 flush_output_callback.Run(json_events_str_ptr, has_more_events); 1767 flush_output_callback.Run(json_events_str_ptr, has_more_events);
1769 } while (has_more_events); 1768 } while (has_more_events);
1770 } 1769 }
1771 1770
1772 void TraceLog::FinishFlush(int generation) { 1771 void TraceLog::FinishFlush(int generation) {
1773 scoped_ptr<TraceBuffer> previous_logged_events;
1774 OutputCallback flush_output_callback; 1772 OutputCallback flush_output_callback;
1773 bool async_task_started = false;
1775 1774
1776 if (!CheckGeneration(generation)) 1775 if (!CheckGeneration(generation))
1777 return; 1776 return;
1778 1777
1779 { 1778 {
1780 AutoLock lock(lock_); 1779 AutoLock lock(lock_);
1781 1780
1782 previous_logged_events.swap(logged_events_); 1781 previous_logged_events_.swap(logged_events_);
1783 UseNextTraceBuffer(); 1782 UseNextTraceBuffer();
1784 thread_message_loops_.clear(); 1783 thread_message_loops_.clear();
1785 1784
1786 flush_message_loop_proxy_ = NULL; 1785 flush_message_loop_proxy_ = NULL;
1787 flush_output_callback = flush_output_callback_; 1786 flush_output_callback = flush_output_callback_;
1788 flush_output_callback_.Reset(); 1787 flush_output_callback_.Reset();
1788
1789 async_task_started = WorkerPool::PostTask(
Sami 2014/12/05 16:33:01 Is there any reason to expect this to fail in prac
loislo 2014/12/05 21:38:45 As far as I see it has different behavior on the P
Sami 2014/12/08 14:35:36 Interesting. Looks like QueueUserWorkItem can fail
1790 FROM_HERE,
1791 Bind(&TraceLog::ConvertTraceEventsToTraceFormat,
1792 Unretained(this),
1793 flush_output_callback),
1794 true);
1789 } 1795 }
1790 1796 if (!async_task_started)
1791 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 1797 ConvertTraceEventsToTraceFormat(flush_output_callback);
1792 flush_output_callback);
1793 } 1798 }
1794 1799
1795 // Run in each thread holding a local event buffer. 1800 // Run in each thread holding a local event buffer.
1796 void TraceLog::FlushCurrentThread(int generation) { 1801 void TraceLog::FlushCurrentThread(int generation) {
1797 { 1802 {
1798 AutoLock lock(lock_); 1803 AutoLock lock(lock_);
1799 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { 1804 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) {
1800 // This is late. The corresponding flush has finished. 1805 // This is late. The corresponding flush has finished.
1801 return; 1806 return;
1802 } 1807 }
(...skipping 29 matching lines...) Expand all
1832 thread_message_loops_.begin(); 1837 thread_message_loops_.begin();
1833 it != thread_message_loops_.end(); ++it) { 1838 it != thread_message_loops_.end(); ++it) {
1834 LOG(WARNING) << "Thread: " << (*it)->thread_name(); 1839 LOG(WARNING) << "Thread: " << (*it)->thread_name();
1835 } 1840 }
1836 } 1841 }
1837 FinishFlush(generation); 1842 FinishFlush(generation);
1838 } 1843 }
1839 1844
1840 void TraceLog::FlushButLeaveBufferIntact( 1845 void TraceLog::FlushButLeaveBufferIntact(
1841 const TraceLog::OutputCallback& flush_output_callback) { 1846 const TraceLog::OutputCallback& flush_output_callback) {
1842 scoped_ptr<TraceBuffer> previous_logged_events;
1843 { 1847 {
1844 AutoLock lock(lock_); 1848 AutoLock lock(lock_);
1845 AddMetadataEventsWhileLocked(); 1849 AddMetadataEventsWhileLocked();
1846 if (thread_shared_chunk_) { 1850 if (thread_shared_chunk_) {
1847 // Return the chunk to the main buffer to flush the sampling data. 1851 // Return the chunk to the main buffer to flush the sampling data.
1848 logged_events_->ReturnChunk(thread_shared_chunk_index_, 1852 logged_events_->ReturnChunk(thread_shared_chunk_index_,
1849 thread_shared_chunk_.Pass()); 1853 thread_shared_chunk_.Pass());
1850 } 1854 }
1851 previous_logged_events = logged_events_->CloneForIteration().Pass(); 1855 previous_logged_events_ = logged_events_->CloneForIteration().Pass();
1852 } // release lock 1856 } // release lock
1853 1857 ConvertTraceEventsToTraceFormat(flush_output_callback);
1854 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(),
1855 flush_output_callback);
1856 } 1858 }
1857 1859
1858 void TraceLog::UseNextTraceBuffer() { 1860 void TraceLog::UseNextTraceBuffer() {
1859 logged_events_.reset(CreateTraceBuffer()); 1861 logged_events_.reset(CreateTraceBuffer());
1860 subtle::NoBarrier_AtomicIncrement(&generation_, 1); 1862 subtle::NoBarrier_AtomicIncrement(&generation_, 1);
1861 thread_shared_chunk_.reset(); 1863 thread_shared_chunk_.reset();
1862 thread_shared_chunk_index_ = 0; 1864 thread_shared_chunk_index_ = 0;
1863 } 1865 }
1864 1866
1865 TraceEventHandle TraceLog::AddTraceEvent( 1867 TraceEventHandle TraceLog::AddTraceEvent(
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2572 } 2574 }
2573 2575
2574 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2576 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2575 if (*category_group_enabled_) { 2577 if (*category_group_enabled_) {
2576 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2578 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2577 name_, event_handle_); 2579 name_, event_handle_);
2578 } 2580 }
2579 } 2581 }
2580 2582
2581 } // namespace trace_event_internal 2583 } // namespace trace_event_internal
OLDNEW
« base/debug/trace_event_impl.h ('K') | « base/debug/trace_event_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698