| OLD | NEW | 
|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/task_scheduler/scheduler_worker_pool_impl.h" | 5 #include "base/task_scheduler/scheduler_worker_pool_impl.h" | 
| 6 | 6 | 
| 7 #include <stddef.h> | 7 #include <stddef.h> | 
| 8 | 8 | 
| 9 #include <algorithm> | 9 #include <algorithm> | 
| 10 #include <utility> | 10 #include <utility> | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 27 #include "base/time/time.h" | 27 #include "base/time/time.h" | 
| 28 | 28 | 
| 29 namespace base { | 29 namespace base { | 
| 30 namespace internal { | 30 namespace internal { | 
| 31 | 31 | 
| 32 namespace { | 32 namespace { | 
| 33 | 33 | 
| 34 constexpr char kPoolNameSuffix[] = "Pool"; | 34 constexpr char kPoolNameSuffix[] = "Pool"; | 
| 35 constexpr char kDetachDurationHistogramPrefix[] = | 35 constexpr char kDetachDurationHistogramPrefix[] = | 
| 36     "TaskScheduler.DetachDuration."; | 36     "TaskScheduler.DetachDuration."; | 
|  | 37 constexpr char kNumTasksBeforeDetachHistogramPrefix[] = | 
|  | 38     "TaskScheduler.NumTasksBeforeDetach."; | 
| 37 constexpr char kNumTasksBetweenWaitsHistogramPrefix[] = | 39 constexpr char kNumTasksBetweenWaitsHistogramPrefix[] = | 
| 38     "TaskScheduler.NumTasksBetweenWaits."; | 40     "TaskScheduler.NumTasksBetweenWaits."; | 
| 39 constexpr char kTaskLatencyHistogramPrefix[] = "TaskScheduler.TaskLatency."; | 41 constexpr char kTaskLatencyHistogramPrefix[] = "TaskScheduler.TaskLatency."; | 
| 40 | 42 | 
| 41 // SchedulerWorker that owns the current thread, if any. | 43 // SchedulerWorker that owns the current thread, if any. | 
| 42 LazyInstance<ThreadLocalPointer<const SchedulerWorker>>::Leaky | 44 LazyInstance<ThreadLocalPointer<const SchedulerWorker>>::Leaky | 
| 43     tls_current_worker = LAZY_INSTANCE_INITIALIZER; | 45     tls_current_worker = LAZY_INSTANCE_INITIALIZER; | 
| 44 | 46 | 
| 45 // SchedulerWorkerPool that owns the current thread, if any. | 47 // SchedulerWorkerPool that owns the current thread, if any. | 
| 46 LazyInstance<ThreadLocalPointer<const SchedulerWorkerPool>>::Leaky | 48 LazyInstance<ThreadLocalPointer<const SchedulerWorkerPool>>::Leaky | 
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 273   bool last_get_work_returned_nullptr_ = false; | 275   bool last_get_work_returned_nullptr_ = false; | 
| 274 | 276 | 
| 275   // Indicates whether the SchedulerWorker was detached since the last call to | 277   // Indicates whether the SchedulerWorker was detached since the last call to | 
| 276   // GetWork(). | 278   // GetWork(). | 
| 277   bool did_detach_since_last_get_work_ = false; | 279   bool did_detach_since_last_get_work_ = false; | 
| 278 | 280 | 
| 279   // Number of tasks executed since the last time the | 281   // Number of tasks executed since the last time the | 
| 280   // TaskScheduler.NumTasksBetweenWaits histogram was recorded. | 282   // TaskScheduler.NumTasksBetweenWaits histogram was recorded. | 
| 281   size_t num_tasks_since_last_wait_ = 0; | 283   size_t num_tasks_since_last_wait_ = 0; | 
| 282 | 284 | 
|  | 285   // Number of tasks executed since the last time the | 
|  | 286   // TaskScheduler.NumTasksBeforeDetach histogram was recorded. | 
|  | 287   size_t num_tasks_since_last_detach_ = 0; | 
|  | 288 | 
| 283   subtle::Atomic32 num_single_threaded_runners_ = 0; | 289   subtle::Atomic32 num_single_threaded_runners_ = 0; | 
| 284 | 290 | 
| 285   const int index_; | 291   const int index_; | 
| 286 | 292 | 
| 287   DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDelegateImpl); | 293   DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDelegateImpl); | 
| 288 }; | 294 }; | 
| 289 | 295 | 
| 290 SchedulerWorkerPoolImpl::~SchedulerWorkerPoolImpl() { | 296 SchedulerWorkerPoolImpl::~SchedulerWorkerPoolImpl() { | 
| 291   // SchedulerWorkerPool should never be deleted in production unless its | 297   // SchedulerWorkerPool should never be deleted in production unless its | 
| 292   // initialization failed. | 298   // initialization failed. | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 479     const TimeDelta& detach_duration) { | 485     const TimeDelta& detach_duration) { | 
| 480 #if DCHECK_IS_ON() | 486 #if DCHECK_IS_ON() | 
| 481   // Wait for |outer_->workers_created_| to avoid traversing | 487   // Wait for |outer_->workers_created_| to avoid traversing | 
| 482   // |outer_->workers_| while it is being filled by Initialize(). | 488   // |outer_->workers_| while it is being filled by Initialize(). | 
| 483   outer_->workers_created_.Wait(); | 489   outer_->workers_created_.Wait(); | 
| 484   DCHECK(ContainsWorker(outer_->workers_, worker)); | 490   DCHECK(ContainsWorker(outer_->workers_, worker)); | 
| 485 #endif | 491 #endif | 
| 486 | 492 | 
| 487   DCHECK_EQ(num_tasks_since_last_wait_, 0U); | 493   DCHECK_EQ(num_tasks_since_last_wait_, 0U); | 
| 488 | 494 | 
|  | 495   // Record histograms if the worker detached in the past. | 
| 489   if (!detach_duration.is_max()) { | 496   if (!detach_duration.is_max()) { | 
| 490     outer_->detach_duration_histogram_->AddTime(detach_duration); | 497     outer_->detach_duration_histogram_->AddTime(detach_duration); | 
|  | 498     outer_->num_tasks_before_detach_histogram_->Add( | 
|  | 499         num_tasks_since_last_detach_); | 
|  | 500     num_tasks_since_last_detach_ = 0; | 
| 491     did_detach_since_last_get_work_ = true; | 501     did_detach_since_last_get_work_ = true; | 
| 492   } | 502   } | 
| 493 | 503 | 
| 494   PlatformThread::SetName( | 504   PlatformThread::SetName( | 
| 495       StringPrintf("TaskScheduler%sWorker%d", outer_->name_.c_str(), index_)); | 505       StringPrintf("TaskScheduler%sWorker%d", outer_->name_.c_str(), index_)); | 
| 496 | 506 | 
| 497   DCHECK(!tls_current_worker.Get().Get()); | 507   DCHECK(!tls_current_worker.Get().Get()); | 
| 498   DCHECK(!tls_current_worker_pool.Get().Get()); | 508   DCHECK(!tls_current_worker_pool.Get().Get()); | 
| 499   tls_current_worker.Get().Set(worker); | 509   tls_current_worker.Get().Set(worker); | 
| 500   tls_current_worker_pool.Get().Set(outer_); | 510   tls_current_worker_pool.Get().Set(outer_); | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 586   did_detach_since_last_get_work_ = false; | 596   did_detach_since_last_get_work_ = false; | 
| 587   last_get_work_returned_nullptr_ = false; | 597   last_get_work_returned_nullptr_ = false; | 
| 588 | 598 | 
| 589   return sequence; | 599   return sequence; | 
| 590 } | 600 } | 
| 591 | 601 | 
| 592 void SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl:: | 602 void SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl:: | 
| 593     DidRunTaskWithPriority(TaskPriority task_priority, | 603     DidRunTaskWithPriority(TaskPriority task_priority, | 
| 594                            const TimeDelta& task_latency) { | 604                            const TimeDelta& task_latency) { | 
| 595   ++num_tasks_since_last_wait_; | 605   ++num_tasks_since_last_wait_; | 
|  | 606   ++num_tasks_since_last_detach_; | 
| 596 | 607 | 
| 597   const int priority_index = static_cast<int>(task_priority); | 608   const int priority_index = static_cast<int>(task_priority); | 
| 598 | 609 | 
| 599   // As explained in the header file, histograms are allocated on demand. It | 610   // As explained in the header file, histograms are allocated on demand. It | 
| 600   // doesn't matter if an element of |task_latency_histograms_| is set multiple | 611   // doesn't matter if an element of |task_latency_histograms_| is set multiple | 
| 601   // times since GetTaskLatencyHistogram() is idempotent. As explained in the | 612   // times since GetTaskLatencyHistogram() is idempotent. As explained in the | 
| 602   // comment at the top of histogram_macros.h, barriers are required. | 613   // comment at the top of histogram_macros.h, barriers are required. | 
| 603   HistogramBase* task_latency_histogram = reinterpret_cast<HistogramBase*>( | 614   HistogramBase* task_latency_histogram = reinterpret_cast<HistogramBase*>( | 
| 604       subtle::Acquire_Load(&outer_->task_latency_histograms_[priority_index])); | 615       subtle::Acquire_Load(&outer_->task_latency_histograms_[priority_index])); | 
| 605   if (!task_latency_histogram) { | 616   if (!task_latency_histogram) { | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 666       workers_created_(WaitableEvent::ResetPolicy::MANUAL, | 677       workers_created_(WaitableEvent::ResetPolicy::MANUAL, | 
| 667                        WaitableEvent::InitialState::NOT_SIGNALED), | 678                        WaitableEvent::InitialState::NOT_SIGNALED), | 
| 668 #endif | 679 #endif | 
| 669       // Mimics the UMA_HISTOGRAM_LONG_TIMES macro. | 680       // Mimics the UMA_HISTOGRAM_LONG_TIMES macro. | 
| 670       detach_duration_histogram_(Histogram::FactoryTimeGet( | 681       detach_duration_histogram_(Histogram::FactoryTimeGet( | 
| 671           kDetachDurationHistogramPrefix + name_ + kPoolNameSuffix, | 682           kDetachDurationHistogramPrefix + name_ + kPoolNameSuffix, | 
| 672           TimeDelta::FromMilliseconds(1), | 683           TimeDelta::FromMilliseconds(1), | 
| 673           TimeDelta::FromHours(1), | 684           TimeDelta::FromHours(1), | 
| 674           50, | 685           50, | 
| 675           HistogramBase::kUmaTargetedHistogramFlag)), | 686           HistogramBase::kUmaTargetedHistogramFlag)), | 
|  | 687       // Mimics the UMA_HISTOGRAM_COUNTS_1000 macro. A SchedulerWorker is | 
|  | 688       // expected to run between zero and a few hundreds of tasks before | 
|  | 689       // detaching. When it runs more than 1000 tasks, there is no need to know | 
|  | 690       // the exact number of tasks that ran. | 
|  | 691       num_tasks_before_detach_histogram_(Histogram::FactoryGet( | 
|  | 692           kNumTasksBeforeDetachHistogramPrefix + name_ + kPoolNameSuffix, | 
|  | 693           1, | 
|  | 694           1000, | 
|  | 695           50, | 
|  | 696           HistogramBase::kUmaTargetedHistogramFlag)), | 
| 676       // Mimics the UMA_HISTOGRAM_COUNTS_100 macro. A SchedulerWorker is | 697       // Mimics the UMA_HISTOGRAM_COUNTS_100 macro. A SchedulerWorker is | 
| 677       // expected to run between zero and a few tens of tasks between waits. | 698       // expected to run between zero and a few tens of tasks between waits. | 
| 678       // When it runs more than 100 tasks, there is no need to know the exact | 699       // When it runs more than 100 tasks, there is no need to know the exact | 
| 679       // number of tasks that ran. | 700       // number of tasks that ran. | 
| 680       num_tasks_between_waits_histogram_(Histogram::FactoryGet( | 701       num_tasks_between_waits_histogram_(Histogram::FactoryGet( | 
| 681           kNumTasksBetweenWaitsHistogramPrefix + name_ + kPoolNameSuffix, | 702           kNumTasksBetweenWaitsHistogramPrefix + name_ + kPoolNameSuffix, | 
| 682           1, | 703           1, | 
| 683           100, | 704           100, | 
| 684           50, | 705           50, | 
| 685           HistogramBase::kUmaTargetedHistogramFlag)), | 706           HistogramBase::kUmaTargetedHistogramFlag)), | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 765   AutoSchedulerLock auto_lock(idle_workers_stack_lock_); | 786   AutoSchedulerLock auto_lock(idle_workers_stack_lock_); | 
| 766   idle_workers_stack_.Remove(worker); | 787   idle_workers_stack_.Remove(worker); | 
| 767 } | 788 } | 
| 768 | 789 | 
| 769 bool SchedulerWorkerPoolImpl::CanWorkerDetachForTesting() { | 790 bool SchedulerWorkerPoolImpl::CanWorkerDetachForTesting() { | 
| 770   return !worker_detachment_disallowed_.IsSet(); | 791   return !worker_detachment_disallowed_.IsSet(); | 
| 771 } | 792 } | 
| 772 | 793 | 
| 773 }  // namespace internal | 794 }  // namespace internal | 
| 774 }  // namespace base | 795 }  // namespace base | 
| OLD | NEW | 
|---|