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_thread_pool.h" | 5 #include "base/task_scheduler/scheduler_thread_pool.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 13 matching lines...) Expand all Loading... | |
24 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
25 | 25 |
26 namespace base { | 26 namespace base { |
27 namespace internal { | 27 namespace internal { |
28 namespace { | 28 namespace { |
29 | 29 |
30 const size_t kNumThreadsInThreadPool = 4; | 30 const size_t kNumThreadsInThreadPool = 4; |
31 const size_t kNumThreadsPostingTasks = 4; | 31 const size_t kNumThreadsPostingTasks = 4; |
32 const size_t kNumTasksPostedPerThread = 150; | 32 const size_t kNumTasksPostedPerThread = 150; |
33 | 33 |
34 class TaskSchedulerThreadPoolTest : public testing::Test { | 34 class TaskSchedulerThreadPoolTest |
35 : public testing::TestWithParam<ExecutionMode> { | |
35 protected: | 36 protected: |
36 TaskSchedulerThreadPoolTest() = default; | 37 TaskSchedulerThreadPoolTest() = default; |
37 | 38 |
38 void SetUp() override { | 39 void SetUp() override { |
39 thread_pool_ = SchedulerThreadPool::CreateThreadPool( | 40 thread_pool_ = SchedulerThreadPool::CreateThreadPool( |
40 ThreadPriority::NORMAL, kNumThreadsInThreadPool, | 41 ThreadPriority::NORMAL, kNumThreadsInThreadPool, |
41 Bind(&TaskSchedulerThreadPoolTest::RanTaskFromSequenceCallback, | 42 Bind(&TaskSchedulerThreadPoolTest::RanTaskFromSequenceCallback, |
42 Unretained(this)), | 43 Unretained(this)), |
43 &task_tracker_); | 44 &task_tracker_); |
44 ASSERT_TRUE(thread_pool_); | 45 ASSERT_TRUE(thread_pool_); |
(...skipping 19 matching lines...) Expand all Loading... | |
64 } | 65 } |
65 } | 66 } |
66 | 67 |
67 TaskTracker task_tracker_; | 68 TaskTracker task_tracker_; |
68 | 69 |
69 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerThreadPoolTest); | 70 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerThreadPoolTest); |
70 }; | 71 }; |
71 | 72 |
72 class TaskFactory { | 73 class TaskFactory { |
73 public: | 74 public: |
74 TaskFactory() : cv_(&lock_) {} | 75 // Constructs a TaskFactory that posts tasks through |task_runner|. |
76 // |execution_mode| is the execution mode of |task_runner|. | |
77 TaskFactory(scoped_refptr<TaskRunner> task_runner, | |
robliao
2016/04/04 18:45:50
I wonder if there's a way we can extract this out
fdoray
2016/04/04 19:41:18
I changed the code to avoid relying on the caller
| |
78 ExecutionMode execution_mode) | |
79 : cv_(&lock_), | |
80 task_runner_(std::move(task_runner)), | |
81 execution_mode_(execution_mode) {} | |
75 | 82 |
76 // Posts a task through |task_runner|. If |post_nested_task| is true, the task | 83 // Posts a task. If |post_nested_task| is true, the task will post a new task |
77 // will post a new task through |task_runner| when it runs. If |event| is set, | 84 // when it runs. If |event| is set, the task will block until it is signaled. |
78 // the task will block until it is signaled. | 85 void PostTask(bool post_nested_task, WaitableEvent* event) { |
79 void PostTask(scoped_refptr<TaskRunner> task_runner, | |
80 bool post_nested_task, | |
81 WaitableEvent* event) { | |
82 AutoLock auto_lock(lock_); | 86 AutoLock auto_lock(lock_); |
83 task_runner->PostTask( | 87 task_runner_->PostTask( |
84 FROM_HERE, Bind(&TaskFactory::RunTaskCallback, Unretained(this), | 88 FROM_HERE, |
85 num_created_tasks_++, task_runner, post_nested_task, | 89 Bind(&TaskFactory::RunTaskCallback, Unretained(this), |
86 Unretained(event))); | 90 num_created_tasks_++, post_nested_task, Unretained(event))); |
87 } | 91 } |
88 | 92 |
89 // Waits for all tasks posted by PostTask() to start running. It is not | 93 // Waits for all tasks posted by PostTask() to start running. It is not |
90 // guaranteed that the tasks have completed their execution when this returns. | 94 // guaranteed that the tasks have completed their execution when this returns. |
91 void WaitForAllTasksToRun() const { | 95 void WaitForAllTasksToRun() const { |
92 AutoLock auto_lock(lock_); | 96 AutoLock auto_lock(lock_); |
93 while (run_tasks_.size() < num_created_tasks_) | 97 while (run_tasks_.size() < num_created_tasks_) |
94 cv_.Wait(); | 98 cv_.Wait(); |
95 } | 99 } |
96 | 100 |
97 size_t NumRunTasks() const { | 101 size_t NumRunTasks() const { |
98 AutoLock auto_lock(lock_); | 102 AutoLock auto_lock(lock_); |
99 return run_tasks_.size(); | 103 return run_tasks_.size(); |
100 } | 104 } |
101 | 105 |
102 private: | 106 private: |
103 void RunTaskCallback(size_t task_index, | 107 void RunTaskCallback(size_t task_index, |
104 scoped_refptr<TaskRunner> task_runner, | |
105 bool post_nested_task, | 108 bool post_nested_task, |
106 WaitableEvent* event) { | 109 WaitableEvent* event) { |
107 if (post_nested_task) | 110 if (post_nested_task) |
108 PostTask(task_runner, false, nullptr); | 111 PostTask(false, nullptr); |
109 | 112 |
110 EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread()); | 113 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); |
111 | 114 |
112 { | 115 { |
113 AutoLock auto_lock(lock_); | 116 AutoLock auto_lock(lock_); |
114 | 117 |
118 if (execution_mode_ == ExecutionMode::SEQUENCED && | |
119 task_index != run_tasks_.size()) { | |
120 ADD_FAILURE() << "A SEQUENCED task didn't run in the expected order."; | |
121 } | |
122 | |
115 if (run_tasks_.find(task_index) != run_tasks_.end()) | 123 if (run_tasks_.find(task_index) != run_tasks_.end()) |
116 ADD_FAILURE() << "A task ran more than once."; | 124 ADD_FAILURE() << "A task ran more than once."; |
117 run_tasks_.insert(task_index); | 125 run_tasks_.insert(task_index); |
118 | 126 |
119 cv_.Signal(); | 127 cv_.Signal(); |
120 } | 128 } |
121 | 129 |
122 if (event) | 130 if (event) |
123 event->Wait(); | 131 event->Wait(); |
124 } | 132 } |
125 | 133 |
126 // Synchronizes access to all members below. | 134 // Synchronizes access to all members below. |
127 mutable Lock lock_; | 135 mutable Lock lock_; |
128 | 136 |
129 // Condition variable signaled when a task runs. | 137 // Condition variable signaled when a task runs. |
130 mutable ConditionVariable cv_; | 138 mutable ConditionVariable cv_; |
131 | 139 |
140 // Task runner through which this factory posts tasks. | |
141 const scoped_refptr<TaskRunner> task_runner_; | |
142 | |
143 // Execution mode of |task_runner_|. | |
144 const ExecutionMode execution_mode_; | |
145 | |
132 // Number of tasks posted by PostTask(). | 146 // Number of tasks posted by PostTask(). |
133 size_t num_created_tasks_ = 0; | 147 size_t num_created_tasks_ = 0; |
134 | 148 |
135 // Indexes of tasks that ran. | 149 // Indexes of tasks that ran. |
136 std::unordered_set<size_t> run_tasks_; | 150 std::unordered_set<size_t> run_tasks_; |
137 | 151 |
138 DISALLOW_COPY_AND_ASSIGN(TaskFactory); | 152 DISALLOW_COPY_AND_ASSIGN(TaskFactory); |
139 }; | 153 }; |
140 | 154 |
141 class ThreadPostingTasks : public SimpleThread { | 155 class ThreadPostingTasks : public SimpleThread { |
142 public: | 156 public: |
143 // Constructs a thread that posts tasks to |thread_pool| through an | 157 // Constructs a thread that posts tasks to |thread_pool| through an |
144 // |execution_mode| task runner. If |wait_for_all_threads_idle| is true, the | 158 // |execution_mode| task runner. If |wait_for_all_threads_idle| is true, the |
145 // thread wait until all worker threads in |thread_pool| are idle before | 159 // thread wait until all worker threads in |thread_pool| are idle before |
146 // posting a new task. If |post_nested_task| is true, each task posted by this | 160 // posting a new task. If |post_nested_task| is true, each task posted by this |
147 // thread posts another task when it runs. | 161 // thread posts another task when it runs. |
148 ThreadPostingTasks(SchedulerThreadPool* thread_pool, | 162 ThreadPostingTasks(SchedulerThreadPool* thread_pool, |
149 ExecutionMode execution_mode, | 163 ExecutionMode execution_mode, |
150 bool wait_for_all_threads_idle, | 164 bool wait_for_all_threads_idle, |
151 bool post_nested_task) | 165 bool post_nested_task) |
152 : SimpleThread("ThreadPostingTasks"), | 166 : SimpleThread("ThreadPostingTasks"), |
153 thread_pool_(thread_pool), | 167 thread_pool_(thread_pool), |
154 task_runner_(thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), | 168 task_runner_(thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), |
155 execution_mode)), | 169 execution_mode)), |
156 wait_for_all_threads_idle_(wait_for_all_threads_idle), | 170 wait_for_all_threads_idle_(wait_for_all_threads_idle), |
157 post_nested_task_(post_nested_task) {} | 171 post_nested_task_(post_nested_task), |
172 factory_(task_runner_, execution_mode) {} | |
158 | 173 |
159 const TaskFactory* factory() const { return &factory_; } | 174 const TaskFactory* factory() const { return &factory_; } |
160 | 175 |
161 private: | 176 private: |
162 void Run() override { | 177 void Run() override { |
163 EXPECT_FALSE(task_runner_->RunsTasksOnCurrentThread()); | 178 EXPECT_FALSE(task_runner_->RunsTasksOnCurrentThread()); |
164 | 179 |
165 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) { | 180 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) { |
166 if (wait_for_all_threads_idle_) | 181 if (wait_for_all_threads_idle_) |
167 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 182 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); |
168 factory_.PostTask(task_runner_, post_nested_task_, nullptr); | 183 factory_.PostTask(post_nested_task_, nullptr); |
169 } | 184 } |
170 } | 185 } |
171 | 186 |
172 SchedulerThreadPool* const thread_pool_; | 187 SchedulerThreadPool* const thread_pool_; |
173 scoped_refptr<TaskRunner> task_runner_; | 188 scoped_refptr<TaskRunner> task_runner_; |
174 const bool wait_for_all_threads_idle_; | 189 const bool wait_for_all_threads_idle_; |
175 const bool post_nested_task_; | 190 const bool post_nested_task_; |
176 TaskFactory factory_; | 191 TaskFactory factory_; |
177 | 192 |
178 DISALLOW_COPY_AND_ASSIGN(ThreadPostingTasks); | 193 DISALLOW_COPY_AND_ASSIGN(ThreadPostingTasks); |
179 }; | 194 }; |
180 | 195 |
181 TEST_F(TaskSchedulerThreadPoolTest, PostParallelTasks) { | 196 TEST_P(TaskSchedulerThreadPoolTest, PostTasks) { |
182 // Create threads to post tasks to PARALLEL TaskRunners. | 197 // Create threads to post tasks. |
183 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 198 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
184 for (size_t j = 0; j < kNumThreadsPostingTasks; ++j) { | 199 for (size_t j = 0; j < kNumThreadsPostingTasks; ++j) { |
185 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 200 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( |
186 thread_pool_.get(), ExecutionMode::PARALLEL, false, false))); | 201 thread_pool_.get(), ExecutionMode::PARALLEL, false, false))); |
robliao
2016/04/04 18:45:50
Should PARALLEL be parameterized? All of the tests
fdoray
2016/04/04 19:41:18
Done.
| |
187 threads_posting_tasks.back()->Start(); | 202 threads_posting_tasks.back()->Start(); |
188 } | 203 } |
189 | 204 |
190 // Wait for all tasks to run. | 205 // Wait for all tasks to run. |
191 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 206 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
192 thread_posting_tasks->Join(); | 207 thread_posting_tasks->Join(); |
193 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 208 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
194 EXPECT_EQ(kNumTasksPostedPerThread, | 209 EXPECT_EQ(kNumTasksPostedPerThread, |
195 thread_posting_tasks->factory()->NumRunTasks()); | 210 thread_posting_tasks->factory()->NumRunTasks()); |
196 } | 211 } |
197 } | 212 } |
198 | 213 |
199 TEST_F(TaskSchedulerThreadPoolTest, PostParallelTasksWaitAllThreadsIdle) { | 214 TEST_P(TaskSchedulerThreadPoolTest, PostTasksWaitAllThreadsIdle) { |
200 // Create threads to post tasks to PARALLEL TaskRunners. To verify that | 215 // Create threads to post tasks. To verify that worker threads can sleep and |
201 // worker threads can sleep and be woken up when new tasks are posted, wait | 216 // be woken up when new tasks are posted, wait for all threads to become idle |
202 // for all threads to become idle before posting a new task. | 217 // before posting a new task. |
203 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 218 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
204 for (size_t j = 0; j < kNumThreadsPostingTasks; ++j) { | 219 for (size_t j = 0; j < kNumThreadsPostingTasks; ++j) { |
205 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 220 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( |
206 thread_pool_.get(), ExecutionMode::PARALLEL, true, false))); | 221 thread_pool_.get(), ExecutionMode::PARALLEL, true, false))); |
207 threads_posting_tasks.back()->Start(); | 222 threads_posting_tasks.back()->Start(); |
208 } | 223 } |
209 | 224 |
210 // Wait for all tasks to run. | 225 // Wait for all tasks to run. |
211 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 226 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
212 thread_posting_tasks->Join(); | 227 thread_posting_tasks->Join(); |
213 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 228 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
214 EXPECT_EQ(kNumTasksPostedPerThread, | 229 EXPECT_EQ(kNumTasksPostedPerThread, |
215 thread_posting_tasks->factory()->NumRunTasks()); | 230 thread_posting_tasks->factory()->NumRunTasks()); |
216 } | 231 } |
217 } | 232 } |
218 | 233 |
219 TEST_F(TaskSchedulerThreadPoolTest, NestedPostParallelTasks) { | 234 TEST_P(TaskSchedulerThreadPoolTest, NestedPostTasks) { |
220 // Create threads to post tasks to PARALLEL TaskRunners. Each task posted by | 235 // Create threads to post tasks. Each task posted by these threads will post |
221 // these threads will post another task when it runs. | 236 // another task when it runs. |
222 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 237 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
223 for (size_t j = 0; j < kNumThreadsPostingTasks; ++j) { | 238 for (size_t j = 0; j < kNumThreadsPostingTasks; ++j) { |
224 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 239 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( |
225 thread_pool_.get(), ExecutionMode::PARALLEL, false, true))); | 240 thread_pool_.get(), ExecutionMode::PARALLEL, false, true))); |
226 threads_posting_tasks.back()->Start(); | 241 threads_posting_tasks.back()->Start(); |
227 } | 242 } |
228 | 243 |
229 // Wait for all tasks to run. | 244 // Wait for all tasks to run. |
230 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 245 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
231 thread_posting_tasks->Join(); | 246 thread_posting_tasks->Join(); |
232 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 247 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
233 EXPECT_EQ(2 * kNumTasksPostedPerThread, | 248 EXPECT_EQ(2 * kNumTasksPostedPerThread, |
234 thread_posting_tasks->factory()->NumRunTasks()); | 249 thread_posting_tasks->factory()->NumRunTasks()); |
235 } | 250 } |
236 | 251 |
237 // Wait until all worker threads are idle to be sure that no task accesses | 252 // Wait until all worker threads are idle to be sure that no task accesses |
238 // its TaskFactory after |thread_posting_tasks| is destroyed. | 253 // its TaskFactory after |thread_posting_tasks| is destroyed. |
239 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 254 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); |
240 } | 255 } |
241 | 256 |
242 TEST_F(TaskSchedulerThreadPoolTest, PostParallelTasksWithOneAvailableThread) { | 257 TEST_P(TaskSchedulerThreadPoolTest, PostTasksWithOneAvailableThread) { |
243 TaskFactory factory; | |
244 | |
245 // Post tasks to keep all threads busy except one until |event| is signaled. | 258 // Post tasks to keep all threads busy except one until |event| is signaled. |
259 // Use different factories so that tasks are added to different sequences when | |
260 // the execution mode is SEQUENCED. | |
246 WaitableEvent event(true, false); | 261 WaitableEvent event(true, false); |
247 auto task_runner = thread_pool_->CreateTaskRunnerWithTraits( | 262 std::vector<scoped_ptr<TaskFactory>> factories; |
248 TaskTraits(), ExecutionMode::PARALLEL); | 263 for (size_t i = 0; i < (kNumThreadsInThreadPool - 1); ++i) { |
249 for (size_t i = 0; i < (kNumThreadsInThreadPool - 1); ++i) | 264 factories.push_back(make_scoped_ptr(new TaskFactory( |
250 factory.PostTask(task_runner, false, &event); | 265 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
251 factory.WaitForAllTasksToRun(); | 266 GetParam()))); |
267 factories.back()->PostTask(false, &event); | |
268 factories.back()->WaitForAllTasksToRun(); | |
269 } | |
252 | 270 |
253 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact | 271 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact |
254 // that only one thread in |thread_pool_| isn't busy. | 272 // that only one thread in |thread_pool_| isn't busy. |
273 factories.push_back(make_scoped_ptr(new TaskFactory( | |
robliao
2016/04/04 18:45:50
Should this really be a part of |factories| or doe
fdoray
2016/04/04 19:41:18
Done.
| |
274 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | |
275 GetParam()))); | |
255 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) | 276 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) |
256 factory.PostTask(task_runner, false, nullptr); | 277 factories.back()->PostTask(false, nullptr); |
257 factory.WaitForAllTasksToRun(); | 278 factories.back()->WaitForAllTasksToRun(); |
258 | 279 |
259 // Release tasks waiting on |event|. | 280 // Release tasks waiting on |event|. |
260 event.Signal(); | 281 event.Signal(); |
261 | 282 |
262 // Wait until all worker threads are idle to be sure that no task accesses | 283 // Wait until all worker threads are idle to be sure that no task accesses |
263 // its TaskFactory after |factory| is destroyed. | 284 // its TaskFactory after |factories| is destroyed. |
264 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 285 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); |
265 } | 286 } |
266 | 287 |
267 TEST_F(TaskSchedulerThreadPoolTest, Saturate) { | 288 TEST_P(TaskSchedulerThreadPoolTest, Saturate) { |
268 TaskFactory factory; | |
269 | |
270 // Verify that it is possible to have |kNumThreadsInThreadPool| tasks running | 289 // Verify that it is possible to have |kNumThreadsInThreadPool| tasks running |
271 // simultaneously. | 290 // simultaneously. Use different factories so that tasks are added to |
291 // different sequences when the execution mode is SEQUENCED. | |
272 WaitableEvent event(true, false); | 292 WaitableEvent event(true, false); |
273 auto task_runner = thread_pool_->CreateTaskRunnerWithTraits( | 293 std::vector<scoped_ptr<TaskFactory>> factories; |
274 TaskTraits(), ExecutionMode::PARALLEL); | 294 for (size_t i = 0; i < kNumThreadsInThreadPool; ++i) { |
275 for (size_t i = 0; i < kNumThreadsInThreadPool; ++i) | 295 factories.push_back(make_scoped_ptr(new TaskFactory( |
276 factory.PostTask(task_runner, false, &event); | 296 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
277 factory.WaitForAllTasksToRun(); | 297 GetParam()))); |
298 factories.back()->PostTask(false, &event); | |
299 factories.back()->WaitForAllTasksToRun(); | |
300 } | |
278 | 301 |
279 // Release tasks waiting on |event|. | 302 // Release tasks waiting on |event|. |
280 event.Signal(); | 303 event.Signal(); |
281 | 304 |
282 // Wait until all worker threads are idle to be sure that no task accesses | 305 // Wait until all worker threads are idle to be sure that no task accesses |
283 // its TaskFactory after |factory| is destroyed. | 306 // its TaskFactory after |factories| is destroyed. |
284 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 307 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); |
285 } | 308 } |
286 | 309 |
310 INSTANTIATE_TEST_CASE_P(Parallel, | |
311 TaskSchedulerThreadPoolTest, | |
312 ::testing::Values(ExecutionMode::PARALLEL)); | |
313 INSTANTIATE_TEST_CASE_P(Sequenced, | |
314 TaskSchedulerThreadPoolTest, | |
315 ::testing::Values(ExecutionMode::SEQUENCED)); | |
316 | |
287 // Checks that when PostTaskHelper is called with an empty sequence, the task | 317 // Checks that when PostTaskHelper is called with an empty sequence, the task |
288 // is added to the sequence and the sequence is added to the priority queue. | 318 // is added to the sequence and the sequence is added to the priority queue. |
289 TEST(TaskSchedulerPostTaskHelperTest, PostTaskInEmptySequence) { | 319 TEST(TaskSchedulerPostTaskHelperTest, PostTaskInEmptySequence) { |
290 std::unique_ptr<Task> task( | 320 std::unique_ptr<Task> task( |
291 new Task(FROM_HERE, Bind(&DoNothing), TaskTraits())); | 321 new Task(FROM_HERE, Bind(&DoNothing), TaskTraits())); |
292 const Task* task_raw = task.get(); | 322 const Task* task_raw = task.get(); |
293 scoped_refptr<Sequence> sequence(new Sequence); | 323 scoped_refptr<Sequence> sequence(new Sequence); |
294 PriorityQueue priority_queue(Bind(&DoNothing)); | 324 PriorityQueue priority_queue(Bind(&DoNothing)); |
295 TaskTracker task_tracker; | 325 TaskTracker task_tracker; |
296 | 326 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 EXPECT_NE(task_raw, sequence->PeekTask()); | 361 EXPECT_NE(task_raw, sequence->PeekTask()); |
332 sequence->PopTask(); | 362 sequence->PopTask(); |
333 EXPECT_EQ(task_raw, sequence->PeekTask()); | 363 EXPECT_EQ(task_raw, sequence->PeekTask()); |
334 sequence->PopTask(); | 364 sequence->PopTask(); |
335 EXPECT_EQ(nullptr, sequence->PeekTask()); | 365 EXPECT_EQ(nullptr, sequence->PeekTask()); |
336 } | 366 } |
337 | 367 |
338 } // namespace | 368 } // namespace |
339 } // namespace internal | 369 } // namespace internal |
340 } // namespace base | 370 } // namespace base |
OLD | NEW |