Index: content/browser/tracing/tracing_controller_impl.cc |
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc |
index 33c236117761a07bf20ec6ba9d4a89e291926cd4..b119b011b98ea5acb52470c680454f7e87de2d72 100644 |
--- a/content/browser/tracing/tracing_controller_impl.cc |
+++ b/content/browser/tracing/tracing_controller_impl.cc |
@@ -49,6 +49,8 @@ const char kChromeTracingAgentName[] = "chrome"; |
const char kETWTracingAgentName[] = "etw"; |
const char kChromeTraceLabel[] = "traceEvents"; |
+const int kIssueClockSyncTimeout = 30; |
+ |
std::string GetNetworkTypeString() { |
switch (net::NetworkChangeNotifier::GetConnectionType()) { |
case net::NetworkChangeNotifier::CONNECTION_ETHERNET: |
@@ -148,6 +150,8 @@ TracingControllerImpl::TracingControllerImpl() |
approximate_event_count_(0), |
pending_memory_dump_ack_count_(0), |
failed_memory_dump_count_(0), |
+ clock_sync_id_(0), |
+ pending_clock_sync_ack_count_(0), |
is_tracing_(false), |
is_monitoring_(false) { |
base::trace_event::MemoryDumpManager::GetInstance()->Initialize( |
@@ -287,6 +291,20 @@ bool TracingControllerImpl::StopTracing( |
return false; |
trace_data_sink_ = trace_data_sink; |
+ |
+ // Issue clock sync marker before actually stopping tracing. |
+ // StopTracingAfterClockSync() will be called after clock sync is done. |
+ IssueClockSyncMarker(); |
+ |
+ return true; |
+} |
+ |
+void TracingControllerImpl::StopTracingAfterClockSync() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
+ // |pending_clock_sync_ack_count_| could be non-zero if clock sync times out. |
+ pending_clock_sync_ack_count_ = 0; |
+ |
// Disable local trace early to avoid traces during end-tracing process from |
// interfering with the process. |
base::Closure on_stop_tracing_done_callback = base::Bind( |
@@ -295,7 +313,6 @@ bool TracingControllerImpl::StopTracing( |
base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, |
base::Unretained(this), |
on_stop_tracing_done_callback)); |
- return true; |
} |
void TracingControllerImpl::OnStopTracingDone() { |
@@ -913,19 +930,67 @@ void TracingControllerImpl::StopAgentTracing( |
} |
bool TracingControllerImpl::SupportsExplicitClockSync() { |
- // TODO(zhenw): return true after implementing explicit clock sync. |
- return false; |
+ return true; |
} |
void TracingControllerImpl::RecordClockSyncMarker( |
int sync_id, |
const RecordClockSyncMarkerCallback& callback) { |
DCHECK(SupportsExplicitClockSync()); |
- // TODO(zhenw): implement explicit clock sync. |
+ |
+ TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id); |
+} |
+ |
+int TracingControllerImpl::GetUniqueClockSyncID() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ // There is no need to lock because this function only runs on UI thread. |
+ return ++clock_sync_id_; |
} |
void TracingControllerImpl::IssueClockSyncMarker() { |
- // TODO(zhenw): implement explicit clock sync. |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ DCHECK(pending_clock_sync_ack_count_ == 0); |
+ |
+ for (const auto& it : additional_tracing_agents_) { |
+ if (it->SupportsExplicitClockSync()) { |
+ it->RecordClockSyncMarker( |
+ GetUniqueClockSyncID(), |
+ base::Bind(&TracingControllerImpl::OnClockSyncMarkerRecordedByAgent, |
+ base::Unretained(this))); |
+ pending_clock_sync_ack_count_++; |
+ } |
+ } |
+ |
+ // If no clock sync is needed, stop tracing right away. Otherwise, schedule |
+ // to stop tracing after timeout. |
+ if (pending_clock_sync_ack_count_ == 0) { |
+ StopTracingAfterClockSync(); |
+ } else { |
+ clock_sync_timer_.Start( |
+ FROM_HERE, |
+ base::TimeDelta::FromSeconds(kIssueClockSyncTimeout), |
+ this, |
+ &TracingControllerImpl::StopTracingAfterClockSync); |
+ } |
+} |
+ |
+void TracingControllerImpl::OnClockSyncMarkerRecordedByAgent( |
+ int sync_id, |
+ const base::TimeTicks& issue_ts, |
+ const base::TimeTicks& issue_end_ts) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
+ TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts); |
+ |
+ // Timer is not running means that clock sync already timed out. |
+ if (!clock_sync_timer_.IsRunning()) |
+ return; |
+ |
+ // Stop tracing only if all agents report back. |
+ if(--pending_clock_sync_ack_count_ == 0) { |
+ clock_sync_timer_.Stop(); |
+ StopTracingAfterClockSync(); |
+ } |
} |
void TracingControllerImpl::RequestGlobalMemoryDump( |