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

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

Issue 1882293004: TaskScheduler: Remove wake up callback from PriorityQueue. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@5c_noexit
Patch Set: CR robliao #3 (remove unnecessary comment) 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/priority_queue.cc ('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/priority_queue.h" 5 #include "base/task_scheduler/priority_queue.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/macros.h" 9 #include "base/macros.h"
12 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
13 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
14 #include "base/synchronization/waitable_event.h" 12 #include "base/synchronization/waitable_event.h"
15 #include "base/task_scheduler/sequence.h" 13 #include "base/task_scheduler/sequence.h"
16 #include "base/task_scheduler/task.h" 14 #include "base/task_scheduler/task.h"
17 #include "base/task_scheduler/task_traits.h" 15 #include "base/task_scheduler/task_traits.h"
18 #include "base/task_scheduler/test_utils.h" 16 #include "base/task_scheduler/test_utils.h"
19 #include "base/threading/platform_thread.h" 17 #include "base/threading/platform_thread.h"
20 #include "base/threading/simple_thread.h" 18 #include "base/threading/simple_thread.h"
21 #include "base/time/time.h" 19 #include "base/time/time.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
24 21
25 namespace base { 22 namespace base {
26 namespace internal { 23 namespace internal {
27 24
28 namespace { 25 namespace {
29 26
30 class PriorityQueueCallbackMock {
31 public:
32 PriorityQueueCallbackMock() = default;
33 MOCK_METHOD0(WakeUp, void());
34
35 private:
36 DISALLOW_COPY_AND_ASSIGN(PriorityQueueCallbackMock);
37 };
38
39 class ThreadBeginningTransaction : public SimpleThread { 27 class ThreadBeginningTransaction : public SimpleThread {
40 public: 28 public:
41 explicit ThreadBeginningTransaction(PriorityQueue* priority_queue) 29 explicit ThreadBeginningTransaction(PriorityQueue* priority_queue)
42 : SimpleThread("ThreadBeginningTransaction"), 30 : SimpleThread("ThreadBeginningTransaction"),
43 priority_queue_(priority_queue), 31 priority_queue_(priority_queue),
44 transaction_began_(true, false) {} 32 transaction_began_(true, false) {}
45 33
46 // SimpleThread: 34 // SimpleThread:
47 void Run() override { 35 void Run() override {
48 std::unique_ptr<PriorityQueue::Transaction> transaction = 36 std::unique_ptr<PriorityQueue::Transaction> transaction =
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING)))); 89 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))));
102 SequenceSortKey sort_key_c = sequence_c->GetSortKey(); 90 SequenceSortKey sort_key_c = sequence_c->GetSortKey();
103 91
104 scoped_refptr<Sequence> sequence_d(new Sequence); 92 scoped_refptr<Sequence> sequence_d(new Sequence);
105 sequence_d->PushTask(WrapUnique( 93 sequence_d->PushTask(WrapUnique(
106 new Task(FROM_HERE, Closure(), 94 new Task(FROM_HERE, Closure(),
107 TaskTraits().WithPriority(TaskPriority::BACKGROUND)))); 95 TaskTraits().WithPriority(TaskPriority::BACKGROUND))));
108 SequenceSortKey sort_key_d = sequence_d->GetSortKey(); 96 SequenceSortKey sort_key_d = sequence_d->GetSortKey();
109 97
110 // Create a PriorityQueue and a Transaction. 98 // Create a PriorityQueue and a Transaction.
111 testing::StrictMock<PriorityQueueCallbackMock> mock; 99 PriorityQueue pq;
112 PriorityQueue pq(Bind(&PriorityQueueCallbackMock::WakeUp, Unretained(&mock))); 100 auto transaction(pq.BeginTransaction());
113 std::unique_ptr<PriorityQueue::Transaction> transaction(
114 pq.BeginTransaction());
115 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(), 101 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(),
116 transaction->Peek()); 102 transaction->Peek());
117 103
118 // Push |sequence_a| in the PriorityQueue. It becomes the sequence with the 104 // Push |sequence_a| in the PriorityQueue. It becomes the sequence with the
119 // highest priority. 105 // highest priority.
120 transaction->Push(WrapUnique( 106 transaction->Push(WrapUnique(
121 new PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a))); 107 new PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a)));
122 EXPECT_SEQUENCE_AND_SORT_KEY_EQ( 108 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
123 PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a), 109 PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a),
124 transaction->Peek()); 110 transaction->Peek());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 // with the highest priority. 151 // with the highest priority.
166 transaction->Pop(); 152 transaction->Pop();
167 EXPECT_SEQUENCE_AND_SORT_KEY_EQ( 153 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
168 PriorityQueue::SequenceAndSortKey(sequence_d, sort_key_d), 154 PriorityQueue::SequenceAndSortKey(sequence_d, sort_key_d),
169 transaction->Peek()); 155 transaction->Peek());
170 156
171 // Pop |sequence_d| from the PriorityQueue. It is now empty. 157 // Pop |sequence_d| from the PriorityQueue. It is now empty.
172 transaction->Pop(); 158 transaction->Pop();
173 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(), 159 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(),
174 transaction->Peek()); 160 transaction->Peek());
175
176 // Expect 4 calls to mock.WakeUp() when the Transaction is destroyed.
177 EXPECT_CALL(mock, WakeUp()).Times(4);
178 transaction.reset();
179 }
180
181 TEST(TaskSchedulerPriorityQueueTest, PushNoWakeUpPopPeek) {
182 // Create test sequences.
183 scoped_refptr<Sequence> sequence_a(new Sequence);
184 sequence_a->PushTask(WrapUnique(
185 new Task(FROM_HERE, Closure(),
186 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE))));
187 SequenceSortKey sort_key_a = sequence_a->GetSortKey();
188
189 scoped_refptr<Sequence> sequence_b(new Sequence);
190 sequence_b->PushTask(WrapUnique(
191 new Task(FROM_HERE, Closure(),
192 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))));
193 SequenceSortKey sort_key_b = sequence_b->GetSortKey();
194
195 scoped_refptr<Sequence> sequence_c(new Sequence);
196 sequence_c->PushTask(WrapUnique(
197 new Task(FROM_HERE, Closure(),
198 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))));
199 SequenceSortKey sort_key_c = sequence_c->GetSortKey();
200
201 scoped_refptr<Sequence> sequence_d(new Sequence);
202 sequence_d->PushTask(WrapUnique(
203 new Task(FROM_HERE, Closure(),
204 TaskTraits().WithPriority(TaskPriority::BACKGROUND))));
205 SequenceSortKey sort_key_d = sequence_d->GetSortKey();
206
207 // Create a PriorityQueue and a Transaction.
208 testing::StrictMock<PriorityQueueCallbackMock> mock;
209 PriorityQueue pq(Bind(&PriorityQueueCallbackMock::WakeUp, Unretained(&mock)));
210 std::unique_ptr<PriorityQueue::Transaction> transaction(
211 pq.BeginTransaction());
212 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(),
213 transaction->Peek());
214
215 // Push |sequence_a| in the PriorityQueue. It becomes the sequence with the
216 // highest priority.
217 transaction->PushNoWakeUp(WrapUnique(
218 new PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a)));
219 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
220 PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a),
221 transaction->Peek());
222
223 // Push |sequence_b| in the PriorityQueue. It becomes the sequence with the
224 // highest priority.
225 transaction->PushNoWakeUp(WrapUnique(
226 new PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b)));
227 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
228 PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b),
229 transaction->Peek());
230
231 // Push |sequence_c| in the PriorityQueue. |sequence_b| is still the sequence
232 // with the highest priority.
233 transaction->PushNoWakeUp(WrapUnique(
234 new PriorityQueue::SequenceAndSortKey(sequence_c, sort_key_c)));
235 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
236 PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b),
237 transaction->Peek());
238
239 // Push |sequence_d| in the PriorityQueue. |sequence_b| is still the sequence
240 // with the highest priority.
241 transaction->PushNoWakeUp(WrapUnique(
242 new PriorityQueue::SequenceAndSortKey(sequence_d, sort_key_d)));
243 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
244 PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b),
245 transaction->Peek());
246
247 // Pop |sequence_b| from the PriorityQueue. |sequence_c| becomes the sequence
248 // with the highest priority.
249 transaction->Pop();
250 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
251 PriorityQueue::SequenceAndSortKey(sequence_c, sort_key_c),
252 transaction->Peek());
253
254 // Pop |sequence_c| from the PriorityQueue. |sequence_a| becomes the sequence
255 // with the highest priority.
256 transaction->Pop();
257 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
258 PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a),
259 transaction->Peek());
260
261 // Pop |sequence_a| from the PriorityQueue. |sequence_d| becomes the sequence
262 // with the highest priority.
263 transaction->Pop();
264 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
265 PriorityQueue::SequenceAndSortKey(sequence_d, sort_key_d),
266 transaction->Peek());
267
268 // Pop |sequence_d| from the PriorityQueue. It is now empty.
269 transaction->Pop();
270 EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(),
271 transaction->Peek());
272
273 // Expect no call to mock.WakeUp() when the Transaction is destroyed.
274 EXPECT_CALL(mock, WakeUp()).Times(0);
275 transaction.reset();
276 } 161 }
277 162
278 // Check that creating Transactions on the same thread for 2 unrelated 163 // Check that creating Transactions on the same thread for 2 unrelated
279 // PriorityQueues causes a crash. 164 // PriorityQueues causes a crash.
280 TEST(TaskSchedulerPriorityQueueTest, IllegalTwoTransactionsSameThread) { 165 TEST(TaskSchedulerPriorityQueueTest, IllegalTwoTransactionsSameThread) {
281 PriorityQueue pq_a(Bind(&DoNothing)); 166 PriorityQueue pq_a;
282 PriorityQueue pq_b(Bind(&DoNothing)); 167 PriorityQueue pq_b;
283 168
284 EXPECT_DCHECK_DEATH( 169 EXPECT_DCHECK_DEATH(
285 { 170 {
286 std::unique_ptr<PriorityQueue::Transaction> transaction_a = 171 std::unique_ptr<PriorityQueue::Transaction> transaction_a =
287 pq_a.BeginTransaction(); 172 pq_a.BeginTransaction();
288 std::unique_ptr<PriorityQueue::Transaction> transaction_b = 173 std::unique_ptr<PriorityQueue::Transaction> transaction_b =
289 pq_b.BeginTransaction(); 174 pq_b.BeginTransaction();
290 }, 175 },
291 ""); 176 "");
292 } 177 }
293 178
294 // Check that there is no crash when Transactions are created on the same thread 179 // Check that there is no crash when Transactions are created on the same thread
295 // for 2 PriorityQueues which have a predecessor relationship. 180 // for 2 PriorityQueues which have a predecessor relationship.
296 TEST(TaskSchedulerPriorityQueueTest, LegalTwoTransactionsSameThread) { 181 TEST(TaskSchedulerPriorityQueueTest, LegalTwoTransactionsSameThread) {
297 PriorityQueue pq_a(Bind(&DoNothing)); 182 PriorityQueue pq_a;
298 PriorityQueue pq_b(Bind(&DoNothing), &pq_a); 183 PriorityQueue pq_b(&pq_a);
299 184
300 // This shouldn't crash. 185 // This shouldn't crash.
301 std::unique_ptr<PriorityQueue::Transaction> transaction_a = 186 std::unique_ptr<PriorityQueue::Transaction> transaction_a =
302 pq_a.BeginTransaction(); 187 pq_a.BeginTransaction();
303 std::unique_ptr<PriorityQueue::Transaction> transaction_b = 188 std::unique_ptr<PriorityQueue::Transaction> transaction_b =
304 pq_b.BeginTransaction(); 189 pq_b.BeginTransaction();
305 } 190 }
306 191
307 // Check that it is possible to begin multiple Transactions for the same 192 // Check that it is possible to begin multiple Transactions for the same
308 // PriorityQueue on different threads. The call to BeginTransaction() on the 193 // PriorityQueue on different threads. The call to BeginTransaction() on the
309 // second thread should block until the Transaction has ended on the first 194 // second thread should block until the Transaction has ended on the first
310 // thread. 195 // thread.
311 TEST(TaskSchedulerPriorityQueueTest, TwoTransactionsTwoThreads) { 196 TEST(TaskSchedulerPriorityQueueTest, TwoTransactionsTwoThreads) {
312 PriorityQueue pq(Bind(&DoNothing)); 197 PriorityQueue pq;
313 198
314 // Call BeginTransaction() on this thread and keep the Transaction alive. 199 // Call BeginTransaction() on this thread and keep the Transaction alive.
315 std::unique_ptr<PriorityQueue::Transaction> transaction = 200 std::unique_ptr<PriorityQueue::Transaction> transaction =
316 pq.BeginTransaction(); 201 pq.BeginTransaction();
317 202
318 // Call BeginTransaction() on another thread. 203 // Call BeginTransaction() on another thread.
319 ThreadBeginningTransaction thread_beginning_transaction(&pq); 204 ThreadBeginningTransaction thread_beginning_transaction(&pq);
320 thread_beginning_transaction.Start(); 205 thread_beginning_transaction.Start();
321 206
322 // After a few milliseconds, the call to BeginTransaction() on the other 207 // After a few milliseconds, the call to BeginTransaction() on the other
323 // thread should not have returned. 208 // thread should not have returned.
324 thread_beginning_transaction.ExpectTransactionDoesNotBegin(); 209 thread_beginning_transaction.ExpectTransactionDoesNotBegin();
325 210
326 // End the Transaction on the current thread. 211 // End the Transaction on the current thread.
327 transaction.reset(); 212 transaction.reset();
328 213
329 // The other thread should exit after its call to BeginTransaction() returns. 214 // The other thread should exit after its call to BeginTransaction() returns.
330 thread_beginning_transaction.Join(); 215 thread_beginning_transaction.Join();
331 } 216 }
332 217
333 TEST(TaskSchedulerPriorityQueueTest, SequenceAndSortKeyIsNull) { 218 TEST(TaskSchedulerPriorityQueueTest, SequenceAndSortKeyIsNull) {
334 EXPECT_TRUE(PriorityQueue::SequenceAndSortKey().is_null()); 219 EXPECT_TRUE(PriorityQueue::SequenceAndSortKey().is_null());
335 220
336 const PriorityQueue::SequenceAndSortKey non_null_sequence_andsort_key( 221 const PriorityQueue::SequenceAndSortKey non_null_sequence_and_sort_key(
337 make_scoped_refptr(new Sequence), 222 make_scoped_refptr(new Sequence),
338 SequenceSortKey(TaskPriority::USER_VISIBLE, TimeTicks())); 223 SequenceSortKey(TaskPriority::USER_VISIBLE, TimeTicks()));
339 EXPECT_FALSE(non_null_sequence_andsort_key.is_null()); 224 EXPECT_FALSE(non_null_sequence_and_sort_key.is_null());
340 } 225 }
341 226
342 } // namespace internal 227 } // namespace internal
343 } // namespace base 228 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/priority_queue.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698