Chromium Code Reviews| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 scoped_refptr<TaskRunner> CreateTaskRunnerWithExecutionMode( | 114 scoped_refptr<TaskRunner> CreateTaskRunnerWithExecutionMode( |
| 115 SchedulerWorkerPoolImpl* worker_pool, | 115 SchedulerWorkerPoolImpl* worker_pool, |
| 116 test::ExecutionMode execution_mode) { | 116 test::ExecutionMode execution_mode) { |
| 117 // Allow tasks posted to the returned TaskRunner to wait on a WaitableEvent. | 117 // Allow tasks posted to the returned TaskRunner to wait on a WaitableEvent. |
| 118 const TaskTraits traits = TaskTraits().WithBaseSyncPrimitives(); | 118 const TaskTraits traits = TaskTraits().WithBaseSyncPrimitives(); |
| 119 switch (execution_mode) { | 119 switch (execution_mode) { |
| 120 case test::ExecutionMode::PARALLEL: | 120 case test::ExecutionMode::PARALLEL: |
| 121 return worker_pool->CreateTaskRunnerWithTraits(traits); | 121 return worker_pool->CreateTaskRunnerWithTraits(traits); |
| 122 case test::ExecutionMode::SEQUENCED: | 122 case test::ExecutionMode::SEQUENCED: |
| 123 return worker_pool->CreateSequencedTaskRunnerWithTraits(traits); | 123 return worker_pool->CreateSequencedTaskRunnerWithTraits(traits); |
| 124 case test::ExecutionMode::SINGLE_THREADED: | 124 default: |
|
fdoray
2017/03/14 18:35:47
If you have no default and you forget to handle an
robliao
2017/03/14 22:58:28
Indeed. I would agree if the goal here is to be ex
gab
2017/03/16 15:34:45
In that case we can keep default but we should sti
robliao
2017/03/16 22:49:03
That suggests we should be using NOTREACHED() at t
gab
2017/03/20 16:40:58
Ah, had missed this was in a unittest. ADD_FAILURE
| |
| 125 return worker_pool->CreateSingleThreadTaskRunnerWithTraits(traits); | 125 // Fall through. |
| 126 break; | |
| 126 } | 127 } |
| 127 ADD_FAILURE() << "Unknown ExecutionMode"; | 128 ADD_FAILURE() << "Unexpected ExecutionMode"; |
| 128 return nullptr; | 129 return nullptr; |
| 129 } | 130 } |
| 130 | 131 |
| 131 using PostNestedTask = test::TestTaskFactory::PostNestedTask; | 132 using PostNestedTask = test::TestTaskFactory::PostNestedTask; |
| 132 | 133 |
| 133 class ThreadPostingTasks : public SimpleThread { | 134 class ThreadPostingTasks : public SimpleThread { |
| 134 public: | 135 public: |
| 135 enum class WaitBeforePostTask { | 136 enum class WaitBeforePostTask { |
| 136 NO_WAIT, | 137 NO_WAIT, |
| 137 WAIT_FOR_ALL_WORKERS_IDLE, | 138 WAIT_FOR_ALL_WORKERS_IDLE, |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 sequenced_task_runner, Unretained(&task_ran))); | 367 sequenced_task_runner, Unretained(&task_ran))); |
| 367 task_ran.Wait(); | 368 task_ran.Wait(); |
| 368 } | 369 } |
| 369 | 370 |
| 370 INSTANTIATE_TEST_CASE_P(Parallel, | 371 INSTANTIATE_TEST_CASE_P(Parallel, |
| 371 TaskSchedulerWorkerPoolImplTest, | 372 TaskSchedulerWorkerPoolImplTest, |
| 372 ::testing::Values(test::ExecutionMode::PARALLEL)); | 373 ::testing::Values(test::ExecutionMode::PARALLEL)); |
| 373 INSTANTIATE_TEST_CASE_P(Sequenced, | 374 INSTANTIATE_TEST_CASE_P(Sequenced, |
| 374 TaskSchedulerWorkerPoolImplTest, | 375 TaskSchedulerWorkerPoolImplTest, |
| 375 ::testing::Values(test::ExecutionMode::SEQUENCED)); | 376 ::testing::Values(test::ExecutionMode::SEQUENCED)); |
| 376 INSTANTIATE_TEST_CASE_P( | |
| 377 SingleThreaded, | |
| 378 TaskSchedulerWorkerPoolImplTest, | |
| 379 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); | |
| 380 | 377 |
| 381 namespace { | 378 namespace { |
| 382 | 379 |
| 383 // Same as TaskSchedulerWorkerPoolImplTest but its SchedulerWorkerPoolImpl | |
| 384 // instance uses |max_threads == 1|. | |
| 385 class TaskSchedulerWorkerPoolImplSingleWorkerTest | |
| 386 : public TaskSchedulerWorkerPoolImplTest { | |
| 387 public: | |
| 388 TaskSchedulerWorkerPoolImplSingleWorkerTest() = default; | |
| 389 | |
| 390 protected: | |
| 391 void SetUp() override { | |
| 392 InitializeWorkerPool(TimeDelta::Max(), 1); | |
| 393 } | |
| 394 | |
| 395 private: | |
| 396 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplSingleWorkerTest); | |
| 397 }; | |
| 398 | |
| 399 } // namespace | |
| 400 | |
| 401 // Verify that the RunsTasksOnCurrentThread() method of a | |
| 402 // SchedulerSingleThreadTaskRunner returns false when called from a task that | |
| 403 // isn't part of its sequence even though it's running on that | |
| 404 // SchedulerSingleThreadTaskRunner's assigned worker. Note: Tests that use | |
| 405 // TestTaskFactory already verify that RunsTasksOnCurrentThread() returns true | |
| 406 // when appropriate so this method complements it to get full coverage of that | |
| 407 // method. | |
| 408 TEST_P(TaskSchedulerWorkerPoolImplSingleWorkerTest, | |
| 409 SingleThreadRunsTasksOnCurrentThread) { | |
| 410 scoped_refptr<TaskRunner> task_runner( | |
| 411 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam())); | |
| 412 scoped_refptr<SingleThreadTaskRunner> single_thread_task_runner( | |
| 413 worker_pool_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits())); | |
| 414 | |
| 415 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | |
| 416 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 417 task_runner->PostTask( | |
| 418 FROM_HERE, | |
| 419 Bind( | |
| 420 [](scoped_refptr<TaskRunner> single_thread_task_runner, | |
| 421 WaitableEvent* task_ran) { | |
| 422 EXPECT_FALSE(single_thread_task_runner->RunsTasksOnCurrentThread()); | |
| 423 task_ran->Signal(); | |
| 424 }, | |
| 425 single_thread_task_runner, Unretained(&task_ran))); | |
| 426 task_ran.Wait(); | |
| 427 } | |
| 428 | |
| 429 INSTANTIATE_TEST_CASE_P(Parallel, | |
| 430 TaskSchedulerWorkerPoolImplSingleWorkerTest, | |
| 431 ::testing::Values(test::ExecutionMode::PARALLEL)); | |
| 432 INSTANTIATE_TEST_CASE_P(Sequenced, | |
| 433 TaskSchedulerWorkerPoolImplSingleWorkerTest, | |
| 434 ::testing::Values(test::ExecutionMode::SEQUENCED)); | |
| 435 INSTANTIATE_TEST_CASE_P( | |
| 436 SingleThreaded, | |
| 437 TaskSchedulerWorkerPoolImplSingleWorkerTest, | |
| 438 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); | |
| 439 | |
| 440 namespace { | |
| 441 | |
| 442 class TaskSchedulerWorkerPoolSingleThreadedTest | |
| 443 : public TaskSchedulerWorkerPoolImplTest { | |
| 444 public: | |
| 445 void InitializeThreadChecker() { | |
| 446 thread_checker_.reset(new ThreadCheckerImpl()); | |
| 447 } | |
| 448 | |
| 449 void CheckValidThread() { | |
| 450 EXPECT_TRUE(thread_checker_->CalledOnValidThread()); | |
| 451 } | |
| 452 | |
| 453 protected: | |
| 454 void SetUp() override { | |
| 455 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | |
| 456 } | |
| 457 | |
| 458 TaskSchedulerWorkerPoolSingleThreadedTest() = default; | |
| 459 | |
| 460 private: | |
| 461 std::unique_ptr<ThreadCheckerImpl> thread_checker_; | |
| 462 | |
| 463 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolSingleThreadedTest); | |
| 464 }; | |
| 465 | |
| 466 } // namespace | |
| 467 | |
| 468 // Verify that thread resources for a single thread remain. | |
| 469 TEST_F(TaskSchedulerWorkerPoolSingleThreadedTest, SingleThreadTask) { | |
| 470 auto single_thread_task_runner = | |
| 471 worker_pool_->CreateSingleThreadTaskRunnerWithTraits( | |
| 472 TaskTraits().WithShutdownBehavior( | |
| 473 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
| 474 single_thread_task_runner->PostTask( | |
| 475 FROM_HERE, | |
| 476 Bind(&TaskSchedulerWorkerPoolSingleThreadedTest::InitializeThreadChecker, | |
| 477 Unretained(this))); | |
| 478 WaitableEvent task_waiter(WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 479 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 480 single_thread_task_runner->PostTask( | |
| 481 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_waiter))); | |
| 482 task_waiter.Wait(); | |
| 483 worker_pool_->WaitForAllWorkersIdleForTesting(); | |
| 484 | |
| 485 // Give the worker pool a chance to reclaim its threads. | |
| 486 PlatformThread::Sleep(kReclaimTimeForDetachTests + kExtraTimeToWaitForDetach); | |
| 487 | |
| 488 worker_pool_->DisallowWorkerDetachmentForTesting(); | |
| 489 | |
| 490 single_thread_task_runner->PostTask( | |
| 491 FROM_HERE, | |
| 492 Bind(&TaskSchedulerWorkerPoolSingleThreadedTest::CheckValidThread, | |
| 493 Unretained(this))); | |
| 494 single_thread_task_runner->PostTask( | |
| 495 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_waiter))); | |
| 496 task_waiter.Wait(); | |
| 497 } | |
| 498 | |
| 499 namespace { | |
| 500 | |
| 501 constexpr size_t kMagicTlsValue = 42; | 380 constexpr size_t kMagicTlsValue = 42; |
| 502 | 381 |
| 503 class TaskSchedulerWorkerPoolCheckTlsReuse | 382 class TaskSchedulerWorkerPoolCheckTlsReuse |
| 504 : public TaskSchedulerWorkerPoolImplTest { | 383 : public TaskSchedulerWorkerPoolImplTest { |
| 505 public: | 384 public: |
| 506 void SetTlsValueAndWait() { | 385 void SetTlsValueAndWait() { |
| 507 slot_.Set(reinterpret_cast<void*>(kMagicTlsValue)); | 386 slot_.Set(reinterpret_cast<void*>(kMagicTlsValue)); |
| 508 waiter_.Wait(); | 387 waiter_.Wait(); |
| 509 } | 388 } |
| 510 | 389 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 851 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), | 730 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), |
| 852 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 731 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 853 &delayed_task_manager); | 732 &delayed_task_manager); |
| 854 ASSERT_TRUE(worker_pool); | 733 ASSERT_TRUE(worker_pool); |
| 855 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); | 734 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); |
| 856 worker_pool->JoinForTesting(); | 735 worker_pool->JoinForTesting(); |
| 857 } | 736 } |
| 858 | 737 |
| 859 } // namespace internal | 738 } // namespace internal |
| 860 } // namespace base | 739 } // namespace base |
| OLD | NEW |