Chromium Code Reviews| Index: base/task_scheduler/scheduler_thread_pool.h |
| diff --git a/base/task_scheduler/scheduler_thread_pool.h b/base/task_scheduler/scheduler_thread_pool.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..516946d470db94cbaddecb690eb17849ed974d8c |
| --- /dev/null |
| +++ b/base/task_scheduler/scheduler_thread_pool.h |
| @@ -0,0 +1,138 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef BASE_TASK_SCHEDULER_SCHEDULER_THREAD_POOL_H_ |
| +#define BASE_TASK_SCHEDULER_SCHEDULER_THREAD_POOL_H_ |
| + |
| +#include <stddef.h> |
| + |
| +#include <memory> |
| +#include <stack> |
| +#include <vector> |
| + |
| +#include "base/base_export.h" |
| +#include "base/macros.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/synchronization/condition_variable.h" |
| +#include "base/task_runner.h" |
| +#include "base/task_scheduler/priority_queue.h" |
| +#include "base/task_scheduler/scheduler_lock.h" |
| +#include "base/task_scheduler/scheduler_worker_thread.h" |
| +#include "base/task_scheduler/sequence.h" |
| +#include "base/task_scheduler/task_traits.h" |
| +#include "base/threading/platform_thread.h" |
| +#include "base/threading/thread_local.h" |
| + |
| +namespace base { |
| +namespace internal { |
| + |
| +struct SequenceSortKey; |
| +class TaskTracker; |
| + |
| +// A pool of threads that run Tasks. This class is thread-safe. |
| +class BASE_EXPORT SchedulerThreadPool { |
| + public: |
| + // Creates a SchedulerThreadPool with up to |max_threads| threads of priority |
| + // |thread_priority|. |ran_task_from_sequence_callback| is invoked after a |
| + // thread of this thread pool tries to run a Task from a Sequence. |
| + // |task_tracker| is used to handle shutdown behavior of Tasks. Returns |
| + // nullptr when it's not possible to create a thread pool with at least one |
| + // thread. |
| + static std::unique_ptr<SchedulerThreadPool> CreateThreadPool( |
| + ThreadPriority thread_priority, |
| + size_t max_threads, |
| + const SchedulerWorkerThread::RanTaskFromSequenceCallback& |
| + ran_task_from_sequence_callback, |
| + TaskTracker* task_tracker); |
| + |
| + // Destroying a SchedulerThreadPool in production is not allowed; it is always |
| + // leaked. |
| + // In tests, it can only be destroyed after JoinForTesting() has returned. |
| + ~SchedulerThreadPool(); |
| + |
| + // Returns a TaskRunner whose PostTask invocations will result in scheduling |
| + // Tasks with |traits| and |execution_mode| in this thread pool. |
| + scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits( |
| + const TaskTraits& traits, |
| + ExecutionMode execution_mode); |
| + |
| + // Reinserts |sequence| in |shared_priority_queue_| with |sequence_sort_key| |
|
robliao
2016/04/01 21:05:51
Nit: Into this thread's shared priority queue.
(My
fdoray
2016/04/01 21:45:30
Done.
|
| + // after one of its Tasks ran. |
|
robliao
2016/04/01 21:05:51
The "after one of its Tasks ran" can be removed. I
fdoray
2016/04/01 21:45:30
Done.
|
| + void ReinsertSequence(scoped_refptr<Sequence> sequence, |
| + const SequenceSortKey& sequence_sort_key); |
| + |
| + // Waits until all threads are idle. |
| + void WaitForAllWorkerThreadsIdleForTesting(); |
| + |
| + // Joins all threads of this thread pool. Tasks that are already running are |
| + // allowed to complete their execution. This can only be called once. |
| + void JoinForTesting(); |
| + |
| + private: |
| + SchedulerThreadPool(ThreadPriority thread_priority, |
| + size_t max_threads, |
| + const SchedulerWorkerThread::RanTaskFromSequenceCallback& |
| + ran_task_from_sequence_callback, |
| + TaskTracker* task_tracker); |
| + |
| + // Wakes up one thread from this thread pool if they aren't all busy. |
| + void WakeUpOneThread(); |
| + |
| + // Adds |worker_thread| to |idle_worker_threads_stack_|. |
| + void AddToIdleSchedulerWorkerThreadsStack( |
| + SchedulerWorkerThread* worker_thread); |
| + |
| + // Invoked when a sequence is inserted in |shared_priority_queue_|. |
| + void SequenceInsertedInSharedPriorityQueueCallback(); |
| + |
| + // Invoked when the main function of a worker thread is entered. |
| + void MainEntryCallback() const; |
| + |
| + // Invoked by a worker thread to get a Sequence from which to run a Task. |
| + scoped_refptr<Sequence> GetWorkCallback(SchedulerWorkerThread* worker_thread); |
| + |
| + // PriorityQueue from which all threads of this thread pool get work. |
| + PriorityQueue shared_priority_queue_; |
| + |
| + // All worker threads owned by this thread pool. This is only modified by the |
| + // constructor. |
| + std::vector<std::unique_ptr<SchedulerWorkerThread>> worker_threads_; |
| + |
| + // True if WakeUpOneThread() shouldn't be called when a Sequence is inserted |
| + // in |shared_priority_queue_| by a given thread. |
| + ThreadLocalBoolean no_wake_up_on_sequence_insertion_; |
| + |
| + // Synchronizes access to |idle_worker_threads_stack_| and |
| + // |idle_worker_threads_cv_|. |
| + SchedulerLock idle_worker_threads_stack_lock_; |
| + |
| + // Stack of idle worker threads. The last worker thread that became idle is on |
| + // top of the stack. |
| + std::stack<SchedulerWorkerThread*> idle_worker_threads_stack_; |
| + |
| + // Signaled when all worker threads become idle. |
| + std::unique_ptr<ConditionVariable> idle_worker_threads_stack_cv_; |
| + |
| + // Synchronizes access to |join_for_testing_returned_|. |
| + SchedulerLock join_for_testing_returned_lock_; |
| + |
| + // True once JoinForTesting() has returned. |
| + bool join_for_testing_returned_ = false; |
| + |
| + TaskTracker* const task_tracker_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SchedulerThreadPool); |
| +}; |
| + |
| +// Helper for posting |task| to the provided |sequence| and |priority_queue| |
| +// conditional on |task_tracker|. Exposed for testing. |
| +void BASE_EXPORT PostTaskHelper(std::unique_ptr<Task> task, |
| + scoped_refptr<Sequence> sequence, |
| + PriorityQueue* priority_queue, |
| + TaskTracker* task_tracker); |
| + |
| +} // namespace internal |
| +} // namespace base |
| + |
| +#endif // BASE_TASK_SCHEDULER_SCHEDULER_THREAD_POOL_H_ |