OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/task_scheduler/task_scheduler_impl.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/bind_helpers.h" | |
11 #include "base/logging.h" | |
12 #include "base/task_scheduler/sequence_sort_key.h" | |
13 | |
14 namespace base { | |
15 namespace internal { | |
16 | |
17 TaskSchedulerImpl::~TaskSchedulerImpl() { | |
18 DCHECK(join_for_testing_returned_.IsSignaled()); | |
19 } | |
20 | |
21 // static | |
22 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create() { | |
gab
2016/04/27 19:15:28
In SchedulerThreadPool we had a static Create() wi
fdoray
2016/04/28 18:36:32
Done.
robliao
2016/04/29 18:34:21
While this class doesn't support creation failure,
fdoray
2016/04/29 19:42:42
If TaskSchedulerImpl::Create successfully creates
gab
2016/04/29 20:33:18
Agreed, and I think the "doing work in the constru
| |
23 std::unique_ptr<TaskSchedulerImpl> scheduler(new TaskSchedulerImpl); | |
24 scheduler->Initialize(); | |
25 return scheduler; | |
26 } | |
27 | |
28 scoped_refptr<TaskRunner> TaskSchedulerImpl::CreateTaskRunnerWithTraits( | |
29 const TaskTraits& traits, | |
30 ExecutionMode execution_mode) { | |
31 return GetThreadPoolForTraits(traits)->CreateTaskRunnerWithTraits( | |
32 traits, execution_mode); | |
33 } | |
34 | |
35 void TaskSchedulerImpl::Shutdown() { | |
36 // TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown. | |
37 task_tracker_.Shutdown(); | |
38 } | |
39 | |
40 void TaskSchedulerImpl::JoinForTesting() { | |
41 DCHECK(!join_for_testing_returned_.IsSignaled()); | |
42 background_thread_pool_->JoinForTesting(); | |
43 background_file_io_thread_pool_->JoinForTesting(); | |
44 normal_thread_pool_->JoinForTesting(); | |
45 normal_file_io_thread_pool_->JoinForTesting(); | |
46 join_for_testing_returned_.Signal(); | |
47 } | |
48 | |
49 TaskSchedulerImpl::TaskSchedulerImpl() | |
50 // TODO(robliao): Wake up the service thread instead of calling DoNothing() | |
51 // when the delayed run time changes. | |
52 : delayed_task_manager_(Bind(&DoNothing)), | |
53 join_for_testing_returned_(true, false) {} | |
54 | |
55 void TaskSchedulerImpl::Initialize() { | |
56 const SchedulerThreadPoolImpl::ReEnqueueSequenceCallback | |
57 re_enqueue_sequence_callback = | |
58 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); | |
59 | |
60 // TODO(fdoray): Derive the number of threads per pool from hardware | |
61 // characteristics rather than using hard-coded constants. | |
62 | |
63 // Passing pointers to objects owned by |this| to | |
64 // SchedulerThreadPoolImpl::Create() is safe because a TaskSchedulerImpl can't | |
65 // be deleted before all its thread pools have been joined. | |
66 background_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
67 ThreadPriority::BACKGROUND, 1U, re_enqueue_sequence_callback, | |
68 &task_tracker_, &delayed_task_manager_); | |
69 CHECK(background_thread_pool_); | |
70 | |
71 background_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
72 ThreadPriority::BACKGROUND, 1U, re_enqueue_sequence_callback, | |
73 &task_tracker_, &delayed_task_manager_); | |
74 CHECK(background_file_io_thread_pool_); | |
75 | |
76 normal_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
77 ThreadPriority::NORMAL, 4U, re_enqueue_sequence_callback, &task_tracker_, | |
78 &delayed_task_manager_); | |
79 CHECK(normal_thread_pool_); | |
80 | |
81 normal_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
82 ThreadPriority::NORMAL, 12U, re_enqueue_sequence_callback, &task_tracker_, | |
83 &delayed_task_manager_); | |
84 CHECK(normal_file_io_thread_pool_); | |
85 } | |
86 | |
87 SchedulerThreadPool* TaskSchedulerImpl::GetThreadPoolForTraits( | |
88 const TaskTraits& traits) { | |
89 if (traits.with_file_io()) { | |
90 if (traits.priority() == TaskPriority::BACKGROUND) | |
91 return background_file_io_thread_pool_.get(); | |
92 return normal_file_io_thread_pool_.get(); | |
93 } | |
94 | |
95 if (traits.priority() == TaskPriority::BACKGROUND) | |
96 return background_thread_pool_.get(); | |
97 return normal_thread_pool_.get(); | |
98 } | |
99 | |
100 void TaskSchedulerImpl::ReEnqueueSequenceCallback( | |
101 scoped_refptr<Sequence> sequence) { | |
102 DCHECK(sequence); | |
103 | |
104 const SequenceSortKey sort_key = sequence->GetSortKey(); | |
105 const Task* next_task_in_sequence = sequence->PeekTask(); | |
106 DCHECK(next_task_in_sequence); | |
107 | |
108 TaskTraits traits = TaskTraits().WithPriority(sort_key.priority); | |
109 if (next_task_in_sequence->traits.with_file_io()) | |
110 traits = traits.WithFileIO(); | |
111 | |
112 GetThreadPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), | |
gab
2016/04/27 19:15:28
Why not use |next_task_in_sequence->traits| instea
fdoray
2016/04/28 18:36:32
Added comment to explain why I do this.
| |
113 sort_key); | |
114 } | |
115 | |
116 } // namespace internal | |
117 } // namespace base | |
OLD | NEW |