1201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/histogram_synchronizer.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeTicks;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Negative numbers are never used as sequence numbers.  We explicitly pick a
20201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// negative number that is "so negative" that even when we add one (as is done
21201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// when we generated the next sequence number) that it will still be negative.
22201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// We have code that handles wrapping around on an overflow into negative
23201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// territory.
244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochstatic const int kNeverUsableSequenceNumber = -2;
254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistogramSynchronizer::HistogramSynchronizer()
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  : lock_(),
28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    received_all_renderer_histograms_(&lock_),
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_task_(NULL),
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_thread_(NULL),
31201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    last_used_sequence_number_(kNeverUsableSequenceNumber),
324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    async_sequence_number_(kNeverUsableSequenceNumber),
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    async_renderers_pending_(0),
344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    synchronous_sequence_number_(kNeverUsableSequenceNumber),
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    synchronous_renderers_pending_(0) {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(histogram_synchronizer_ == NULL);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  histogram_synchronizer_ = this;
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistogramSynchronizer::~HistogramSynchronizer() {
41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Just in case we have any pending tasks, clear them out.
42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetCallbackTaskAndThread(NULL, NULL);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  histogram_synchronizer_ = NULL;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistogramSynchronizer* HistogramSynchronizer::CurrentSynchronizer() {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(histogram_synchronizer_ != NULL);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return histogram_synchronizer_;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistogramSynchronizer::FetchRendererHistogramsSynchronously(
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TimeDelta wait_time) {
54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  NotifyAllRenderers(SYNCHRONOUS_HISTOGRAMS);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TimeTicks start = TimeTicks::Now();
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TimeTicks end_time = start + wait_time;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int unresponsive_renderer_count;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    base::AutoLock auto_lock(lock_);
61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    while (synchronous_renderers_pending_ > 0 && TimeTicks::Now() < end_time) {
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      wait_time = end_time - TimeTicks::Now();
63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      received_all_renderer_histograms_.TimedWait(wait_time);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unresponsive_renderer_count = synchronous_renderers_pending_;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    synchronous_renderers_pending_ = 0;
674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    synchronous_sequence_number_ = kNeverUsableSequenceNumber;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UMA_HISTOGRAM_COUNTS("Histogram.RendersNotRespondingSynchronous",
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       unresponsive_renderer_count);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!unresponsive_renderer_count)
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UMA_HISTOGRAM_TIMES("Histogram.FetchRendererHistogramsSynchronously",
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        TimeTicks::Now() - start);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistogramSynchronizer::FetchRendererHistogramsAsynchronously(
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop* callback_thread,
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Task* callback_task,
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int wait_time) {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(callback_thread != NULL);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(callback_task != NULL);
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  HistogramSynchronizer* current_synchronizer = CurrentSynchronizer();
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_synchronizer == NULL) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // System teardown is happening.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_thread->PostTask(FROM_HERE, callback_task);
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  current_synchronizer->SetCallbackTaskAndThread(callback_thread,
93201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                 callback_task);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sequence_number =
96201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      current_synchronizer->NotifyAllRenderers(ASYNC_HISTOGRAMS);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Post a task that would be called after waiting for wait_time.  This acts
99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // as a watchdog, to ensure that a non-responsive renderer won't block us from
100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // making the callback.
101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostDelayedTask(
102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      BrowserThread::UI, FROM_HERE,
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          current_synchronizer,
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          sequence_number),
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      wait_time);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistogramSynchronizer::DeserializeHistogramList(
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int sequence_number,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<std::string>& histograms) {
1144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<std::string>::const_iterator it = histograms.begin();
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it < histograms.end();
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++it) {
118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::Histogram::DeserializeHistogramInfo(*it);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  HistogramSynchronizer* current_synchronizer = CurrentSynchronizer();
122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (current_synchronizer == NULL)
123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Record that we have received a histogram from renderer process.
126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  current_synchronizer->DecrementPendingRenderers(sequence_number);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochint HistogramSynchronizer::NotifyAllRenderers(
130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    RendererHistogramRequester requester) {
131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // To iterate over RenderProcessHosts, or to send messages to the hosts, we
132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // need to be on the UI thread.
133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int notification_count = 0;
136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch       !it.IsAtEnd(); it.Advance())
138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch     ++notification_count;
139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int sequence_number = GetNextAvailableSequenceNumber(requester,
141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                       notification_count);
142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch       !it.IsAtEnd(); it.Advance()) {
144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (!it.GetCurrentValue()->Send(
145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        new ViewMsg_GetRendererHistograms(sequence_number)))
146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      DecrementPendingRenderers(sequence_number);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return sequence_number;
150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid HistogramSynchronizer::DecrementPendingRenderers(int sequence_number) {
153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool synchronous_completed = false;
154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool asynchronous_completed = false;
155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    base::AutoLock auto_lock(lock_);
158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (sequence_number == async_sequence_number_) {
159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (--async_renderers_pending_ <= 0)
160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        asynchronous_completed = true;
161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    } else if (sequence_number == synchronous_sequence_number_) {
162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (--synchronous_renderers_pending_ <= 0)
163201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        synchronous_completed = true;
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (asynchronous_completed)
168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    ForceHistogramSynchronizationDoneCallback(sequence_number);
169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  else if (synchronous_completed)
170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    received_all_renderer_histograms_.Signal();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid HistogramSynchronizer::SetCallbackTaskAndThread(
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop* callback_thread,
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Task* callback_task) {
176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  Task* old_task = NULL;
177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MessageLoop* old_thread = NULL;
178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TimeTicks old_start_time;
179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int unresponsive_renderers;
180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const TimeTicks now = TimeTicks::Now();
181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  {
1823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    base::AutoLock auto_lock(lock_);
183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    old_task = callback_task_;
184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    callback_task_ = callback_task;
185201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    old_thread = callback_thread_;
186201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    callback_thread_ = callback_thread;
187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    unresponsive_renderers = async_renderers_pending_;
188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    old_start_time = async_callback_start_time_;
189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    async_callback_start_time_ = now;
190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Prevent premature calling of our new callbacks.
191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    async_sequence_number_ = kNeverUsableSequenceNumber;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Just in case there was a task pending....
194201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  InternalPostTask(old_thread, old_task, unresponsive_renderers,
195201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                   old_start_time);
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback(
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int sequence_number) {
200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  Task* task = NULL;
201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MessageLoop* thread = NULL;
202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TimeTicks started;
203201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int unresponsive_renderers;
204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  {
2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    base::AutoLock lock(lock_);
206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (sequence_number != async_sequence_number_)
207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return;
208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    task = callback_task_;
209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    thread = callback_thread_;
210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    callback_task_ = NULL;
211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    callback_thread_ = NULL;
212201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    started = async_callback_start_time_;
213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    unresponsive_renderers = async_renderers_pending_;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
215201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  InternalPostTask(thread, task, unresponsive_renderers, started);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid HistogramSynchronizer::InternalPostTask(MessageLoop* thread, Task* task,
219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                             int unresponsive_renderers,
220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                             const base::TimeTicks& started) {
221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!task || !thread)
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UMA_HISTOGRAM_COUNTS("Histogram.RendersNotRespondingAsynchronous",
224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                       unresponsive_renderers);
225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!unresponsive_renderers) {
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UMA_HISTOGRAM_TIMES("Histogram.FetchRendererHistogramsAsynchronously",
227201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                        TimeTicks::Now() - started);
228201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  thread->PostTask(FROM_HERE, task);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint HistogramSynchronizer::GetNextAvailableSequenceNumber(
234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    RendererHistogramRequester requester,
235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    int renderer_count) {
2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::AutoLock auto_lock(lock_);
237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ++last_used_sequence_number_;
238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Watch out for wrapping to a negative number.
239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (last_used_sequence_number_ < 0) {
240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Bypass the reserved number, which is used when a renderer spontaneously
241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // decides to send some histogram data.
242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    last_used_sequence_number_ =
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        chrome::kHistogramSynchronizerReservedSequenceNumber + 1;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK_NE(last_used_sequence_number_,
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            chrome::kHistogramSynchronizerReservedSequenceNumber);
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (requester == ASYNC_HISTOGRAMS) {
248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    async_sequence_number_ = last_used_sequence_number_;
249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    async_renderers_pending_ = renderer_count;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (requester == SYNCHRONOUS_HISTOGRAMS) {
251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    synchronous_sequence_number_ = last_used_sequence_number_;
252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    synchronous_renderers_pending_ = renderer_count;
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return last_used_sequence_number_;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistogramSynchronizer* HistogramSynchronizer::histogram_synchronizer_ = NULL;
259