| Index: base/task_scheduler/scheduler_worker_pool_impl.cc | 
| diff --git a/base/task_scheduler/scheduler_worker_pool_impl.cc b/base/task_scheduler/scheduler_worker_pool_impl.cc | 
| index 4a9ee43fb08fec7f4a78868cda81336c5e37e5ff..3aa05eafec698e2edbcf69a9730b5e913cd59268 100644 | 
| --- a/base/task_scheduler/scheduler_worker_pool_impl.cc | 
| +++ b/base/task_scheduler/scheduler_worker_pool_impl.cc | 
| @@ -237,14 +237,14 @@ class SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl | 
| } | 
|  | 
| // SchedulerWorker::Delegate: | 
| -  void OnMainEntry(SchedulerWorker* worker, | 
| -                   const TimeDelta& detach_duration) override; | 
| +  void OnMainEntry(SchedulerWorker* worker) override; | 
| scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override; | 
| void DidRunTaskWithPriority(TaskPriority task_priority, | 
| const TimeDelta& task_latency) override; | 
| void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override; | 
| TimeDelta GetSleepTimeout() override; | 
| bool CanDetach(SchedulerWorker* worker) override; | 
| +  void OnDetach() override; | 
|  | 
| void RegisterSingleThreadTaskRunner() { | 
| // No barrier as barriers only affect sequential consistency which is | 
| @@ -268,6 +268,9 @@ class SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl | 
| // |single_threaded_priority_queue_|. | 
| bool last_sequence_is_single_threaded_ = false; | 
|  | 
| +  // Time of the last detach. | 
| +  TimeTicks last_detach_time_; | 
| + | 
| // Time when GetWork() first returned nullptr. | 
| TimeTicks idle_start_time_; | 
|  | 
| @@ -481,8 +484,7 @@ SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl:: | 
| ~SchedulerWorkerDelegateImpl() = default; | 
|  | 
| void SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::OnMainEntry( | 
| -    SchedulerWorker* worker, | 
| -    const TimeDelta& detach_duration) { | 
| +    SchedulerWorker* worker) { | 
| #if DCHECK_IS_ON() | 
| // Wait for |outer_->workers_created_| to avoid traversing | 
| // |outer_->workers_| while it is being filled by Initialize(). | 
| @@ -492,13 +494,9 @@ void SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::OnMainEntry( | 
|  | 
| DCHECK_EQ(num_tasks_since_last_wait_, 0U); | 
|  | 
| -  // Record histograms if the worker detached in the past. | 
| -  if (!detach_duration.is_max()) { | 
| -    outer_->detach_duration_histogram_->AddTime(detach_duration); | 
| -    outer_->num_tasks_before_detach_histogram_->Add( | 
| -        num_tasks_since_last_detach_); | 
| -    num_tasks_since_last_detach_ = 0; | 
| -    did_detach_since_last_get_work_ = true; | 
| +  if (!last_detach_time_.is_null()) { | 
| +    outer_->detach_duration_histogram_->AddTime(TimeTicks::Now() - | 
| +                                                last_detach_time_); | 
| } | 
|  | 
| PlatformThread::SetName( | 
| @@ -525,16 +523,15 @@ SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::GetWork( | 
| // Record the TaskScheduler.NumTasksBetweenWaits histogram if the | 
| // SchedulerWorker waited on its WaitableEvent since the last GetWork(). | 
| // | 
| -  // Note: When GetWork() returns nullptr for the first time after returning a | 
| -  // Sequence, SchedulerWorker waits on its WaitableEvent. When the wait stops | 
| -  // (either because WakeUp() was called or because the sleep timeout expired), | 
| -  // GetWork() is called and the histogram is recorded. If GetWork() returns | 
| -  // nullptr again, the SchedulerWorker may detach. | 
| -  // |did_detach_since_last_get_work_| is set to true from OnMainEntry() if the | 
| -  // SchedulerWorker detaches and wakes up again. The next call to GetWork() | 
| -  // won't record the histogram (which is correct since the SchedulerWorker | 
| -  // didn't wait on its WaitableEvent since the last time the histogram was | 
| -  // recorded). | 
| +  // Note: When GetWork() starts returning nullptr, the SchedulerWorker waits on | 
| +  // its WaitableEvent. When it wakes up (either because WakeUp() was called or | 
| +  // because the sleep timeout expired), it calls GetWork() again. The code | 
| +  // below records the histogram and, if GetWork() returns nullptr again, the | 
| +  // SchedulerWorker may detach. If that happens, | 
| +  // |did_detach_since_last_get_work_| is set to true and the next call to | 
| +  // GetWork() won't record the histogram  (which is correct since the | 
| +  // SchedulerWorker didn't wait on its WaitableEvent since the last time the | 
| +  // histogram was recorded). | 
| if (last_get_work_returned_nullptr_ && !did_detach_since_last_get_work_) { | 
| outer_->num_tasks_between_waits_histogram_->Add(num_tasks_since_last_wait_); | 
| num_tasks_since_last_wait_ = 0; | 
| @@ -659,6 +656,14 @@ bool SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::CanDetach( | 
| return can_detach; | 
| } | 
|  | 
| +void SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::OnDetach() { | 
| +  DCHECK(!did_detach_since_last_get_work_); | 
| +  outer_->num_tasks_before_detach_histogram_->Add(num_tasks_since_last_detach_); | 
| +  num_tasks_since_last_detach_ = 0; | 
| +  did_detach_since_last_get_work_ = true; | 
| +  last_detach_time_ = TimeTicks::Now(); | 
| +} | 
| + | 
| SchedulerWorkerPoolImpl::SchedulerWorkerPoolImpl( | 
| StringPiece name, | 
| SchedulerWorkerPoolParams::IORestriction io_restriction, | 
| @@ -684,10 +689,9 @@ SchedulerWorkerPoolImpl::SchedulerWorkerPoolImpl( | 
| TimeDelta::FromHours(1), | 
| 50, | 
| HistogramBase::kUmaTargetedHistogramFlag)), | 
| -      // Mimics the UMA_HISTOGRAM_COUNTS_1000 macro. A SchedulerWorker is | 
| -      // expected to run between zero and a few hundreds of tasks before | 
| -      // detaching. When it runs more than 1000 tasks, there is no need to know | 
| -      // the exact number of tasks that ran. | 
| +      // Mimics the UMA_HISTOGRAM_COUNTS_1000 macro. When a worker runs more | 
| +      // than 1000 tasks before detaching, there is no need to know the exact | 
| +      // number of tasks that ran. | 
| num_tasks_before_detach_histogram_(Histogram::FactoryGet( | 
| kNumTasksBeforeDetachHistogramPrefix + name_ + kPoolNameSuffix, | 
| 1, | 
|  |