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 <memory> | 9 #include <memory> |
10 #include <unordered_set> | 10 #include <unordered_set> |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 void ShouldNotRunCallback() { | 164 void ShouldNotRunCallback() { |
165 ADD_FAILURE() << "Ran a task that shouldn't run."; | 165 ADD_FAILURE() << "Ran a task that shouldn't run."; |
166 } | 166 } |
167 | 167 |
168 } // namespace | 168 } // namespace |
169 | 169 |
170 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasks) { | 170 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasks) { |
171 // Create threads to post tasks. | 171 // Create threads to post tasks. |
172 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 172 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
173 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { | 173 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { |
174 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 174 threads_posting_tasks.push_back(MakeUnique<ThreadPostingTasks>( |
175 worker_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, | 175 worker_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, |
176 PostNestedTask::NO))); | 176 PostNestedTask::NO)); |
177 threads_posting_tasks.back()->Start(); | 177 threads_posting_tasks.back()->Start(); |
178 } | 178 } |
179 | 179 |
180 // Wait for all tasks to run. | 180 // Wait for all tasks to run. |
181 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 181 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
182 thread_posting_tasks->Join(); | 182 thread_posting_tasks->Join(); |
183 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 183 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
184 } | 184 } |
185 | 185 |
186 // Wait until all workers are idle to be sure that no task accesses | 186 // Wait until all workers are idle to be sure that no task accesses |
187 // its TestTaskFactory after |thread_posting_tasks| is destroyed. | 187 // its TestTaskFactory after |thread_posting_tasks| is destroyed. |
188 worker_pool_->WaitForAllWorkersIdleForTesting(); | 188 worker_pool_->WaitForAllWorkersIdleForTesting(); |
189 } | 189 } |
190 | 190 |
191 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWaitAllWorkersIdle) { | 191 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWaitAllWorkersIdle) { |
192 // Create threads to post tasks. To verify that workers can sleep and be woken | 192 // Create threads to post tasks. To verify that workers can sleep and be woken |
193 // up when new tasks are posted, wait for all workers to become idle before | 193 // up when new tasks are posted, wait for all workers to become idle before |
194 // posting a new task. | 194 // posting a new task. |
195 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 195 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
196 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { | 196 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { |
197 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 197 threads_posting_tasks.push_back(MakeUnique<ThreadPostingTasks>( |
198 worker_pool_.get(), GetParam(), | 198 worker_pool_.get(), GetParam(), |
199 WaitBeforePostTask::WAIT_FOR_ALL_WORKERS_IDLE, PostNestedTask::NO))); | 199 WaitBeforePostTask::WAIT_FOR_ALL_WORKERS_IDLE, PostNestedTask::NO)); |
200 threads_posting_tasks.back()->Start(); | 200 threads_posting_tasks.back()->Start(); |
201 } | 201 } |
202 | 202 |
203 // Wait for all tasks to run. | 203 // Wait for all tasks to run. |
204 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 204 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
205 thread_posting_tasks->Join(); | 205 thread_posting_tasks->Join(); |
206 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 206 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
207 } | 207 } |
208 | 208 |
209 // Wait until all workers are idle to be sure that no task accesses its | 209 // Wait until all workers are idle to be sure that no task accesses its |
210 // TestTaskFactory after |thread_posting_tasks| is destroyed. | 210 // TestTaskFactory after |thread_posting_tasks| is destroyed. |
211 worker_pool_->WaitForAllWorkersIdleForTesting(); | 211 worker_pool_->WaitForAllWorkersIdleForTesting(); |
212 } | 212 } |
213 | 213 |
214 TEST_P(TaskSchedulerWorkerPoolImplTest, NestedPostTasks) { | 214 TEST_P(TaskSchedulerWorkerPoolImplTest, NestedPostTasks) { |
215 // Create threads to post tasks. Each task posted by these threads will post | 215 // Create threads to post tasks. Each task posted by these threads will post |
216 // another task when it runs. | 216 // another task when it runs. |
217 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 217 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
218 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { | 218 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { |
219 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 219 threads_posting_tasks.push_back(MakeUnique<ThreadPostingTasks>( |
220 worker_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, | 220 worker_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, |
221 PostNestedTask::YES))); | 221 PostNestedTask::YES)); |
222 threads_posting_tasks.back()->Start(); | 222 threads_posting_tasks.back()->Start(); |
223 } | 223 } |
224 | 224 |
225 // Wait for all tasks to run. | 225 // Wait for all tasks to run. |
226 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 226 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
227 thread_posting_tasks->Join(); | 227 thread_posting_tasks->Join(); |
228 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 228 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
229 } | 229 } |
230 | 230 |
231 // Wait until all workers are idle to be sure that no task accesses its | 231 // Wait until all workers are idle to be sure that no task accesses its |
232 // TestTaskFactory after |thread_posting_tasks| is destroyed. | 232 // TestTaskFactory after |thread_posting_tasks| is destroyed. |
233 worker_pool_->WaitForAllWorkersIdleForTesting(); | 233 worker_pool_->WaitForAllWorkersIdleForTesting(); |
234 } | 234 } |
235 | 235 |
236 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWithOneAvailableWorker) { | 236 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWithOneAvailableWorker) { |
237 // Post blocking tasks to keep all workers busy except one until |event| is | 237 // Post blocking tasks to keep all workers busy except one until |event| is |
238 // signaled. Use different factories so that tasks are added to different | 238 // signaled. Use different factories so that tasks are added to different |
239 // sequences and can run simultaneously when the execution mode is SEQUENCED. | 239 // sequences and can run simultaneously when the execution mode is SEQUENCED. |
240 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 240 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
241 WaitableEvent::InitialState::NOT_SIGNALED); | 241 WaitableEvent::InitialState::NOT_SIGNALED); |
242 std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories; | 242 std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories; |
243 for (size_t i = 0; i < (kNumWorkersInWorkerPool - 1); ++i) { | 243 for (size_t i = 0; i < (kNumWorkersInWorkerPool - 1); ++i) { |
244 blocked_task_factories.push_back(WrapUnique(new test::TestTaskFactory( | 244 blocked_task_factories.push_back(MakeUnique<test::TestTaskFactory>( |
245 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 245 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
246 GetParam()))); | 246 GetParam())); |
247 EXPECT_TRUE(blocked_task_factories.back()->PostTask( | 247 EXPECT_TRUE(blocked_task_factories.back()->PostTask( |
248 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); | 248 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); |
249 blocked_task_factories.back()->WaitForAllTasksToRun(); | 249 blocked_task_factories.back()->WaitForAllTasksToRun(); |
250 } | 250 } |
251 | 251 |
252 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact | 252 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact |
253 // that only one worker in |worker_pool_| isn't busy. | 253 // that only one worker in |worker_pool_| isn't busy. |
254 test::TestTaskFactory short_task_factory( | 254 test::TestTaskFactory short_task_factory( |
255 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 255 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
256 GetParam()); | 256 GetParam()); |
(...skipping 11 matching lines...) Expand all Loading... |
268 | 268 |
269 TEST_P(TaskSchedulerWorkerPoolImplTest, Saturate) { | 269 TEST_P(TaskSchedulerWorkerPoolImplTest, Saturate) { |
270 // Verify that it is possible to have |kNumWorkersInWorkerPool| | 270 // Verify that it is possible to have |kNumWorkersInWorkerPool| |
271 // tasks/sequences running simultaneously. Use different factories so that the | 271 // tasks/sequences running simultaneously. Use different factories so that the |
272 // blocking tasks are added to different sequences and can run simultaneously | 272 // blocking tasks are added to different sequences and can run simultaneously |
273 // when the execution mode is SEQUENCED. | 273 // when the execution mode is SEQUENCED. |
274 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 274 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
275 WaitableEvent::InitialState::NOT_SIGNALED); | 275 WaitableEvent::InitialState::NOT_SIGNALED); |
276 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; | 276 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; |
277 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { | 277 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
278 factories.push_back(WrapUnique(new test::TestTaskFactory( | 278 factories.push_back(MakeUnique<test::TestTaskFactory>( |
279 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 279 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
280 GetParam()))); | 280 GetParam())); |
281 EXPECT_TRUE(factories.back()->PostTask( | 281 EXPECT_TRUE(factories.back()->PostTask( |
282 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); | 282 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); |
283 factories.back()->WaitForAllTasksToRun(); | 283 factories.back()->WaitForAllTasksToRun(); |
284 } | 284 } |
285 | 285 |
286 // Release tasks waiting on |event|. | 286 // Release tasks waiting on |event|. |
287 event.Signal(); | 287 event.Signal(); |
288 | 288 |
289 // Wait until all workers are idle to be sure that no task accesses | 289 // Wait until all workers are idle to be sure that no task accesses |
290 // its TestTaskFactory after it is destroyed. | 290 // its TestTaskFactory after it is destroyed. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 count_waiter->Wait(); | 548 count_waiter->Wait(); |
549 | 549 |
550 EXPECT_GT(subtle::NoBarrier_Load(&zero_tls_values_), 0); | 550 EXPECT_GT(subtle::NoBarrier_Load(&zero_tls_values_), 0); |
551 | 551 |
552 // Release tasks waiting on |waiter_|. | 552 // Release tasks waiting on |waiter_|. |
553 waiter_.Signal(); | 553 waiter_.Signal(); |
554 } | 554 } |
555 | 555 |
556 } // namespace internal | 556 } // namespace internal |
557 } // namespace base | 557 } // namespace base |
OLD | NEW |