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_thread.h" | 5 #include "base/task_scheduler/scheduler_worker_thread.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <vector> | 10 #include <vector> |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 // returned by GetWork(). | 87 // returned by GetWork(). |
88 EXPECT_EQ(created_sequences_.size(), num_run_tasks_); | 88 EXPECT_EQ(created_sequences_.size(), num_run_tasks_); |
89 } | 89 } |
90 | 90 |
91 void SetNumSequencesToCreate(size_t num_sequences_to_create) { | 91 void SetNumSequencesToCreate(size_t num_sequences_to_create) { |
92 AutoSchedulerLock auto_lock(lock_); | 92 AutoSchedulerLock auto_lock(lock_); |
93 EXPECT_EQ(0U, num_sequences_to_create_); | 93 EXPECT_EQ(0U, num_sequences_to_create_); |
94 num_sequences_to_create_ = num_sequences_to_create; | 94 num_sequences_to_create_ = num_sequences_to_create; |
95 } | 95 } |
96 | 96 |
97 size_t NumGetWork() const { | 97 void SetMaxGetWork(size_t max_get_work) { |
98 AutoSchedulerLock auto_lock(lock_); | 98 AutoSchedulerLock auto_lock(lock_); |
99 return num_get_work_; | 99 max_get_work_ = max_get_work; |
100 } | 100 } |
101 | 101 |
102 std::unique_ptr<SchedulerWorkerThread> worker_thread_; | 102 std::unique_ptr<SchedulerWorkerThread> worker_thread_; |
103 | 103 |
104 private: | 104 private: |
105 // SchedulerWorkerThreadDelegate: | 105 // SchedulerWorkerThreadDelegate: |
106 void OnMainEntry() override { | 106 void OnMainEntry() override { |
107 AutoSchedulerLock auto_lock(lock_); | 107 AutoSchedulerLock auto_lock(lock_); |
108 ++num_main_entry_; | 108 ++num_main_entry_; |
109 num_main_entry_cv_->Signal(); | 109 num_main_entry_cv_->Signal(); |
110 } | 110 } |
111 | 111 |
112 void OnMainExit() override { | 112 void OnMainExit() override { |
113 AutoSchedulerLock auto_lock(lock_); | 113 AutoSchedulerLock auto_lock(lock_); |
114 ++num_main_exit_; | 114 ++num_main_exit_; |
115 } | 115 } |
116 | 116 |
117 scoped_refptr<Sequence> GetWork() override { | 117 scoped_refptr<Sequence> GetWork() override { |
118 { | 118 { |
119 AutoSchedulerLock auto_lock(lock_); | 119 AutoSchedulerLock auto_lock(lock_); |
120 | 120 |
121 // Increment the number of times that this method has been called. | 121 // Increment the number of times that this method has been called. |
122 ++num_get_work_; | 122 ++num_get_work_; |
123 num_get_work_cv_->Signal(); | 123 num_get_work_cv_->Signal(); |
124 | 124 |
125 // Verify that this method isn't called more times than expected. | |
126 EXPECT_LE(num_get_work_, max_get_work_); | |
127 | |
125 // Check if a Sequence should be returned. | 128 // Check if a Sequence should be returned. |
126 if (num_sequences_to_create_ == 0) | 129 if (num_sequences_to_create_ == 0) |
127 return nullptr; | 130 return nullptr; |
128 --num_sequences_to_create_; | 131 --num_sequences_to_create_; |
129 } | 132 } |
130 | 133 |
131 // Create a Sequence that contains 1 Task. | 134 // Create a Sequence that contains 1 Task. |
132 scoped_refptr<Sequence> sequence(new Sequence); | 135 scoped_refptr<Sequence> sequence(new Sequence); |
133 task_tracker_.PostTask( | 136 task_tracker_.PostTask( |
134 Bind(IgnoreResult(&Sequence::PushTask), Unretained(sequence.get())), | 137 Bind(IgnoreResult(&Sequence::PushTask), Unretained(sequence.get())), |
135 WrapUnique(new Task( | 138 WrapUnique(new Task( |
136 FROM_HERE, Bind(&TaskSchedulerWorkerThreadTest::RunTaskCallback, | 139 FROM_HERE, Bind(&TaskSchedulerWorkerThreadTest::RunTaskCallback, |
137 Unretained(this)), | 140 Unretained(this)), |
138 TaskTraits()))); | 141 TaskTraits()))); |
139 | 142 |
140 { | 143 { |
141 // Add the Sequence to the vector of created Sequences. | 144 // Add the Sequence to the vector of created Sequences. |
142 AutoSchedulerLock auto_lock(lock_); | 145 AutoSchedulerLock auto_lock(lock_); |
143 created_sequences_.push_back(sequence); | 146 created_sequences_.push_back(sequence); |
144 } | 147 } |
145 | 148 |
146 return sequence; | 149 return sequence; |
147 } | 150 } |
148 | 151 |
149 // Called after the SchedulerWorkerThread has tried to run a Task from | 152 // Called after the SchedulerWorkerThread has tried to run a Task from |
150 // |sequence| (a TaskTracker might have prevented the Task from running). | 153 // |sequence| (a TaskTracker might have prevented the Task from running). |
151 void RanTaskFromSequence(scoped_refptr<Sequence> sequence) override { | 154 void RanTaskFromSequence(scoped_refptr<Sequence> sequence) override { |
152 AutoSchedulerLock auto_lock(lock_); | 155 AutoSchedulerLock auto_lock(lock_); |
153 run_sequences_.push_back(std::move(sequence)); | 156 run_sequences_.push_back(std::move(sequence)); |
157 EXPECT_LE(run_sequences_.size(), created_sequences_.size()); | |
154 run_sequences_cv_->Signal(); | 158 run_sequences_cv_->Signal(); |
155 } | 159 } |
156 | 160 |
157 void RunTaskCallback() { | 161 void RunTaskCallback() { |
158 AutoSchedulerLock auto_lock(lock_); | 162 AutoSchedulerLock auto_lock(lock_); |
159 ++num_run_tasks_; | 163 ++num_run_tasks_; |
164 EXPECT_LE(num_run_tasks_, created_sequences_.size()); | |
160 } | 165 } |
161 | 166 |
162 TaskTracker task_tracker_; | 167 TaskTracker task_tracker_; |
163 | 168 |
164 // Synchronizes access to all members below. | 169 // Synchronizes access to all members below. |
165 mutable SchedulerLock lock_; | 170 mutable SchedulerLock lock_; |
166 | 171 |
167 // Number of times that OnMainEntry() has been called. | 172 // Number of times that OnMainEntry() has been called. |
168 size_t num_main_entry_ = 0; | 173 size_t num_main_entry_ = 0; |
169 | 174 |
170 // Condition variable signaled when |num_main_entry_| is incremented. | 175 // Condition variable signaled when |num_main_entry_| is incremented. |
171 std::unique_ptr<ConditionVariable> num_main_entry_cv_; | 176 std::unique_ptr<ConditionVariable> num_main_entry_cv_; |
172 | 177 |
173 // Number of times that OnMainExit() has been called. | 178 // Number of times that OnMainExit() has been called. |
174 size_t num_main_exit_ = 0; | 179 size_t num_main_exit_ = 0; |
175 | 180 |
176 // Number of Sequences that should be created by GetWork(). When this | 181 // Number of Sequences that should be created by GetWork(). When this |
177 // is 0, GetWork() returns nullptr. | 182 // is 0, GetWork() returns nullptr. |
178 size_t num_sequences_to_create_ = 0; | 183 size_t num_sequences_to_create_ = 0; |
179 | 184 |
180 // Number of times that GetWork() has been called. | 185 // Number of times that GetWork() has been called. |
181 size_t num_get_work_ = 0; | 186 size_t num_get_work_ = 0; |
182 | 187 |
188 // Maximum number of times that GetWork() can be called. | |
189 size_t max_get_work_ = 0; | |
190 | |
183 // Condition variable signaled when |num_get_work_| is incremented. | 191 // Condition variable signaled when |num_get_work_| is incremented. |
184 std::unique_ptr<ConditionVariable> num_get_work_cv_; | 192 std::unique_ptr<ConditionVariable> num_get_work_cv_; |
185 | 193 |
186 // Sequences created by GetWork(). | 194 // Sequences created by GetWork(). |
187 std::vector<scoped_refptr<Sequence>> created_sequences_; | 195 std::vector<scoped_refptr<Sequence>> created_sequences_; |
188 | 196 |
189 // Sequences passed to RanTaskFromSequence(). | 197 // Sequences passed to RanTaskFromSequence(). |
190 std::vector<scoped_refptr<Sequence>> run_sequences_; | 198 std::vector<scoped_refptr<Sequence>> run_sequences_; |
191 | 199 |
192 // Condition variable signaled when a Sequence is added to |run_sequences_|. | 200 // Condition variable signaled when a Sequence is added to |run_sequences_|. |
193 std::unique_ptr<ConditionVariable> run_sequences_cv_; | 201 std::unique_ptr<ConditionVariable> run_sequences_cv_; |
194 | 202 |
195 // Number of times that RunTaskCallback() has been called. | 203 // Number of times that RunTaskCallback() has been called. |
196 size_t num_run_tasks_ = 0; | 204 size_t num_run_tasks_ = 0; |
197 | 205 |
198 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadTest); | 206 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadTest); |
199 }; | 207 }; |
200 | 208 |
201 // Verify that when GetWork() continuously returns Sequences, all Tasks in these | 209 // Verify that when GetWork() continuously returns Sequences, all Tasks in these |
202 // Sequences run successfully. The SchedulerWorkerThread is woken up once. | 210 // Sequences run successfully. The test wakes up the SchedulerWorkerThread once. |
203 TEST_F(TaskSchedulerWorkerThreadTest, ContinousWork) { | 211 TEST_F(TaskSchedulerWorkerThreadTest, ContinuousWork) { |
204 // Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to | 212 // Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to |
205 // return nullptr. | 213 // return nullptr. |
206 SetNumSequencesToCreate(kNumSequencesPerTest); | 214 SetNumSequencesToCreate(kNumSequencesPerTest); |
207 | 215 |
216 // Expect |kNumSequencesPerTest| calls to GetWork() in which it returns a | |
217 // Sequence and 1 call in which its returns nullptr. | |
gab
2016/04/07 15:47:36
s/1/one/ (in comments err towards only using digit
fdoray
2016/04/07 22:17:16
Done.
| |
218 const size_t kExpectedNumGetWork = kNumSequencesPerTest + 1; | |
219 SetMaxGetWork(kExpectedNumGetWork); | |
220 | |
208 // Wake up |worker_thread_| and wait until it has run all the Tasks returned | 221 // Wake up |worker_thread_| and wait until it has run all the Tasks returned |
209 // by GetWork(). | 222 // by GetWork(). |
210 worker_thread_->WakeUp(); | 223 worker_thread_->WakeUp(); |
211 WaitForAllSequencesToRun(); | 224 WaitForAllSequencesToRun(); |
212 | 225 WaitForNumGetWork(kExpectedNumGetWork); |
213 // Expect |kNumSequencesPerTest| calls to GetWork() in which it returned a | |
214 // Sequence and 1 call in which it returned nullptr. | |
215 const size_t expected_num_get_work = kNumSequencesPerTest + 1; | |
216 WaitForNumGetWork(expected_num_get_work); | |
217 EXPECT_EQ(expected_num_get_work, NumGetWork()); | |
218 } | 226 } |
219 | 227 |
220 // Verify that when GetWork() alternates between returning a Sequence and | 228 // Verify that when GetWork() alternates between returning a Sequence and |
221 // returning nullptr, all Tasks in the returned Sequences run successfully. The | 229 // returning nullptr, all Tasks in the returned Sequences run successfully. The |
222 // SchedulerWorkerThread is woken up once for each Sequence. | 230 // test wakes up the SchedulerWorkerThread once for each Sequence. |
223 TEST_F(TaskSchedulerWorkerThreadTest, IntermittentWork) { | 231 TEST_F(TaskSchedulerWorkerThreadTest, IntermittentWork) { |
224 for (size_t i = 0; i < kNumSequencesPerTest; ++i) { | 232 for (size_t i = 0; i < kNumSequencesPerTest; ++i) { |
225 // Set GetWork() to return 1 Sequence before starting to return | 233 // Set GetWork() to return 1 Sequence before starting to return |
226 // nullptr. | 234 // nullptr. |
227 SetNumSequencesToCreate(1); | 235 SetNumSequencesToCreate(1); |
228 | 236 |
237 // Expect |i + 1| calls to GetWork() in which it returns a Sequence and | |
238 // |i + 1| calls in which it returns nullptr. | |
239 const size_t expected_num_get_work = 2 * (i + 1); | |
240 SetMaxGetWork(expected_num_get_work); | |
241 | |
229 // Wake up |worker_thread_| and wait until it has run all the Tasks returned | 242 // Wake up |worker_thread_| and wait until it has run all the Tasks returned |
230 // by GetWork(). | 243 // by GetWork(). |
231 worker_thread_->WakeUp(); | 244 worker_thread_->WakeUp(); |
232 WaitForAllSequencesToRun(); | 245 WaitForAllSequencesToRun(); |
233 | |
234 // Expect |i| calls to GetWork() in which it returned a Sequence and | |
235 // |i| calls in which it returned nullptr. | |
236 const size_t expected_num_get_work = 2 * (i + 1); | |
237 WaitForNumGetWork(expected_num_get_work); | 246 WaitForNumGetWork(expected_num_get_work); |
238 EXPECT_EQ(expected_num_get_work, NumGetWork()); | |
239 } | 247 } |
240 } | 248 } |
241 | 249 |
242 } // namespace | 250 } // namespace |
243 } // namespace internal | 251 } // namespace internal |
244 } // namespace base | 252 } // namespace base |
OLD | NEW |