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

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

Issue 1035783002: Re-land issue 750183008 (Parallelize trace messages serialization) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months 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
« no previous file with comments | « base/trace_event/trace_event_impl.h ('k') | content/browser/tracing/tracing_controller_impl.cc » ('j') | 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/trace_event/trace_event_impl.h" 5 #include "base/trace_event/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 12 matching lines...) Expand all
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)
38 #include "base/trace_event/trace_event_win.h" 39 #include "base/trace_event/trace_event_win.h"
39 #endif 40 #endif
40 41
41 class DeleteTraceLogForTesting { 42 class DeleteTraceLogForTesting {
42 public: 43 public:
(...skipping 23 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 kTraceEventBufferSizeInBytes = 100 * 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 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 process_sort_index_(0), 1202 process_sort_index_(0),
1202 process_id_hash_(0), 1203 process_id_hash_(0),
1203 process_id_(0), 1204 process_id_(0),
1204 watch_category_(0), 1205 watch_category_(0),
1205 trace_options_(kInternalRecordUntilFull), 1206 trace_options_(kInternalRecordUntilFull),
1206 sampling_thread_handle_(0), 1207 sampling_thread_handle_(0),
1207 category_filter_(CategoryFilter::kDefaultCategoryFilterString), 1208 category_filter_(CategoryFilter::kDefaultCategoryFilterString),
1208 event_callback_category_filter_( 1209 event_callback_category_filter_(
1209 CategoryFilter::kDefaultCategoryFilterString), 1210 CategoryFilter::kDefaultCategoryFilterString),
1210 thread_shared_chunk_index_(0), 1211 thread_shared_chunk_index_(0),
1211 generation_(0) { 1212 generation_(0),
1213 use_worker_thread_(false) {
1212 // Trace is enabled or disabled on one thread while other threads are 1214 // 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 1215 // 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 1216 // traced or not, so we allow races on the enabled flag to keep the trace
1215 // macros fast. 1217 // macros fast.
1216 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: 1218 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots:
1217 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, 1219 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled,
1218 // sizeof(g_category_group_enabled), 1220 // sizeof(g_category_group_enabled),
1219 // "trace_event category enabled"); 1221 // "trace_event category enabled");
1220 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { 1222 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) {
1221 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], 1223 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i],
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 // Flush() works as the following: 1676 // Flush() works as the following:
1675 // 1. Flush() is called in threadA whose message loop is saved in 1677 // 1. Flush() is called in threadA whose message loop is saved in
1676 // flush_message_loop_proxy_; 1678 // flush_message_loop_proxy_;
1677 // 2. If thread_message_loops_ is not empty, threadA posts task to each message 1679 // 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; 1680 // loop to flush the thread local buffers; otherwise finish the flush;
1679 // 3. FlushCurrentThread() deletes the thread local event buffer: 1681 // 3. FlushCurrentThread() deletes the thread local event buffer:
1680 // - The last batch of events of the thread are flushed into the main buffer; 1682 // - 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_; 1683 // - The message loop will be removed from thread_message_loops_;
1682 // If this is the last message loop, finish the flush; 1684 // 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. 1685 // 4. If any thread hasn't finish its flush in time, finish the flush.
1684 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { 1686 void TraceLog::Flush(const TraceLog::OutputCallback& cb,
1687 bool use_worker_thread) {
1688 use_worker_thread_ = use_worker_thread;
1685 if (IsEnabled()) { 1689 if (IsEnabled()) {
1686 // Can't flush when tracing is enabled because otherwise PostTask would 1690 // Can't flush when tracing is enabled because otherwise PostTask would
1687 // - generate more trace events; 1691 // - generate more trace events;
1688 // - deschedule the calling thread on some platforms causing inaccurate 1692 // - deschedule the calling thread on some platforms causing inaccurate
1689 // timing of the trace events. 1693 // timing of the trace events.
1690 scoped_refptr<RefCountedString> empty_result = new RefCountedString; 1694 scoped_refptr<RefCountedString> empty_result = new RefCountedString;
1691 if (!cb.is_null()) 1695 if (!cb.is_null())
1692 cb.Run(empty_result, false); 1696 cb.Run(empty_result, false);
1693 LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled"; 1697 LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled";
1694 return; 1698 return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 flush_message_loop_proxy_->PostDelayedTask( 1732 flush_message_loop_proxy_->PostDelayedTask(
1729 FROM_HERE, 1733 FROM_HERE,
1730 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), 1734 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation),
1731 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); 1735 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs));
1732 return; 1736 return;
1733 } 1737 }
1734 1738
1735 FinishFlush(generation); 1739 FinishFlush(generation);
1736 } 1740 }
1737 1741
1742 // Usually it runs on a different thread.
1738 void TraceLog::ConvertTraceEventsToTraceFormat( 1743 void TraceLog::ConvertTraceEventsToTraceFormat(
1739 scoped_ptr<TraceBuffer> logged_events, 1744 scoped_ptr<TraceBuffer> logged_events,
1740 const TraceLog::OutputCallback& flush_output_callback) { 1745 const TraceLog::OutputCallback& flush_output_callback) {
1741 1746
1742 if (flush_output_callback.is_null()) 1747 if (flush_output_callback.is_null())
1743 return; 1748 return;
1744 1749
1745 // 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
1746 // to let the caller know the completion of flush. 1751 // to let the caller know the completion of flush.
1747 bool has_more_events = true; 1752 bool has_more_events = true;
1748 do { 1753 do {
1749 scoped_refptr<RefCountedString> json_events_str_ptr = 1754 scoped_refptr<RefCountedString> json_events_str_ptr =
1750 new RefCountedString(); 1755 new RefCountedString();
1751 1756
1752 for (size_t i = 0; i < kTraceEventBatchChunks; ++i) { 1757 while (json_events_str_ptr->size() < kTraceEventBufferSizeInBytes) {
1753 const TraceBufferChunk* chunk = logged_events->NextChunk(); 1758 const TraceBufferChunk* chunk = logged_events->NextChunk();
1754 if (!chunk) { 1759 has_more_events = chunk != NULL;
1755 has_more_events = false; 1760 if (!chunk)
1756 break; 1761 break;
1757 }
1758 for (size_t j = 0; j < chunk->size(); ++j) { 1762 for (size_t j = 0; j < chunk->size(); ++j) {
1759 if (i > 0 || j > 0) 1763 if (json_events_str_ptr->size())
1760 json_events_str_ptr->data().append(",\n"); 1764 json_events_str_ptr->data().append(",\n");
1761 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); 1765 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()));
1762 } 1766 }
1763 } 1767 }
1764
1765 flush_output_callback.Run(json_events_str_ptr, has_more_events); 1768 flush_output_callback.Run(json_events_str_ptr, has_more_events);
1766 } while (has_more_events); 1769 } while (has_more_events);
1767 } 1770 }
1768 1771
1769 void TraceLog::FinishFlush(int generation) { 1772 void TraceLog::FinishFlush(int generation) {
1770 scoped_ptr<TraceBuffer> previous_logged_events; 1773 scoped_ptr<TraceBuffer> previous_logged_events;
1771 OutputCallback flush_output_callback; 1774 OutputCallback flush_output_callback;
1772 1775
1773 if (!CheckGeneration(generation)) 1776 if (!CheckGeneration(generation))
1774 return; 1777 return;
1775 1778
1776 { 1779 {
1777 AutoLock lock(lock_); 1780 AutoLock lock(lock_);
1778 1781
1779 previous_logged_events.swap(logged_events_); 1782 previous_logged_events.swap(logged_events_);
1780 UseNextTraceBuffer(); 1783 UseNextTraceBuffer();
1781 thread_message_loops_.clear(); 1784 thread_message_loops_.clear();
1782 1785
1783 flush_message_loop_proxy_ = NULL; 1786 flush_message_loop_proxy_ = NULL;
1784 flush_output_callback = flush_output_callback_; 1787 flush_output_callback = flush_output_callback_;
1785 flush_output_callback_.Reset(); 1788 flush_output_callback_.Reset();
1786 } 1789 }
1787 1790
1791 if (use_worker_thread_ &&
1792 WorkerPool::PostTask(
1793 FROM_HERE,
1794 Bind(&TraceLog::ConvertTraceEventsToTraceFormat,
1795 Passed(&previous_logged_events),
1796 flush_output_callback),
1797 true)) {
1798 return;
1799 }
1800
1788 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 1801 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(),
1789 flush_output_callback); 1802 flush_output_callback);
1790 } 1803 }
1791 1804
1792 // Run in each thread holding a local event buffer. 1805 // Run in each thread holding a local event buffer.
1793 void TraceLog::FlushCurrentThread(int generation) { 1806 void TraceLog::FlushCurrentThread(int generation) {
1794 { 1807 {
1795 AutoLock lock(lock_); 1808 AutoLock lock(lock_);
1796 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { 1809 if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) {
1797 // This is late. The corresponding flush has finished. 1810 // This is late. The corresponding flush has finished.
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
2602 } 2615 }
2603 2616
2604 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2617 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2605 if (*category_group_enabled_) { 2618 if (*category_group_enabled_) {
2606 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2619 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2607 name_, event_handle_); 2620 name_, event_handle_);
2608 } 2621 }
2609 } 2622 }
2610 2623
2611 } // namespace trace_event_internal 2624 } // namespace trace_event_internal
OLDNEW
« no previous file with comments | « base/trace_event/trace_event_impl.h ('k') | content/browser/tracing/tracing_controller_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698