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 12 matching lines...) Expand all Loading... |
23 #include "base/synchronization/condition_variable.h" | 23 #include "base/synchronization/condition_variable.h" |
24 #include "base/synchronization/lock.h" | 24 #include "base/synchronization/lock.h" |
25 #include "base/synchronization/waitable_event.h" | 25 #include "base/synchronization/waitable_event.h" |
26 #include "base/task_runner.h" | 26 #include "base/task_runner.h" |
27 #include "base/task_scheduler/delayed_task_manager.h" | 27 #include "base/task_scheduler/delayed_task_manager.h" |
28 #include "base/task_scheduler/scheduler_worker_pool_params.h" | 28 #include "base/task_scheduler/scheduler_worker_pool_params.h" |
29 #include "base/task_scheduler/sequence.h" | 29 #include "base/task_scheduler/sequence.h" |
30 #include "base/task_scheduler/sequence_sort_key.h" | 30 #include "base/task_scheduler/sequence_sort_key.h" |
31 #include "base/task_scheduler/task_tracker.h" | 31 #include "base/task_scheduler/task_tracker.h" |
32 #include "base/task_scheduler/test_task_factory.h" | 32 #include "base/task_scheduler/test_task_factory.h" |
| 33 #include "base/task_scheduler/test_utils.h" |
33 #include "base/test/gtest_util.h" | 34 #include "base/test/gtest_util.h" |
34 #include "base/test/test_simple_task_runner.h" | 35 #include "base/test/test_simple_task_runner.h" |
35 #include "base/test/test_timeouts.h" | 36 #include "base/test/test_timeouts.h" |
36 #include "base/threading/platform_thread.h" | 37 #include "base/threading/platform_thread.h" |
37 #include "base/threading/simple_thread.h" | 38 #include "base/threading/simple_thread.h" |
38 #include "base/threading/thread.h" | 39 #include "base/threading/thread.h" |
39 #include "base/threading/thread_checker_impl.h" | 40 #include "base/threading/thread_checker_impl.h" |
40 #include "base/threading/thread_local_storage.h" | 41 #include "base/threading/thread_local_storage.h" |
41 #include "base/threading/thread_restrictions.h" | 42 #include "base/threading/thread_restrictions.h" |
42 #include "base/time/time.h" | 43 #include "base/time/time.h" |
(...skipping 10 matching lines...) Expand all Loading... |
53 // small timeout is used. This results in many spurious wake ups before a worker | 54 // small timeout is used. This results in many spurious wake ups before a worker |
54 // is allowed to detach. | 55 // is allowed to detach. |
55 constexpr TimeDelta kReclaimTimeForDetachTests = | 56 constexpr TimeDelta kReclaimTimeForDetachTests = |
56 TimeDelta::FromMilliseconds(500); | 57 TimeDelta::FromMilliseconds(500); |
57 constexpr TimeDelta kExtraTimeToWaitForDetach = | 58 constexpr TimeDelta kExtraTimeToWaitForDetach = |
58 TimeDelta::FromSeconds(1); | 59 TimeDelta::FromSeconds(1); |
59 | 60 |
60 using IORestriction = SchedulerWorkerPoolParams::IORestriction; | 61 using IORestriction = SchedulerWorkerPoolParams::IORestriction; |
61 | 62 |
62 class TaskSchedulerWorkerPoolImplTest | 63 class TaskSchedulerWorkerPoolImplTest |
63 : public testing::TestWithParam<ExecutionMode> { | 64 : public testing::TestWithParam<test::ExecutionMode> { |
64 protected: | 65 protected: |
65 TaskSchedulerWorkerPoolImplTest() | 66 TaskSchedulerWorkerPoolImplTest() |
66 : service_thread_("TaskSchedulerServiceThread") {} | 67 : service_thread_("TaskSchedulerServiceThread") {} |
67 | 68 |
68 void SetUp() override { | 69 void SetUp() override { |
69 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); | 70 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); |
70 } | 71 } |
71 | 72 |
72 void TearDown() override { | 73 void TearDown() override { |
73 service_thread_.Stop(); | 74 service_thread_.Stop(); |
(...skipping 29 matching lines...) Expand all Loading... |
103 // In production code, this callback would be implemented by the | 104 // In production code, this callback would be implemented by the |
104 // TaskScheduler which would first determine which PriorityQueue the | 105 // TaskScheduler which would first determine which PriorityQueue the |
105 // sequence must be re-enqueued. | 106 // sequence must be re-enqueued. |
106 const SequenceSortKey sort_key(sequence->GetSortKey()); | 107 const SequenceSortKey sort_key(sequence->GetSortKey()); |
107 worker_pool_->ReEnqueueSequence(std::move(sequence), sort_key); | 108 worker_pool_->ReEnqueueSequence(std::move(sequence), sort_key); |
108 } | 109 } |
109 | 110 |
110 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplTest); | 111 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplTest); |
111 }; | 112 }; |
112 | 113 |
| 114 scoped_refptr<TaskRunner> CreateTaskRunnerWithExecutionMode( |
| 115 SchedulerWorkerPoolImpl* worker_pool, |
| 116 test::ExecutionMode execution_mode) { |
| 117 switch (execution_mode) { |
| 118 case test::ExecutionMode::PARALLEL: |
| 119 return worker_pool->CreateTaskRunnerWithTraits(TaskTraits()); |
| 120 case test::ExecutionMode::SEQUENCED: |
| 121 return worker_pool->CreateSequencedTaskRunnerWithTraits(TaskTraits()); |
| 122 case test::ExecutionMode::SINGLE_THREADED: |
| 123 return worker_pool->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
| 124 } |
| 125 ADD_FAILURE() << "Unknown ExecutionMode"; |
| 126 return nullptr; |
| 127 } |
| 128 |
113 using PostNestedTask = test::TestTaskFactory::PostNestedTask; | 129 using PostNestedTask = test::TestTaskFactory::PostNestedTask; |
114 | 130 |
115 class ThreadPostingTasks : public SimpleThread { | 131 class ThreadPostingTasks : public SimpleThread { |
116 public: | 132 public: |
117 enum class WaitBeforePostTask { | 133 enum class WaitBeforePostTask { |
118 NO_WAIT, | 134 NO_WAIT, |
119 WAIT_FOR_ALL_WORKERS_IDLE, | 135 WAIT_FOR_ALL_WORKERS_IDLE, |
120 }; | 136 }; |
121 | 137 |
122 // Constructs a thread that posts tasks to |worker_pool| through an | 138 // Constructs a thread that posts tasks to |worker_pool| through an |
123 // |execution_mode| task runner. If |wait_before_post_task| is | 139 // |execution_mode| task runner. If |wait_before_post_task| is |
124 // WAIT_FOR_ALL_WORKERS_IDLE, the thread waits until all workers in | 140 // WAIT_FOR_ALL_WORKERS_IDLE, the thread waits until all workers in |
125 // |worker_pool| are idle before posting a new task. If |post_nested_task| is | 141 // |worker_pool| are idle before posting a new task. If |post_nested_task| is |
126 // YES, each task posted by this thread posts another task when it runs. | 142 // YES, each task posted by this thread posts another task when it runs. |
127 ThreadPostingTasks(SchedulerWorkerPoolImpl* worker_pool, | 143 ThreadPostingTasks(SchedulerWorkerPoolImpl* worker_pool, |
128 ExecutionMode execution_mode, | 144 test::ExecutionMode execution_mode, |
129 WaitBeforePostTask wait_before_post_task, | 145 WaitBeforePostTask wait_before_post_task, |
130 PostNestedTask post_nested_task) | 146 PostNestedTask post_nested_task) |
131 : SimpleThread("ThreadPostingTasks"), | 147 : SimpleThread("ThreadPostingTasks"), |
132 worker_pool_(worker_pool), | 148 worker_pool_(worker_pool), |
133 wait_before_post_task_(wait_before_post_task), | 149 wait_before_post_task_(wait_before_post_task), |
134 post_nested_task_(post_nested_task), | 150 post_nested_task_(post_nested_task), |
135 factory_(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), | 151 factory_(CreateTaskRunnerWithExecutionMode(worker_pool, execution_mode), |
136 execution_mode), | |
137 execution_mode) { | 152 execution_mode) { |
138 DCHECK(worker_pool_); | 153 DCHECK(worker_pool_); |
139 } | 154 } |
140 | 155 |
141 const test::TestTaskFactory* factory() const { return &factory_; } | 156 const test::TestTaskFactory* factory() const { return &factory_; } |
142 | 157 |
143 private: | 158 private: |
144 void Run() override { | 159 void Run() override { |
145 EXPECT_FALSE(factory_.task_runner()->RunsTasksOnCurrentThread()); | 160 EXPECT_FALSE(factory_.task_runner()->RunsTasksOnCurrentThread()); |
146 | 161 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 | 253 |
239 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWithOneAvailableWorker) { | 254 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWithOneAvailableWorker) { |
240 // Post blocking tasks to keep all workers busy except one until |event| is | 255 // Post blocking tasks to keep all workers busy except one until |event| is |
241 // signaled. Use different factories so that tasks are added to different | 256 // signaled. Use different factories so that tasks are added to different |
242 // sequences and can run simultaneously when the execution mode is SEQUENCED. | 257 // sequences and can run simultaneously when the execution mode is SEQUENCED. |
243 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 258 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
244 WaitableEvent::InitialState::NOT_SIGNALED); | 259 WaitableEvent::InitialState::NOT_SIGNALED); |
245 std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories; | 260 std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories; |
246 for (size_t i = 0; i < (kNumWorkersInWorkerPool - 1); ++i) { | 261 for (size_t i = 0; i < (kNumWorkersInWorkerPool - 1); ++i) { |
247 blocked_task_factories.push_back(MakeUnique<test::TestTaskFactory>( | 262 blocked_task_factories.push_back(MakeUnique<test::TestTaskFactory>( |
248 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 263 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()), |
249 GetParam())); | 264 GetParam())); |
250 EXPECT_TRUE(blocked_task_factories.back()->PostTask( | 265 EXPECT_TRUE(blocked_task_factories.back()->PostTask( |
251 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); | 266 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); |
252 blocked_task_factories.back()->WaitForAllTasksToRun(); | 267 blocked_task_factories.back()->WaitForAllTasksToRun(); |
253 } | 268 } |
254 | 269 |
255 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact | 270 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact |
256 // that only one worker in |worker_pool_| isn't busy. | 271 // that only one worker in |worker_pool_| isn't busy. |
257 test::TestTaskFactory short_task_factory( | 272 test::TestTaskFactory short_task_factory( |
258 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 273 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()), |
259 GetParam()); | 274 GetParam()); |
260 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) | 275 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) |
261 EXPECT_TRUE(short_task_factory.PostTask(PostNestedTask::NO, Closure())); | 276 EXPECT_TRUE(short_task_factory.PostTask(PostNestedTask::NO, Closure())); |
262 short_task_factory.WaitForAllTasksToRun(); | 277 short_task_factory.WaitForAllTasksToRun(); |
263 | 278 |
264 // Release tasks waiting on |event|. | 279 // Release tasks waiting on |event|. |
265 event.Signal(); | 280 event.Signal(); |
266 | 281 |
267 // Wait until all workers are idle to be sure that no task accesses | 282 // Wait until all workers are idle to be sure that no task accesses |
268 // its TestTaskFactory after it is destroyed. | 283 // its TestTaskFactory after it is destroyed. |
269 worker_pool_->WaitForAllWorkersIdleForTesting(); | 284 worker_pool_->WaitForAllWorkersIdleForTesting(); |
270 } | 285 } |
271 | 286 |
272 TEST_P(TaskSchedulerWorkerPoolImplTest, Saturate) { | 287 TEST_P(TaskSchedulerWorkerPoolImplTest, Saturate) { |
273 // Verify that it is possible to have |kNumWorkersInWorkerPool| | 288 // Verify that it is possible to have |kNumWorkersInWorkerPool| |
274 // tasks/sequences running simultaneously. Use different factories so that the | 289 // tasks/sequences running simultaneously. Use different factories so that the |
275 // blocking tasks are added to different sequences and can run simultaneously | 290 // blocking tasks are added to different sequences and can run simultaneously |
276 // when the execution mode is SEQUENCED. | 291 // when the execution mode is SEQUENCED. |
277 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 292 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
278 WaitableEvent::InitialState::NOT_SIGNALED); | 293 WaitableEvent::InitialState::NOT_SIGNALED); |
279 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; | 294 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; |
280 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { | 295 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
281 factories.push_back(MakeUnique<test::TestTaskFactory>( | 296 factories.push_back(MakeUnique<test::TestTaskFactory>( |
282 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 297 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()), |
283 GetParam())); | 298 GetParam())); |
284 EXPECT_TRUE(factories.back()->PostTask( | 299 EXPECT_TRUE(factories.back()->PostTask( |
285 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); | 300 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); |
286 factories.back()->WaitForAllTasksToRun(); | 301 factories.back()->WaitForAllTasksToRun(); |
287 } | 302 } |
288 | 303 |
289 // Release tasks waiting on |event|. | 304 // Release tasks waiting on |event|. |
290 event.Signal(); | 305 event.Signal(); |
291 | 306 |
292 // Wait until all workers are idle to be sure that no task accesses | 307 // Wait until all workers are idle to be sure that no task accesses |
293 // its TestTaskFactory after it is destroyed. | 308 // its TestTaskFactory after it is destroyed. |
294 worker_pool_->WaitForAllWorkersIdleForTesting(); | 309 worker_pool_->WaitForAllWorkersIdleForTesting(); |
295 } | 310 } |
296 | 311 |
297 // Verify that a Task can't be posted after shutdown. | 312 // Verify that a Task can't be posted after shutdown. |
298 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTaskAfterShutdown) { | 313 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTaskAfterShutdown) { |
299 auto task_runner = | 314 auto task_runner = |
300 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()); | 315 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()); |
301 task_tracker_.Shutdown(); | 316 task_tracker_.Shutdown(); |
302 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRunCallback))); | 317 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRunCallback))); |
303 } | 318 } |
304 | 319 |
305 // Verify that a Task runs shortly after its delay expires. | 320 // Verify that a Task runs shortly after its delay expires. |
306 TEST_P(TaskSchedulerWorkerPoolImplTest, PostDelayedTask) { | 321 TEST_P(TaskSchedulerWorkerPoolImplTest, PostDelayedTask) { |
307 TimeTicks start_time = TimeTicks::Now(); | 322 TimeTicks start_time = TimeTicks::Now(); |
308 | 323 |
309 // Post a task with a short delay. | 324 // Post a task with a short delay. |
310 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 325 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
311 WaitableEvent::InitialState::NOT_SIGNALED); | 326 WaitableEvent::InitialState::NOT_SIGNALED); |
312 EXPECT_TRUE(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()) | 327 EXPECT_TRUE(CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()) |
313 ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal, | 328 ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal, |
314 Unretained(&task_ran)), | 329 Unretained(&task_ran)), |
315 TestTimeouts::tiny_timeout())); | 330 TestTimeouts::tiny_timeout())); |
316 | 331 |
317 // Wait until the task runs. | 332 // Wait until the task runs. |
318 task_ran.Wait(); | 333 task_ran.Wait(); |
319 | 334 |
320 // Expect the task to run after its delay expires, but not more than 250 ms | 335 // Expect the task to run after its delay expires, but not more than 250 ms |
321 // after that. | 336 // after that. |
322 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 337 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
323 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 338 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
324 EXPECT_LT(actual_delay, | 339 EXPECT_LT(actual_delay, |
325 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 340 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
326 } | 341 } |
327 | 342 |
328 // Verify that the RunsTasksOnCurrentThread() method of a SEQUENCED TaskRunner | 343 // Verify that the RunsTasksOnCurrentThread() method of a SEQUENCED TaskRunner |
329 // returns false when called from a task that isn't part of the sequence. | 344 // returns false when called from a task that isn't part of the sequence. |
330 TEST_P(TaskSchedulerWorkerPoolImplTest, SequencedRunsTasksOnCurrentThread) { | 345 TEST_P(TaskSchedulerWorkerPoolImplTest, SequencedRunsTasksOnCurrentThread) { |
331 scoped_refptr<TaskRunner> task_runner( | 346 scoped_refptr<TaskRunner> task_runner( |
332 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam())); | 347 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam())); |
333 scoped_refptr<TaskRunner> sequenced_task_runner( | 348 scoped_refptr<SequencedTaskRunner> sequenced_task_runner( |
334 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), | 349 worker_pool_->CreateSequencedTaskRunnerWithTraits(TaskTraits())); |
335 ExecutionMode::SEQUENCED)); | |
336 | 350 |
337 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 351 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
338 WaitableEvent::InitialState::NOT_SIGNALED); | 352 WaitableEvent::InitialState::NOT_SIGNALED); |
339 task_runner->PostTask( | 353 task_runner->PostTask( |
340 FROM_HERE, | 354 FROM_HERE, |
341 Bind( | 355 Bind( |
342 [](scoped_refptr<TaskRunner> sequenced_task_runner, | 356 [](scoped_refptr<TaskRunner> sequenced_task_runner, |
343 WaitableEvent* task_ran) { | 357 WaitableEvent* task_ran) { |
344 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); | 358 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); |
345 // Tests that use TestTaskFactory already verify that | 359 // Tests that use TestTaskFactory already verify that |
346 // RunsTasksOnCurrentThread() returns true when appropriate. | 360 // RunsTasksOnCurrentThread() returns true when appropriate. |
347 task_ran->Signal(); | 361 task_ran->Signal(); |
348 }, | 362 }, |
349 sequenced_task_runner, Unretained(&task_ran))); | 363 sequenced_task_runner, Unretained(&task_ran))); |
350 task_ran.Wait(); | 364 task_ran.Wait(); |
351 } | 365 } |
352 | 366 |
353 INSTANTIATE_TEST_CASE_P(Parallel, | 367 INSTANTIATE_TEST_CASE_P(Parallel, |
354 TaskSchedulerWorkerPoolImplTest, | 368 TaskSchedulerWorkerPoolImplTest, |
355 ::testing::Values(ExecutionMode::PARALLEL)); | 369 ::testing::Values(test::ExecutionMode::PARALLEL)); |
356 INSTANTIATE_TEST_CASE_P(Sequenced, | 370 INSTANTIATE_TEST_CASE_P(Sequenced, |
357 TaskSchedulerWorkerPoolImplTest, | 371 TaskSchedulerWorkerPoolImplTest, |
358 ::testing::Values(ExecutionMode::SEQUENCED)); | 372 ::testing::Values(test::ExecutionMode::SEQUENCED)); |
359 INSTANTIATE_TEST_CASE_P(SingleThreaded, | 373 INSTANTIATE_TEST_CASE_P( |
360 TaskSchedulerWorkerPoolImplTest, | 374 SingleThreaded, |
361 ::testing::Values(ExecutionMode::SINGLE_THREADED)); | 375 TaskSchedulerWorkerPoolImplTest, |
| 376 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); |
362 | 377 |
363 namespace { | 378 namespace { |
364 | 379 |
365 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { | 380 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
366 ADD_FAILURE() | 381 ADD_FAILURE() |
367 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; | 382 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; |
368 } | 383 } |
369 | 384 |
370 // Verifies that the current thread allows I/O if |io_restriction| is ALLOWED | 385 // Verifies that the current thread allows I/O if |io_restriction| is ALLOWED |
371 // and disallows it otherwise. Signals |event| before returning. | 386 // and disallows it otherwise. Signals |event| before returning. |
(...skipping 28 matching lines...) Expand all Loading... |
400 auto worker_pool = SchedulerWorkerPoolImpl::Create( | 415 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
401 SchedulerWorkerPoolParams("TestWorkerPoolWithParam", | 416 SchedulerWorkerPoolParams("TestWorkerPoolWithParam", |
402 ThreadPriority::NORMAL, GetParam(), 1U, | 417 ThreadPriority::NORMAL, GetParam(), 1U, |
403 TimeDelta::Max()), | 418 TimeDelta::Max()), |
404 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 419 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
405 &delayed_task_manager); | 420 &delayed_task_manager); |
406 ASSERT_TRUE(worker_pool); | 421 ASSERT_TRUE(worker_pool); |
407 | 422 |
408 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 423 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
409 WaitableEvent::InitialState::NOT_SIGNALED); | 424 WaitableEvent::InitialState::NOT_SIGNALED); |
410 worker_pool->CreateTaskRunnerWithTraits(TaskTraits(), ExecutionMode::PARALLEL) | 425 worker_pool->CreateTaskRunnerWithTraits(TaskTraits()) |
411 ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran)); | 426 ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran)); |
412 task_ran.Wait(); | 427 task_ran.Wait(); |
413 | 428 |
414 worker_pool->JoinForTesting(); | 429 worker_pool->JoinForTesting(); |
415 } | 430 } |
416 | 431 |
417 INSTANTIATE_TEST_CASE_P(IOAllowed, | 432 INSTANTIATE_TEST_CASE_P(IOAllowed, |
418 TaskSchedulerWorkerPoolImplIORestrictionTest, | 433 TaskSchedulerWorkerPoolImplIORestrictionTest, |
419 ::testing::Values(IORestriction::ALLOWED)); | 434 ::testing::Values(IORestriction::ALLOWED)); |
420 INSTANTIATE_TEST_CASE_P(IODisallowed, | 435 INSTANTIATE_TEST_CASE_P(IODisallowed, |
(...skipping 24 matching lines...) Expand all Loading... |
445 std::unique_ptr<ThreadCheckerImpl> thread_checker_; | 460 std::unique_ptr<ThreadCheckerImpl> thread_checker_; |
446 | 461 |
447 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolSingleThreadedTest); | 462 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolSingleThreadedTest); |
448 }; | 463 }; |
449 | 464 |
450 } // namespace | 465 } // namespace |
451 | 466 |
452 // Verify that thread resources for a single thread remain. | 467 // Verify that thread resources for a single thread remain. |
453 TEST_F(TaskSchedulerWorkerPoolSingleThreadedTest, SingleThreadTask) { | 468 TEST_F(TaskSchedulerWorkerPoolSingleThreadedTest, SingleThreadTask) { |
454 auto single_thread_task_runner = | 469 auto single_thread_task_runner = |
455 worker_pool_->CreateTaskRunnerWithTraits( | 470 worker_pool_->CreateSingleThreadTaskRunnerWithTraits( |
456 TaskTraits(). | 471 TaskTraits().WithShutdownBehavior( |
457 WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN), | 472 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
458 ExecutionMode::SINGLE_THREADED); | |
459 single_thread_task_runner->PostTask( | 473 single_thread_task_runner->PostTask( |
460 FROM_HERE, | 474 FROM_HERE, |
461 Bind(&TaskSchedulerWorkerPoolSingleThreadedTest::InitializeThreadChecker, | 475 Bind(&TaskSchedulerWorkerPoolSingleThreadedTest::InitializeThreadChecker, |
462 Unretained(this))); | 476 Unretained(this))); |
463 WaitableEvent task_waiter(WaitableEvent::ResetPolicy::AUTOMATIC, | 477 WaitableEvent task_waiter(WaitableEvent::ResetPolicy::AUTOMATIC, |
464 WaitableEvent::InitialState::NOT_SIGNALED); | 478 WaitableEvent::InitialState::NOT_SIGNALED); |
465 single_thread_task_runner->PostTask( | 479 single_thread_task_runner->PostTask( |
466 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_waiter))); | 480 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_waiter))); |
467 task_waiter.Wait(); | 481 task_waiter.Wait(); |
468 worker_pool_->WaitForAllWorkersIdleForTesting(); | 482 worker_pool_->WaitForAllWorkersIdleForTesting(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolCheckTlsReuse); | 534 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolCheckTlsReuse); |
521 }; | 535 }; |
522 | 536 |
523 } // namespace | 537 } // namespace |
524 | 538 |
525 // Checks that at least one thread has detached by checking the TLS. | 539 // Checks that at least one thread has detached by checking the TLS. |
526 TEST_F(TaskSchedulerWorkerPoolCheckTlsReuse, CheckDetachedThreads) { | 540 TEST_F(TaskSchedulerWorkerPoolCheckTlsReuse, CheckDetachedThreads) { |
527 // Saturate the threads and mark each thread with a magic TLS value. | 541 // Saturate the threads and mark each thread with a magic TLS value. |
528 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; | 542 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; |
529 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { | 543 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
530 factories.push_back(WrapUnique(new test::TestTaskFactory( | 544 factories.push_back(MakeUnique<test::TestTaskFactory>( |
531 worker_pool_->CreateTaskRunnerWithTraits( | 545 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits()), |
532 TaskTraits(), ExecutionMode::PARALLEL), | 546 test::ExecutionMode::PARALLEL)); |
533 ExecutionMode::PARALLEL))); | |
534 ASSERT_TRUE(factories.back()->PostTask( | 547 ASSERT_TRUE(factories.back()->PostTask( |
535 PostNestedTask::NO, | 548 PostNestedTask::NO, |
536 Bind(&TaskSchedulerWorkerPoolCheckTlsReuse::SetTlsValueAndWait, | 549 Bind(&TaskSchedulerWorkerPoolCheckTlsReuse::SetTlsValueAndWait, |
537 Unretained(this)))); | 550 Unretained(this)))); |
538 factories.back()->WaitForAllTasksToRun(); | 551 factories.back()->WaitForAllTasksToRun(); |
539 } | 552 } |
540 | 553 |
541 // Release tasks waiting on |waiter_|. | 554 // Release tasks waiting on |waiter_|. |
542 waiter_.Signal(); | 555 waiter_.Signal(); |
543 worker_pool_->WaitForAllWorkersIdleForTesting(); | 556 worker_pool_->WaitForAllWorkersIdleForTesting(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 | 606 |
594 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolHistogramTest); | 607 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolHistogramTest); |
595 }; | 608 }; |
596 | 609 |
597 } // namespace | 610 } // namespace |
598 | 611 |
599 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaits) { | 612 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaits) { |
600 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 613 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
601 WaitableEvent::InitialState::NOT_SIGNALED); | 614 WaitableEvent::InitialState::NOT_SIGNALED); |
602 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); | 615 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); |
603 auto task_runner = worker_pool_->CreateTaskRunnerWithTraits( | 616 auto task_runner = |
604 TaskTraits(), ExecutionMode::SEQUENCED); | 617 worker_pool_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); |
605 | 618 |
606 // Post a task. | 619 // Post a task. |
607 task_runner->PostTask(FROM_HERE, | 620 task_runner->PostTask(FROM_HERE, |
608 Bind(&WaitableEvent::Wait, Unretained(&event))); | 621 Bind(&WaitableEvent::Wait, Unretained(&event))); |
609 | 622 |
610 // Post 2 more tasks while the first task hasn't completed its execution. It | 623 // Post 2 more tasks while the first task hasn't completed its execution. It |
611 // is guaranteed that these tasks will run immediately after the first task, | 624 // is guaranteed that these tasks will run immediately after the first task, |
612 // without allowing the worker to sleep. | 625 // without allowing the worker to sleep. |
613 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); | 626 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); |
614 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); | 627 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); |
(...skipping 22 matching lines...) Expand all Loading... |
637 signal_event->Signal(); | 650 signal_event->Signal(); |
638 wait_event->Wait(); | 651 wait_event->Wait(); |
639 } | 652 } |
640 | 653 |
641 } // namespace | 654 } // namespace |
642 | 655 |
643 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaitsWithDetach) { | 656 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaitsWithDetach) { |
644 WaitableEvent tasks_can_exit_event(WaitableEvent::ResetPolicy::MANUAL, | 657 WaitableEvent tasks_can_exit_event(WaitableEvent::ResetPolicy::MANUAL, |
645 WaitableEvent::InitialState::NOT_SIGNALED); | 658 WaitableEvent::InitialState::NOT_SIGNALED); |
646 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | 659 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); |
647 auto task_runner = worker_pool_->CreateTaskRunnerWithTraits( | 660 auto task_runner = worker_pool_->CreateTaskRunnerWithTraits(TaskTraits()); |
648 TaskTraits(), ExecutionMode::PARALLEL); | |
649 | 661 |
650 // Post tasks to saturate the pool. | 662 // Post tasks to saturate the pool. |
651 std::vector<std::unique_ptr<WaitableEvent>> task_started_events; | 663 std::vector<std::unique_ptr<WaitableEvent>> task_started_events; |
652 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { | 664 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
653 task_started_events.push_back( | 665 task_started_events.push_back( |
654 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::MANUAL, | 666 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::MANUAL, |
655 WaitableEvent::InitialState::NOT_SIGNALED)); | 667 WaitableEvent::InitialState::NOT_SIGNALED)); |
656 task_runner->PostTask( | 668 task_runner->PostTask( |
657 FROM_HERE, | 669 FROM_HERE, |
658 Bind(&SignalAndWaitEvent, Unretained(task_started_events.back().get()), | 670 Bind(&SignalAndWaitEvent, Unretained(task_started_events.back().get()), |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { | 726 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { |
715 EXPECT_NE(thread_id, PlatformThread::CurrentId()); | 727 EXPECT_NE(thread_id, PlatformThread::CurrentId()); |
716 } | 728 } |
717 | 729 |
718 } // namespace | 730 } // namespace |
719 | 731 |
720 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBeforeDetach) { | 732 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBeforeDetach) { |
721 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | 733 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); |
722 | 734 |
723 // This test assumes that the TaskRunners aren't assigned to the same worker. | 735 // This test assumes that the TaskRunners aren't assigned to the same worker. |
724 auto task_runner = worker_pool_->CreateTaskRunnerWithTraits( | 736 auto task_runner = |
725 TaskTraits(), ExecutionMode::SINGLE_THREADED); | 737 worker_pool_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
726 auto other_task_runner = worker_pool_->CreateTaskRunnerWithTraits( | 738 auto other_task_runner = |
727 TaskTraits(), ExecutionMode::SINGLE_THREADED); | 739 worker_pool_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
728 | 740 |
729 // Post 3 tasks and wait until they run. | 741 // Post 3 tasks and wait until they run. |
730 PlatformThreadId thread_id; | 742 PlatformThreadId thread_id; |
731 task_runner->PostTask(FROM_HERE, | 743 task_runner->PostTask(FROM_HERE, |
732 Bind(&CaptureThreadId, Unretained(&thread_id))); | 744 Bind(&CaptureThreadId, Unretained(&thread_id))); |
733 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); | 745 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); |
734 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); | 746 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); |
735 worker_pool_->WaitForAllWorkersIdleForTesting(); | 747 worker_pool_->WaitForAllWorkersIdleForTesting(); |
736 | 748 |
737 // To allow the SchedulerWorker associated with |task_runner| to detach: | 749 // To allow the SchedulerWorker associated with |task_runner| to detach: |
(...skipping 10 matching lines...) Expand all Loading... |
748 | 760 |
749 // Verify that counts were recorded to the histogram as expected. | 761 // Verify that counts were recorded to the histogram as expected. |
750 const auto* histogram = worker_pool_->num_tasks_before_detach_histogram(); | 762 const auto* histogram = worker_pool_->num_tasks_before_detach_histogram(); |
751 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0)); | 763 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0)); |
752 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); | 764 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); |
753 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | 765 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); |
754 } | 766 } |
755 | 767 |
756 } // namespace internal | 768 } // namespace internal |
757 } // namespace base | 769 } // namespace base |
OLD | NEW |