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

Side by Side Diff: base/task_scheduler/scheduler_worker_thread.cc

Issue 1895513002: TaskScheduler [12] Support SINGLE_THREADED in SchedulerThreadPool DO NOT SUBMIT (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@10_superstack
Patch Set: rebase Created 4 years, 8 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
« no previous file with comments | « base/task_scheduler/scheduler_worker_thread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_thread.h" 5 #include "base/task_scheduler/scheduler_worker_thread.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 13 matching lines...) Expand all
24 // SchedulerWorkerThread that owns the current thread, if any. 24 // SchedulerWorkerThread that owns the current thread, if any.
25 LazyInstance<ThreadLocalPointer<const SchedulerTaskExecutor>>::Leaky 25 LazyInstance<ThreadLocalPointer<const SchedulerTaskExecutor>>::Leaky
26 tls_current_worker_thread = LAZY_INSTANCE_INITIALIZER; 26 tls_current_worker_thread = LAZY_INSTANCE_INITIALIZER;
27 27
28 // A task runner that runs tasks on a single SchedulerWorkerThread. 28 // A task runner that runs tasks on a single SchedulerWorkerThread.
29 class SchedulerSingleThreadTaskRunner : public SingleThreadTaskRunner { 29 class SchedulerSingleThreadTaskRunner : public SingleThreadTaskRunner {
30 public: 30 public:
31 // Constructs a SchedulerSingleThreadTaskRunner which can be used to post 31 // Constructs a SchedulerSingleThreadTaskRunner which can be used to post
32 // tasks so long as |executor| is alive. 32 // tasks so long as |executor| is alive.
33 // TODO(robliao): Find a concrete way to manage |executor|'s memory. 33 // TODO(robliao): Find a concrete way to manage |executor|'s memory.
34 SchedulerSingleThreadTaskRunner(const TaskTraits& traits, 34 SchedulerSingleThreadTaskRunner(
35 SchedulerTaskExecutor* executor, 35 const TaskTraits& traits,
36 TaskTracker* task_tracker, 36 SchedulerTaskExecutor* executor,
37 DelayedTaskManager* delayed_task_manager) 37 TaskTracker* task_tracker,
38 DelayedTaskManager* delayed_task_manager,
39 base::subtle::Atomic32* num_single_thread_task_runners)
38 : traits_(traits), 40 : traits_(traits),
39 executor_(executor), 41 executor_(executor),
40 task_tracker_(task_tracker), 42 task_tracker_(task_tracker),
41 delayed_task_manager_(delayed_task_manager) {} 43 delayed_task_manager_(delayed_task_manager),
44 num_single_thread_task_runners_(num_single_thread_task_runners) {
45 DCHECK(executor_);
46 DCHECK(task_tracker_);
47 DCHECK(delayed_task_manager_);
48 DCHECK(num_single_thread_task_runners_);
49
50 base::subtle::NoBarrier_AtomicIncrement(num_single_thread_task_runners_, 1);
51 }
42 52
43 // SingleThreadTaskRunner: 53 // SingleThreadTaskRunner:
44 bool PostDelayedTask(const tracked_objects::Location& from_here, 54 bool PostDelayedTask(const tracked_objects::Location& from_here,
45 const Closure& closure, 55 const Closure& closure,
46 TimeDelta delay) override { 56 TimeDelta delay) override {
47 // Post the task as part of |sequence_|. 57 // Post the task as part of |sequence_|.
48 return PostTaskToExecutor( 58 return PostTaskToExecutor(
49 WrapUnique( 59 WrapUnique(
50 new Task(from_here, closure, traits_, 60 new Task(from_here, closure, traits_,
51 delay.is_zero() ? TimeTicks() : TimeTicks::Now() + delay)), 61 delay.is_zero() ? TimeTicks() : TimeTicks::Now() + delay)),
52 sequence_, executor_, task_tracker_, delayed_task_manager_); 62 sequence_, executor_, task_tracker_, delayed_task_manager_);
53 } 63 }
54 64
55 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, 65 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
56 const Closure& closure, 66 const Closure& closure,
57 base::TimeDelta delay) override { 67 base::TimeDelta delay) override {
58 // Tasks are never nested within the task scheduler. 68 // Tasks are never nested within the task scheduler.
59 return PostDelayedTask(from_here, closure, delay); 69 return PostDelayedTask(from_here, closure, delay);
60 } 70 }
61 71
62 bool RunsTasksOnCurrentThread() const override { 72 bool RunsTasksOnCurrentThread() const override {
63 return tls_current_worker_thread.Get().Get() == executor_; 73 return tls_current_worker_thread.Get().Get() == executor_;
64 } 74 }
65 75
66 private: 76 private:
67 ~SchedulerSingleThreadTaskRunner() override = default; 77 ~SchedulerSingleThreadTaskRunner() override {
78 base::subtle::NoBarrier_AtomicIncrement(num_single_thread_task_runners_,
79 -1);
80 }
68 81
69 // Sequence for all Tasks posted through this TaskRunner. 82 // Sequence for all Tasks posted through this TaskRunner.
70 const scoped_refptr<Sequence> sequence_ = new Sequence; 83 const scoped_refptr<Sequence> sequence_ = new Sequence;
71 84
72 const TaskTraits traits_; 85 const TaskTraits traits_;
73 SchedulerTaskExecutor* const executor_; 86 SchedulerTaskExecutor* const executor_;
74 TaskTracker* const task_tracker_; 87 TaskTracker* const task_tracker_;
75 DelayedTaskManager* const delayed_task_manager_; 88 DelayedTaskManager* const delayed_task_manager_;
76 89
90 // Number of single-thread TaskRunners associated with |executor_|.
91 // Incremented by the constructor and decremented by the destructor.
92 base::subtle::Atomic32* const num_single_thread_task_runners_;
93
77 DISALLOW_COPY_AND_ASSIGN(SchedulerSingleThreadTaskRunner); 94 DISALLOW_COPY_AND_ASSIGN(SchedulerSingleThreadTaskRunner);
78 }; 95 };
79 96
80 } // namespace 97 } // namespace
81 98
82 std::unique_ptr<SchedulerWorkerThread> 99 std::unique_ptr<SchedulerWorkerThread>
83 SchedulerWorkerThread::CreateSchedulerWorkerThread( 100 SchedulerWorkerThread::CreateSchedulerWorkerThread(
84 ThreadPriority thread_priority, 101 ThreadPriority thread_priority,
85 Delegate* delegate, 102 Delegate* delegate,
86 TaskTracker* task_tracker, 103 TaskTracker* task_tracker,
87 DelayedTaskManager* delayed_task_manager, 104 DelayedTaskManager* delayed_task_manager,
88 const PriorityQueue* predecessor_priority_queue) { 105 const PriorityQueue* predecessor_priority_queue) {
89 std::unique_ptr<SchedulerWorkerThread> worker_thread( 106 std::unique_ptr<SchedulerWorkerThread> worker_thread(
90 new SchedulerWorkerThread(thread_priority, delegate, task_tracker, 107 new SchedulerWorkerThread(thread_priority, delegate, task_tracker,
91 delayed_task_manager, 108 delayed_task_manager,
92 predecessor_priority_queue)); 109 predecessor_priority_queue));
93 110
94 if (worker_thread->thread_handle_.is_null()) 111 if (worker_thread->thread_handle_.is_null())
95 return nullptr; 112 return nullptr;
96 return worker_thread; 113 return worker_thread;
97 } 114 }
98 115
99 SchedulerWorkerThread::~SchedulerWorkerThread() { 116 SchedulerWorkerThread::~SchedulerWorkerThread() {
100 DCHECK(ShouldExitForTesting()); 117 DCHECK(ShouldExitForTesting());
101 } 118 }
102 119
103 scoped_refptr<SingleThreadTaskRunner> 120 scoped_refptr<SingleThreadTaskRunner>
104 SchedulerWorkerThread::CreateTaskRunnerWithTraits(const TaskTraits& traits) { 121 SchedulerWorkerThread::CreateTaskRunnerWithTraits(const TaskTraits& traits) {
105 return make_scoped_refptr(new SchedulerSingleThreadTaskRunner( 122 return make_scoped_refptr(new SchedulerSingleThreadTaskRunner(
106 traits, this, task_tracker_, delayed_task_manager_)); 123 traits, this, task_tracker_, delayed_task_manager_,
124 &num_single_thread_task_runners_));
125 }
126
127 size_t SchedulerWorkerThread::GetNumSingleThreadTaskRunners() const {
128 return base::subtle::NoBarrier_Load(&num_single_thread_task_runners_);
107 } 129 }
108 130
109 void SchedulerWorkerThread::WakeUp() { 131 void SchedulerWorkerThread::WakeUp() {
110 wake_up_event_.Signal(); 132 wake_up_event_.Signal();
111 } 133 }
112 134
113 void SchedulerWorkerThread::JoinForTesting() { 135 void SchedulerWorkerThread::JoinForTesting() {
114 { 136 {
115 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); 137 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_);
116 should_exit_for_testing_ = true; 138 should_exit_for_testing_ = true;
(...skipping 28 matching lines...) Expand all
145 : wake_up_event_(false, false), 167 : wake_up_event_(false, false),
146 single_threaded_priority_queue_(predecessor_priority_queue), 168 single_threaded_priority_queue_(predecessor_priority_queue),
147 delegate_(delegate), 169 delegate_(delegate),
148 task_tracker_(task_tracker), 170 task_tracker_(task_tracker),
149 delayed_task_manager_(delayed_task_manager) { 171 delayed_task_manager_(delayed_task_manager) {
150 DCHECK(delegate_); 172 DCHECK(delegate_);
151 DCHECK(task_tracker_); 173 DCHECK(task_tracker_);
152 DCHECK(delayed_task_manager_); 174 DCHECK(delayed_task_manager_);
153 DCHECK(predecessor_priority_queue); 175 DCHECK(predecessor_priority_queue);
154 176
177 base::subtle::NoBarrier_Store(&num_single_thread_task_runners_, 0);
178
155 const size_t kDefaultStackSize = 0; 179 const size_t kDefaultStackSize = 0;
156 PlatformThread::CreateWithPriority(kDefaultStackSize, this, &thread_handle_, 180 PlatformThread::CreateWithPriority(kDefaultStackSize, this, &thread_handle_,
157 thread_priority); 181 thread_priority);
158 } 182 }
159 183
160 void SchedulerWorkerThread::ThreadMain() { 184 void SchedulerWorkerThread::ThreadMain() {
161 delegate_->OnMainEntry(); 185 delegate_->OnMainEntry();
162 tls_current_worker_thread.Get().Set(this); 186 tls_current_worker_thread.Get().Set(this);
163 187
164 // A SchedulerWorkerThread starts out sleeping. 188 // A SchedulerWorkerThread starts out sleeping.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 } 228 }
205 } 229 }
206 230
207 bool SchedulerWorkerThread::ShouldExitForTesting() const { 231 bool SchedulerWorkerThread::ShouldExitForTesting() const {
208 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); 232 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_);
209 return should_exit_for_testing_; 233 return should_exit_for_testing_;
210 } 234 }
211 235
212 } // namespace internal 236 } // namespace internal
213 } // namespace base 237 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/scheduler_worker_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698