| 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 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_THREAD_POOL_IMPL_H_ | 5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_ | 
| 6 #define BASE_TASK_SCHEDULER_SCHEDULER_THREAD_POOL_IMPL_H_ | 6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_ | 
| 7 | 7 | 
| 8 #include <stddef.h> | 8 #include <stddef.h> | 
| 9 | 9 | 
| 10 #include <memory> | 10 #include <memory> | 
| 11 #include <string> | 11 #include <string> | 
| 12 #include <vector> | 12 #include <vector> | 
| 13 | 13 | 
| 14 #include "base/base_export.h" | 14 #include "base/base_export.h" | 
| 15 #include "base/callback.h" | 15 #include "base/callback.h" | 
| 16 #include "base/logging.h" | 16 #include "base/logging.h" | 
| 17 #include "base/macros.h" | 17 #include "base/macros.h" | 
| 18 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" | 
| 19 #include "base/strings/string_piece.h" | 19 #include "base/strings/string_piece.h" | 
| 20 #include "base/synchronization/condition_variable.h" | 20 #include "base/synchronization/condition_variable.h" | 
| 21 #include "base/task_runner.h" | 21 #include "base/task_runner.h" | 
| 22 #include "base/task_scheduler/priority_queue.h" | 22 #include "base/task_scheduler/priority_queue.h" | 
| 23 #include "base/task_scheduler/scheduler_lock.h" | 23 #include "base/task_scheduler/scheduler_lock.h" | 
| 24 #include "base/task_scheduler/scheduler_thread_pool.h" | 24 #include "base/task_scheduler/scheduler_worker_pool.h" | 
| 25 #include "base/task_scheduler/scheduler_worker_thread.h" | 25 #include "base/task_scheduler/scheduler_worker_thread.h" | 
| 26 #include "base/task_scheduler/scheduler_worker_thread_stack.h" | 26 #include "base/task_scheduler/scheduler_worker_thread_stack.h" | 
| 27 #include "base/task_scheduler/sequence.h" | 27 #include "base/task_scheduler/sequence.h" | 
| 28 #include "base/task_scheduler/task.h" | 28 #include "base/task_scheduler/task.h" | 
| 29 #include "base/task_scheduler/task_traits.h" | 29 #include "base/task_scheduler/task_traits.h" | 
| 30 #include "base/threading/platform_thread.h" | 30 #include "base/threading/platform_thread.h" | 
| 31 | 31 | 
| 32 namespace base { | 32 namespace base { | 
| 33 namespace internal { | 33 namespace internal { | 
| 34 | 34 | 
| 35 class DelayedTaskManager; | 35 class DelayedTaskManager; | 
| 36 class TaskTracker; | 36 class TaskTracker; | 
| 37 | 37 | 
| 38 // A pool of threads that run Tasks. This class is thread-safe. | 38 // A pool of workers that run Tasks. This class is thread-safe. | 
| 39 class BASE_EXPORT SchedulerThreadPoolImpl : public SchedulerThreadPool { | 39 class BASE_EXPORT SchedulerWorkerPoolImpl : public SchedulerWorkerPool { | 
| 40  public: | 40  public: | 
| 41   enum class IORestriction { | 41   enum class IORestriction { | 
| 42     ALLOWED, | 42     ALLOWED, | 
| 43     DISALLOWED, | 43     DISALLOWED, | 
| 44   }; | 44   }; | 
| 45 | 45 | 
| 46   // Callback invoked when a Sequence isn't empty after a worker thread pops a | 46   // Callback invoked when a Sequence isn't empty after a worker pops a Task | 
| 47   // Task from it. | 47   // from it. | 
| 48   using ReEnqueueSequenceCallback = Callback<void(scoped_refptr<Sequence>)>; | 48   using ReEnqueueSequenceCallback = Callback<void(scoped_refptr<Sequence>)>; | 
| 49 | 49 | 
| 50   // Destroying a SchedulerThreadPool returned by CreateThreadPool() is not | 50   // Destroying a SchedulerWorkerPoolImpl returned by Create() is not allowed in | 
| 51   // allowed in production; it is always leaked. In tests, it can only be | 51   // production; it is always leaked. In tests, it can only be destroyed after | 
| 52   // destroyed after JoinForTesting() has returned. | 52   // JoinForTesting() has returned. | 
| 53   ~SchedulerThreadPoolImpl() override; | 53   ~SchedulerWorkerPoolImpl() override; | 
| 54 | 54 | 
| 55   // Creates a SchedulerThreadPool labeled |name| with up to |max_threads| | 55   // Creates a SchedulerWorkerPoolImpl labeled |name| with up to |max_threads| | 
| 56   // threads of priority |thread_priority|. |io_restriction| indicates whether | 56   // threads of priority |thread_priority|. |io_restriction| indicates whether | 
| 57   // Tasks on the constructed thread pool are allowed to make I/O calls. | 57   // Tasks on the constructed worker pool are allowed to make I/O calls. | 
| 58   // |re_enqueue_sequence_callback| will be invoked after a thread of this | 58   // |re_enqueue_sequence_callback| will be invoked after a worker of this | 
| 59   // thread pool tries to run a Task. |task_tracker| is used to handle shutdown | 59   // worker pool tries to run a Task. |task_tracker| is used to handle shutdown | 
| 60   // behavior of Tasks. |delayed_task_manager| handles Tasks posted with a | 60   // behavior of Tasks. |delayed_task_manager| handles Tasks posted with a | 
| 61   // delay. Returns nullptr on failure to create a thread pool with at least one | 61   // delay. Returns nullptr on failure to create a worker pool with at least one | 
| 62   // thread. | 62   // thread. | 
| 63   static std::unique_ptr<SchedulerThreadPoolImpl> Create( | 63   static std::unique_ptr<SchedulerWorkerPoolImpl> Create( | 
| 64       StringPiece name, | 64       StringPiece name, | 
| 65       ThreadPriority thread_priority, | 65       ThreadPriority thread_priority, | 
| 66       size_t max_threads, | 66       size_t max_threads, | 
| 67       IORestriction io_restriction, | 67       IORestriction io_restriction, | 
| 68       const ReEnqueueSequenceCallback& re_enqueue_sequence_callback, | 68       const ReEnqueueSequenceCallback& re_enqueue_sequence_callback, | 
| 69       TaskTracker* task_tracker, | 69       TaskTracker* task_tracker, | 
| 70       DelayedTaskManager* delayed_task_manager); | 70       DelayedTaskManager* delayed_task_manager); | 
| 71 | 71 | 
| 72   // Waits until all threads are idle. | 72   // Waits until all workers are idle. | 
| 73   void WaitForAllWorkerThreadsIdleForTesting(); | 73   void WaitForAllWorkerWorkersIdleForTesting(); | 
| 74 | 74 | 
| 75   // Joins all threads of this thread pool. Tasks that are already running are | 75   // Joins all workers of this worker pool. Tasks that are already running are | 
| 76   // allowed to complete their execution. This can only be called once. | 76   // allowed to complete their execution. This can only be called once. | 
| 77   void JoinForTesting(); | 77   void JoinForTesting(); | 
| 78 | 78 | 
| 79   // SchedulerThreadPool: | 79   // SchedulerWorkerPool: | 
| 80   scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( | 80   scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( | 
| 81       const TaskTraits& traits, | 81       const TaskTraits& traits, | 
| 82       ExecutionMode execution_mode) override; | 82       ExecutionMode execution_mode) override; | 
| 83   void ReEnqueueSequence(scoped_refptr<Sequence> sequence, | 83   void ReEnqueueSequence(scoped_refptr<Sequence> sequence, | 
| 84                          const SequenceSortKey& sequence_sort_key) override; | 84                          const SequenceSortKey& sequence_sort_key) override; | 
| 85   bool PostTaskWithSequence(std::unique_ptr<Task> task, | 85   bool PostTaskWithSequence(std::unique_ptr<Task> task, | 
| 86                             scoped_refptr<Sequence> sequence, | 86                             scoped_refptr<Sequence> sequence, | 
| 87                             SchedulerWorkerThread* worker_thread) override; | 87                             SchedulerWorkerThread* worker_thread) override; | 
| 88   void PostTaskWithSequenceNow(std::unique_ptr<Task> task, | 88   void PostTaskWithSequenceNow(std::unique_ptr<Task> task, | 
| 89                                scoped_refptr<Sequence> sequence, | 89                                scoped_refptr<Sequence> sequence, | 
| 90                                SchedulerWorkerThread* worker_thread) override; | 90                                SchedulerWorkerThread* worker_thread) override; | 
| 91 | 91 | 
| 92  private: | 92  private: | 
| 93   class SchedulerWorkerThreadDelegateImpl; | 93   class SchedulerWorkerThreadDelegateImpl; | 
| 94 | 94 | 
| 95   SchedulerThreadPoolImpl(StringPiece name, | 95   SchedulerWorkerPoolImpl(StringPiece name, | 
| 96                           IORestriction io_restriction, | 96                           IORestriction io_restriction, | 
| 97                           TaskTracker* task_tracker, | 97                           TaskTracker* task_tracker, | 
| 98                           DelayedTaskManager* delayed_task_manager); | 98                           DelayedTaskManager* delayed_task_manager); | 
| 99 | 99 | 
| 100   bool Initialize( | 100   bool Initialize( | 
| 101       ThreadPriority thread_priority, | 101       ThreadPriority thread_priority, | 
| 102       size_t max_threads, | 102       size_t max_threads, | 
| 103       const ReEnqueueSequenceCallback& re_enqueue_sequence_callback); | 103       const ReEnqueueSequenceCallback& re_enqueue_sequence_callback); | 
| 104 | 104 | 
| 105   // Wakes up the last thread from this thread pool to go idle, if any. | 105   // Wakes up the last worker from this worker pool to go idle, if any. | 
| 106   void WakeUpOneThread(); | 106   void WakeUpOneWorker(); | 
| 107 | 107 | 
| 108   // Adds |worker_thread| to |idle_worker_threads_stack_|. | 108   // Adds |worker_thread| to |idle_worker_threads_stack_|. | 
| 109   void AddToIdleWorkerThreadsStack(SchedulerWorkerThread* worker_thread); | 109   void AddToIdleWorkerThreadsStack(SchedulerWorkerThread* worker_thread); | 
| 110 | 110 | 
| 111   // Removes |worker_thread| from |idle_worker_threads_stack_|. | 111   // Removes |worker_thread| from |idle_worker_threads_stack_|. | 
| 112   void RemoveFromIdleWorkerThreadsStack(SchedulerWorkerThread* worker_thread); | 112   void RemoveFromIdleWorkerThreadsStack(SchedulerWorkerThread* worker_thread); | 
| 113 | 113 | 
| 114   // The name of this thread pool, used to label its worker threads. | 114   // The name of this worker pool, used to label its worker threads. | 
| 115   const std::string name_; | 115   const std::string name_; | 
| 116 | 116 | 
| 117   // All worker threads owned by this thread pool. Only modified during | 117   // All worker threads owned by this worker pool. Only modified during | 
| 118   // initialization of the thread pool. | 118   // initialization of the worker pool. | 
| 119   std::vector<std::unique_ptr<SchedulerWorkerThread>> worker_threads_; | 119   std::vector<std::unique_ptr<SchedulerWorkerThread>> worker_threads_; | 
| 120 | 120 | 
| 121   // Synchronizes access to |next_worker_thread_index_|. | 121   // Synchronizes access to |next_worker_thread_index_|. | 
| 122   SchedulerLock next_worker_thread_index_lock_; | 122   SchedulerLock next_worker_thread_index_lock_; | 
| 123 | 123 | 
| 124   // Index of the worker thread that will be assigned to the next single- | 124   // Index of the worker thread that will be assigned to the next single- | 
| 125   // threaded TaskRunner returned by this pool. | 125   // threaded TaskRunner returned by this pool. | 
| 126   size_t next_worker_thread_index_ = 0; | 126   size_t next_worker_thread_index_ = 0; | 
| 127 | 127 | 
| 128   // PriorityQueue from which all threads of this thread pool get work. | 128   // PriorityQueue from which all threads of this worker pool get work. | 
| 129   PriorityQueue shared_priority_queue_; | 129   PriorityQueue shared_priority_queue_; | 
| 130 | 130 | 
| 131   // Indicates whether Tasks on this thread pool are allowed to make I/O calls. | 131   // Indicates whether Tasks on this worker pool are allowed to make I/O calls. | 
| 132   const IORestriction io_restriction_; | 132   const IORestriction io_restriction_; | 
| 133 | 133 | 
| 134   // Synchronizes access to |idle_worker_threads_stack_| and | 134   // Synchronizes access to |idle_worker_threads_stack_| and | 
| 135   // |idle_worker_threads_stack_cv_for_testing_|. Has |shared_priority_queue_|'s | 135   // |idle_worker_threads_stack_cv_for_testing_|. Has |shared_priority_queue_|'s | 
| 136   // lock as its predecessor so that a thread can be pushed to | 136   // lock as its predecessor so that a thread can be pushed to | 
| 137   // |idle_worker_threads_stack_| within the scope of a Transaction (more | 137   // |idle_worker_threads_stack_| within the scope of a Transaction (more | 
| 138   // details in GetWork()). | 138   // details in GetWork()). | 
| 139   SchedulerLock idle_worker_threads_stack_lock_; | 139   SchedulerLock idle_worker_threads_stack_lock_; | 
| 140 | 140 | 
| 141   // Stack of idle worker threads. | 141   // Stack of idle worker threads. | 
| 142   SchedulerWorkerThreadStack idle_worker_threads_stack_; | 142   SchedulerWorkerThreadStack idle_worker_threads_stack_; | 
| 143 | 143 | 
| 144   // Signaled when all worker threads become idle. | 144   // Signaled when all worker threads become idle. | 
| 145   std::unique_ptr<ConditionVariable> idle_worker_threads_stack_cv_for_testing_; | 145   std::unique_ptr<ConditionVariable> idle_worker_threads_stack_cv_for_testing_; | 
| 146 | 146 | 
| 147   // Signaled once JoinForTesting() has returned. | 147   // Signaled once JoinForTesting() has returned. | 
| 148   WaitableEvent join_for_testing_returned_; | 148   WaitableEvent join_for_testing_returned_; | 
| 149 | 149 | 
| 150 #if DCHECK_IS_ON() | 150 #if DCHECK_IS_ON() | 
| 151   // Signaled when all threads have been created. | 151   // Signaled when all threads have been created. | 
| 152   WaitableEvent threads_created_; | 152   WaitableEvent threads_created_; | 
| 153 #endif | 153 #endif | 
| 154 | 154 | 
| 155   TaskTracker* const task_tracker_; | 155   TaskTracker* const task_tracker_; | 
| 156   DelayedTaskManager* const delayed_task_manager_; | 156   DelayedTaskManager* const delayed_task_manager_; | 
| 157 | 157 | 
| 158   DISALLOW_COPY_AND_ASSIGN(SchedulerThreadPoolImpl); | 158   DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerPoolImpl); | 
| 159 }; | 159 }; | 
| 160 | 160 | 
| 161 }  // namespace internal | 161 }  // namespace internal | 
| 162 }  // namespace base | 162 }  // namespace base | 
| 163 | 163 | 
| 164 #endif  // BASE_TASK_SCHEDULER_SCHEDULER_THREAD_POOL_IMPL_H_ | 164 #endif  // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_POOL_IMPL_H_ | 
| OLD | NEW | 
|---|