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 |