Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: base/threading/sequenced_worker_pool.cc

Issue 2285633003: Test SequencedWorkerPool with redirection to the TaskScheduler. (Closed)
Patch Set: CR gab/danakj #18-19 Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/threading/sequenced_worker_pool.h" 5 #include "base/threading/sequenced_worker_pool.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <list> 9 #include <list>
10 #include <map> 10 #include <map>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #endif 47 #endif
48 48
49 #if !defined(OS_NACL) 49 #if !defined(OS_NACL)
50 #include "base/metrics/histogram_macros.h" 50 #include "base/metrics/histogram_macros.h"
51 #endif 51 #endif
52 52
53 namespace base { 53 namespace base {
54 54
55 namespace { 55 namespace {
56 56
57 // An enum representing the state of all pools. Any given process should only 57 // An enum representing the state of all pools. Any given non-test process
58 // ever transition from NONE_ACTIVE to the active states, transitions between 58 // should only ever transition from NONE_ACTIVE to one of the active states.
59 // actives states are unexpected. The REDIRECTED_TO_TASK_SCHEDULER transition 59 // Transitions between actives states are unexpected. The
60 // occurs when RedirectSequencedWorkerPoolsToTaskSchedulerForProcess() is called 60 // REDIRECTED_TO_TASK_SCHEDULER transition occurs when
61 // and the WORKER_CREATED transition occurs when a Worker needs to be created 61 // RedirectToTaskSchedulerForProcess() is called. The WORKER_CREATED transition
62 // because the first task was posted and the state is still NONE_ACTIVE. 62 // occurs when a Worker needs to be created because the first task was posted
63 // and the state is still NONE_ACTIVE. In a test process, a transition to
64 // NONE_ACTIVE occurs when ResetRedirectToTaskSchedulerForProcessForTesting() is
65 // called.
66 //
63 // |g_all_pools_state| uses relaxed atomic operations to ensure no data race 67 // |g_all_pools_state| uses relaxed atomic operations to ensure no data race
64 // between reads/writes, strict memory ordering isn't required per no other 68 // between reads/writes, strict memory ordering isn't required per no other
65 // state being inferred from its value. Explicit synchronization (e.g. locks or 69 // state being inferred from its value. Explicit synchronization (e.g. locks or
66 // events) would be overkill (it's fine for other threads to still see 70 // events) would be overkill (it's fine for other threads to still see
67 // NONE_ACTIVE after the first Worker was created -- this is not possible for 71 // NONE_ACTIVE after the first Worker was created -- this is not possible for
68 // REDIRECTED_TO_TASK_SCHEDULER per its API requesting to be invoked while no 72 // REDIRECTED_TO_TASK_SCHEDULER per its API requesting to be invoked while no
69 // other threads are active). 73 // other threads are active).
74 //
70 // TODO(gab): Remove this if http://crbug.com/622400 fails (SequencedWorkerPool 75 // TODO(gab): Remove this if http://crbug.com/622400 fails (SequencedWorkerPool
71 // will be phased out completely otherwise). 76 // will be phased out completely otherwise).
72 enum AllPoolsState : subtle::Atomic32 { 77 enum AllPoolsState : subtle::Atomic32 {
73 NONE_ACTIVE, 78 NONE_ACTIVE,
74 WORKER_CREATED, 79 WORKER_CREATED,
75 REDIRECTED_TO_TASK_SCHEDULER, 80 REDIRECTED_TO_TASK_SCHEDULER,
76 }; 81 };
77 subtle::Atomic32 g_all_pools_state = AllPoolsState::NONE_ACTIVE; 82 subtle::Atomic32 g_all_pools_state = AllPoolsState::NONE_ACTIVE;
78 83
79 struct SequencedTask : public TrackingInfo { 84 struct SequencedTask : public TrackingInfo {
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 } else { 900 } else {
896 ThreadMap::const_iterator found = 901 ThreadMap::const_iterator found =
897 threads_.find(PlatformThread::CurrentId()); 902 threads_.find(PlatformThread::CurrentId());
898 return found != threads_.end() && found->second->is_processing_task() && 903 return found != threads_.end() && found->second->is_processing_task() &&
899 sequence_token.Equals(found->second->task_sequence_token()); 904 sequence_token.Equals(found->second->task_sequence_token());
900 } 905 }
901 } 906 }
902 907
903 // See https://code.google.com/p/chromium/issues/detail?id=168415 908 // See https://code.google.com/p/chromium/issues/detail?id=168415
904 void SequencedWorkerPool::Inner::CleanupForTesting() { 909 void SequencedWorkerPool::Inner::CleanupForTesting() {
910 DCHECK_NE(subtle::NoBarrier_Load(&g_all_pools_state),
911 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER);
905 DCHECK(!RunsTasksOnCurrentThread()); 912 DCHECK(!RunsTasksOnCurrentThread());
906 base::ThreadRestrictions::ScopedAllowWait allow_wait; 913 base::ThreadRestrictions::ScopedAllowWait allow_wait;
907 AutoLock lock(lock_); 914 AutoLock lock(lock_);
908 CHECK_EQ(CLEANUP_DONE, cleanup_state_); 915 CHECK_EQ(CLEANUP_DONE, cleanup_state_);
909 if (shutdown_called_) 916 if (shutdown_called_)
910 return; 917 return;
911 if (pending_tasks_.empty() && waiting_thread_count_ == threads_.size()) 918 if (pending_tasks_.empty() && waiting_thread_count_ == threads_.size())
912 return; 919 return;
913 cleanup_state_ = CLEANUP_REQUESTED; 920 cleanup_state_ = CLEANUP_REQUESTED;
914 cleanup_idlers_ = 0; 921 cleanup_idlers_ = 0;
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 scoped_refptr<SequencedWorkerPool> 1449 scoped_refptr<SequencedWorkerPool>
1443 SequencedWorkerPool::GetWorkerPoolForCurrentThread() { 1450 SequencedWorkerPool::GetWorkerPoolForCurrentThread() {
1444 Worker* worker = Worker::GetForCurrentThread(); 1451 Worker* worker = Worker::GetForCurrentThread();
1445 if (!worker) 1452 if (!worker)
1446 return nullptr; 1453 return nullptr;
1447 1454
1448 return worker->worker_pool(); 1455 return worker->worker_pool();
1449 } 1456 }
1450 1457
1451 // static 1458 // static
1452 void SequencedWorkerPool:: 1459 void SequencedWorkerPool::RedirectToTaskSchedulerForProcess() {
1453 RedirectSequencedWorkerPoolsToTaskSchedulerForProcess() {
1454 DCHECK(TaskScheduler::GetInstance()); 1460 DCHECK(TaskScheduler::GetInstance());
1455 // Hitting this DCHECK indicates that a task was posted to a 1461 // Hitting this DCHECK indicates that a task was posted to a
1456 // SequencedWorkerPool before the TaskScheduler was initialized and 1462 // SequencedWorkerPool before the TaskScheduler was initialized and
1457 // redirected, posting task to SequencedWorkerPools needs to at least be 1463 // redirected, posting task to SequencedWorkerPools needs to at least be
1458 // delayed until after that point. 1464 // delayed until after that point.
1459 DCHECK_EQ(AllPoolsState::NONE_ACTIVE, 1465 DCHECK_EQ(AllPoolsState::NONE_ACTIVE,
1460 subtle::NoBarrier_Load(&g_all_pools_state)); 1466 subtle::NoBarrier_Load(&g_all_pools_state));
1461 subtle::NoBarrier_Store(&g_all_pools_state, 1467 subtle::NoBarrier_Store(&g_all_pools_state,
1462 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER); 1468 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER);
1463 } 1469 }
1464 1470
1471 // static
1472 void SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting() {
1473 // This can be called when the current state is REDIRECTED_TO_TASK_SCHEDULER
1474 // to stop redirecting tasks. It can also be called when the current state is
1475 // WORKER_CREATED to allow RedirectToTaskSchedulerForProcess() to be called
1476 // (RedirectToTaskSchedulerForProcess() cannot be called after a worker has
1477 // been created if this isn't called).
1478 subtle::NoBarrier_Store(&g_all_pools_state, AllPoolsState::NONE_ACTIVE);
1479 }
1480
1465 SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, 1481 SequencedWorkerPool::SequencedWorkerPool(size_t max_threads,
1466 const std::string& thread_name_prefix, 1482 const std::string& thread_name_prefix,
1467 base::TaskPriority task_priority) 1483 base::TaskPriority task_priority)
1468 : constructor_task_runner_(ThreadTaskRunnerHandle::Get()), 1484 : constructor_task_runner_(ThreadTaskRunnerHandle::Get()),
1469 inner_(new Inner(this, 1485 inner_(new Inner(this,
1470 max_threads, 1486 max_threads,
1471 thread_name_prefix, 1487 thread_name_prefix,
1472 task_priority, 1488 task_priority,
1473 NULL)) {} 1489 NULL)) {}
1474 1490
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 bool SequencedWorkerPool::IsShutdownInProgress() { 1627 bool SequencedWorkerPool::IsShutdownInProgress() {
1612 return inner_->IsShutdownInProgress(); 1628 return inner_->IsShutdownInProgress();
1613 } 1629 }
1614 1630
1615 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( 1631 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread(
1616 SequenceToken sequence_token) const { 1632 SequenceToken sequence_token) const {
1617 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); 1633 return inner_->IsRunningSequenceOnCurrentThread(sequence_token);
1618 } 1634 }
1619 1635
1620 } // namespace base 1636 } // namespace base
OLDNEW
« no previous file with comments | « base/threading/sequenced_worker_pool.h ('k') | base/threading/sequenced_worker_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698