OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #include "content/browser/tracing/tracing_controller_impl.h" | 4 #include "content/browser/tracing/tracing_controller_impl.h" |
5 | 5 |
6 #include "base/bind.h" | 6 #include "base/bind.h" |
7 #include "base/cpu.h" | 7 #include "base/cpu.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = | 45 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
46 LAZY_INSTANCE_INITIALIZER; | 46 LAZY_INSTANCE_INITIALIZER; |
47 | 47 |
48 const char kChromeTracingAgentName[] = "chrome"; | 48 const char kChromeTracingAgentName[] = "chrome"; |
49 const char kETWTracingAgentName[] = "etw"; | 49 const char kETWTracingAgentName[] = "etw"; |
50 const char kChromeTraceLabel[] = "traceEvents"; | 50 const char kChromeTraceLabel[] = "traceEvents"; |
51 | 51 |
| 52 const int kIssueClockSyncTimeout = 30; |
| 53 |
52 std::string GetNetworkTypeString() { | 54 std::string GetNetworkTypeString() { |
53 switch (net::NetworkChangeNotifier::GetConnectionType()) { | 55 switch (net::NetworkChangeNotifier::GetConnectionType()) { |
54 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | 56 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: |
55 return "Ethernet"; | 57 return "Ethernet"; |
56 case net::NetworkChangeNotifier::CONNECTION_WIFI: | 58 case net::NetworkChangeNotifier::CONNECTION_WIFI: |
57 return "WiFi"; | 59 return "WiFi"; |
58 case net::NetworkChangeNotifier::CONNECTION_2G: | 60 case net::NetworkChangeNotifier::CONNECTION_2G: |
59 return "2G"; | 61 return "2G"; |
60 case net::NetworkChangeNotifier::CONNECTION_3G: | 62 case net::NetworkChangeNotifier::CONNECTION_3G: |
61 return "3G"; | 63 return "3G"; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 } | 143 } |
142 | 144 |
143 TracingControllerImpl::TracingControllerImpl() | 145 TracingControllerImpl::TracingControllerImpl() |
144 : pending_stop_tracing_ack_count_(0), | 146 : pending_stop_tracing_ack_count_(0), |
145 pending_capture_monitoring_snapshot_ack_count_(0), | 147 pending_capture_monitoring_snapshot_ack_count_(0), |
146 pending_trace_log_status_ack_count_(0), | 148 pending_trace_log_status_ack_count_(0), |
147 maximum_trace_buffer_usage_(0), | 149 maximum_trace_buffer_usage_(0), |
148 approximate_event_count_(0), | 150 approximate_event_count_(0), |
149 pending_memory_dump_ack_count_(0), | 151 pending_memory_dump_ack_count_(0), |
150 failed_memory_dump_count_(0), | 152 failed_memory_dump_count_(0), |
| 153 clock_sync_id_(0), |
| 154 pending_clock_sync_ack_count_(0), |
151 is_tracing_(false), | 155 is_tracing_(false), |
152 is_monitoring_(false) { | 156 is_monitoring_(false) { |
153 base::trace_event::MemoryDumpManager::GetInstance()->Initialize( | 157 base::trace_event::MemoryDumpManager::GetInstance()->Initialize( |
154 this /* delegate */, true /* is_coordinator */); | 158 this /* delegate */, true /* is_coordinator */); |
155 | 159 |
156 // Deliberately leaked, like this class. | 160 // Deliberately leaked, like this class. |
157 base::FileTracing::SetProvider(new FileTracingProviderImpl); | 161 base::FileTracing::SetProvider(new FileTracingProviderImpl); |
158 } | 162 } |
159 | 163 |
160 TracingControllerImpl::~TracingControllerImpl() { | 164 TracingControllerImpl::~TracingControllerImpl() { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 delegate->GetMetadataFilterPredicate()); | 284 delegate->GetMetadataFilterPredicate()); |
281 } | 285 } |
282 } | 286 } |
283 trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get()); | 287 trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get()); |
284 } | 288 } |
285 | 289 |
286 if (!can_stop_tracing()) | 290 if (!can_stop_tracing()) |
287 return false; | 291 return false; |
288 | 292 |
289 trace_data_sink_ = trace_data_sink; | 293 trace_data_sink_ = trace_data_sink; |
| 294 |
| 295 // Issue clock sync marker before actually stopping tracing. |
| 296 // StopTracingAfterClockSync() will be called after clock sync is done. |
| 297 IssueClockSyncMarker(); |
| 298 |
| 299 return true; |
| 300 } |
| 301 |
| 302 void TracingControllerImpl::StopTracingAfterClockSync() { |
| 303 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 304 |
| 305 // |pending_clock_sync_ack_count_| could be non-zero if clock sync times out. |
| 306 pending_clock_sync_ack_count_ = 0; |
| 307 |
290 // Disable local trace early to avoid traces during end-tracing process from | 308 // Disable local trace early to avoid traces during end-tracing process from |
291 // interfering with the process. | 309 // interfering with the process. |
292 base::Closure on_stop_tracing_done_callback = base::Bind( | 310 base::Closure on_stop_tracing_done_callback = base::Bind( |
293 &TracingControllerImpl::OnStopTracingDone, base::Unretained(this)); | 311 &TracingControllerImpl::OnStopTracingDone, base::Unretained(this)); |
294 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
295 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, | 313 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, |
296 base::Unretained(this), | 314 base::Unretained(this), |
297 on_stop_tracing_done_callback)); | 315 on_stop_tracing_done_callback)); |
298 return true; | |
299 } | 316 } |
300 | 317 |
301 void TracingControllerImpl::OnStopTracingDone() { | 318 void TracingControllerImpl::OnStopTracingDone() { |
302 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 319 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
303 | 320 |
304 #if defined(OS_ANDROID) | 321 #if defined(OS_ANDROID) |
305 if (pending_get_categories_done_callback_.is_null()) | 322 if (pending_get_categories_done_callback_.is_null()) |
306 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 323 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
307 #endif | 324 #endif |
308 | 325 |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 // Notify all child processes. | 923 // Notify all child processes. |
907 for (auto it : trace_message_filters_) { | 924 for (auto it : trace_message_filters_) { |
908 if (trace_data_sink_) | 925 if (trace_data_sink_) |
909 it->SendEndTracing(); | 926 it->SendEndTracing(); |
910 else | 927 else |
911 it->SendCancelTracing(); | 928 it->SendCancelTracing(); |
912 } | 929 } |
913 } | 930 } |
914 | 931 |
915 bool TracingControllerImpl::SupportsExplicitClockSync() { | 932 bool TracingControllerImpl::SupportsExplicitClockSync() { |
916 // TODO(zhenw): return true after implementing explicit clock sync. | 933 return true; |
917 return false; | |
918 } | 934 } |
919 | 935 |
920 void TracingControllerImpl::RecordClockSyncMarker( | 936 void TracingControllerImpl::RecordClockSyncMarker( |
921 int sync_id, | 937 int sync_id, |
922 const RecordClockSyncMarkerCallback& callback) { | 938 const RecordClockSyncMarkerCallback& callback) { |
923 DCHECK(SupportsExplicitClockSync()); | 939 DCHECK(SupportsExplicitClockSync()); |
924 // TODO(zhenw): implement explicit clock sync. | 940 |
| 941 TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id); |
| 942 } |
| 943 |
| 944 int TracingControllerImpl::GetUniqueClockSyncID() { |
| 945 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 946 // There is no need to lock because this function only runs on UI thread. |
| 947 return ++clock_sync_id_; |
925 } | 948 } |
926 | 949 |
927 void TracingControllerImpl::IssueClockSyncMarker() { | 950 void TracingControllerImpl::IssueClockSyncMarker() { |
928 // TODO(zhenw): implement explicit clock sync. | 951 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 952 DCHECK(pending_clock_sync_ack_count_ == 0); |
| 953 |
| 954 for (const auto& it : additional_tracing_agents_) { |
| 955 if (it->SupportsExplicitClockSync()) { |
| 956 it->RecordClockSyncMarker( |
| 957 GetUniqueClockSyncID(), |
| 958 base::Bind(&TracingControllerImpl::OnClockSyncMarkerRecordedByAgent, |
| 959 base::Unretained(this))); |
| 960 pending_clock_sync_ack_count_++; |
| 961 } |
| 962 } |
| 963 |
| 964 // If no clock sync is needed, stop tracing right away. Otherwise, schedule |
| 965 // to stop tracing after timeout. |
| 966 if (pending_clock_sync_ack_count_ == 0) { |
| 967 StopTracingAfterClockSync(); |
| 968 } else { |
| 969 clock_sync_timer_.Start( |
| 970 FROM_HERE, |
| 971 base::TimeDelta::FromSeconds(kIssueClockSyncTimeout), |
| 972 this, |
| 973 &TracingControllerImpl::StopTracingAfterClockSync); |
| 974 } |
| 975 } |
| 976 |
| 977 void TracingControllerImpl::OnClockSyncMarkerRecordedByAgent( |
| 978 int sync_id, |
| 979 const base::TimeTicks& issue_ts, |
| 980 const base::TimeTicks& issue_end_ts) { |
| 981 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 982 |
| 983 TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts); |
| 984 |
| 985 // Timer is not running means that clock sync already timed out. |
| 986 if (!clock_sync_timer_.IsRunning()) |
| 987 return; |
| 988 |
| 989 // Stop tracing only if all agents report back. |
| 990 if(--pending_clock_sync_ack_count_ == 0) { |
| 991 clock_sync_timer_.Stop(); |
| 992 StopTracingAfterClockSync(); |
| 993 } |
929 } | 994 } |
930 | 995 |
931 void TracingControllerImpl::RequestGlobalMemoryDump( | 996 void TracingControllerImpl::RequestGlobalMemoryDump( |
932 const base::trace_event::MemoryDumpRequestArgs& args, | 997 const base::trace_event::MemoryDumpRequestArgs& args, |
933 const base::trace_event::MemoryDumpCallback& callback) { | 998 const base::trace_event::MemoryDumpCallback& callback) { |
934 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 999 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
935 BrowserThread::PostTask( | 1000 BrowserThread::PostTask( |
936 BrowserThread::UI, FROM_HERE, | 1001 BrowserThread::UI, FROM_HERE, |
937 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, | 1002 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, |
938 base::Unretained(this), args, callback)); | 1003 base::Unretained(this), args, callback)); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 is_monitoring_ = is_monitoring; | 1122 is_monitoring_ = is_monitoring; |
1058 #if !defined(OS_ANDROID) | 1123 #if !defined(OS_ANDROID) |
1059 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); | 1124 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); |
1060 it != tracing_uis_.end(); it++) { | 1125 it != tracing_uis_.end(); it++) { |
1061 (*it)->OnMonitoringStateChanged(is_monitoring); | 1126 (*it)->OnMonitoringStateChanged(is_monitoring); |
1062 } | 1127 } |
1063 #endif | 1128 #endif |
1064 } | 1129 } |
1065 | 1130 |
1066 } // namespace content | 1131 } // namespace content |
OLD | NEW |