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/priority_queue.h" | 5 #include "base/task_scheduler/priority_queue.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 PriorityQueue::Transaction::Transaction(PriorityQueue* outer_queue) | 25 PriorityQueue::Transaction::Transaction(PriorityQueue* outer_queue) |
26 : auto_lock_(new AutoSchedulerLock(outer_queue->container_lock_)), | 26 : auto_lock_(new AutoSchedulerLock(outer_queue->container_lock_)), |
27 outer_queue_(outer_queue) { | 27 outer_queue_(outer_queue) { |
28 DCHECK(CalledOnValidThread()); | 28 DCHECK(CalledOnValidThread()); |
29 } | 29 } |
30 | 30 |
31 PriorityQueue::Transaction::~Transaction() { | 31 PriorityQueue::Transaction::~Transaction() { |
32 DCHECK(CalledOnValidThread()); | 32 DCHECK(CalledOnValidThread()); |
33 | 33 |
34 // Run the sequence insertion callback once for each Sequence that was | 34 // Run the wake up callback once for each call to Push(). Perform this outside |
35 // inserted in the PriorityQueue during the lifetime of this Transaction. | 35 // the scope of PriorityQueue's lock to avoid imposing an unnecessary lock |
36 // Perform this outside the scope of PriorityQueue's lock to avoid imposing an | 36 // dependency on the callback's destination. |
37 // unnecessary lock dependency on |sequence_inserted_callback_|'s destination. | |
38 auto_lock_.reset(); | 37 auto_lock_.reset(); |
39 for (size_t i = 0; i < num_pushed_sequences_; ++i) | 38 for (size_t i = 0; i < num_wake_ups_; ++i) |
40 outer_queue_->sequence_inserted_callback_.Run(); | 39 outer_queue_->wake_up_callback_.Run(); |
41 } | 40 } |
42 | 41 |
43 void PriorityQueue::Transaction::Push( | 42 void PriorityQueue::Transaction::Push( |
44 std::unique_ptr<SequenceAndSortKey> sequence_and_sort_key) { | 43 std::unique_ptr<SequenceAndSortKey> sequence_and_sort_key) { |
45 DCHECK(CalledOnValidThread()); | 44 DCHECK(CalledOnValidThread()); |
46 DCHECK(!sequence_and_sort_key->is_null()); | 45 DCHECK(!sequence_and_sort_key->is_null()); |
47 | 46 |
| 47 PushNoWakeUp(std::move(sequence_and_sort_key)); |
| 48 |
| 49 ++num_wake_ups_; |
| 50 } |
| 51 |
| 52 void PriorityQueue::Transaction::PushNoWakeUp( |
| 53 std::unique_ptr<SequenceAndSortKey> sequence_and_sort_key) { |
| 54 DCHECK(CalledOnValidThread()); |
| 55 DCHECK(!sequence_and_sort_key->is_null()); |
| 56 |
48 outer_queue_->container_.push(std::move(sequence_and_sort_key)); | 57 outer_queue_->container_.push(std::move(sequence_and_sort_key)); |
49 ++num_pushed_sequences_; | |
50 } | 58 } |
51 | 59 |
52 const PriorityQueue::SequenceAndSortKey& PriorityQueue::Transaction::Peek() | 60 const PriorityQueue::SequenceAndSortKey& PriorityQueue::Transaction::Peek() |
53 const { | 61 const { |
54 DCHECK(CalledOnValidThread()); | 62 DCHECK(CalledOnValidThread()); |
55 | 63 |
56 // TODO(fdoray): Add an IsEmpty() method to Transaction and require Peek() to | 64 // TODO(fdoray): Add an IsEmpty() method to Transaction and require Peek() to |
57 // be called on a non-empty PriorityQueue only. | 65 // be called on a non-empty PriorityQueue only. |
58 if (outer_queue_->container_.empty()) | 66 if (outer_queue_->container_.empty()) |
59 return outer_queue_->empty_sequence_and_sort_key_; | 67 return outer_queue_->empty_sequence_and_sort_key_; |
60 | 68 |
61 return *outer_queue_->container_.top(); | 69 return *outer_queue_->container_.top(); |
62 } | 70 } |
63 | 71 |
64 void PriorityQueue::Transaction::Pop() { | 72 void PriorityQueue::Transaction::Pop() { |
65 DCHECK(CalledOnValidThread()); | 73 DCHECK(CalledOnValidThread()); |
66 DCHECK(!outer_queue_->container_.empty()); | 74 DCHECK(!outer_queue_->container_.empty()); |
67 outer_queue_->container_.pop(); | 75 outer_queue_->container_.pop(); |
68 } | 76 } |
69 | 77 |
70 PriorityQueue::PriorityQueue(const Closure& sequence_inserted_callback) | 78 PriorityQueue::PriorityQueue(const Closure& wake_up_callback) |
71 : sequence_inserted_callback_(sequence_inserted_callback) { | 79 : wake_up_callback_(wake_up_callback) { |
72 DCHECK(!sequence_inserted_callback_.is_null()); | 80 DCHECK(!wake_up_callback_.is_null()); |
73 } | 81 } |
74 | 82 |
75 PriorityQueue::PriorityQueue(const Closure& sequence_inserted_callback, | 83 PriorityQueue::PriorityQueue(const Closure& wake_up_callback, |
76 const PriorityQueue* predecessor_priority_queue) | 84 const PriorityQueue* predecessor_priority_queue) |
77 : container_lock_(&predecessor_priority_queue->container_lock_), | 85 : container_lock_(&predecessor_priority_queue->container_lock_), |
78 sequence_inserted_callback_(sequence_inserted_callback) { | 86 wake_up_callback_(wake_up_callback) { |
79 DCHECK(!sequence_inserted_callback_.is_null()); | 87 DCHECK(!wake_up_callback_.is_null()); |
80 DCHECK(predecessor_priority_queue); | 88 DCHECK(predecessor_priority_queue); |
81 } | 89 } |
82 | 90 |
83 PriorityQueue::~PriorityQueue() = default; | 91 PriorityQueue::~PriorityQueue() = default; |
84 | 92 |
85 std::unique_ptr<PriorityQueue::Transaction> PriorityQueue::BeginTransaction() { | 93 std::unique_ptr<PriorityQueue::Transaction> PriorityQueue::BeginTransaction() { |
86 return WrapUnique(new Transaction(this)); | 94 return WrapUnique(new Transaction(this)); |
87 } | 95 } |
88 | 96 |
89 } // namespace internal | 97 } // namespace internal |
90 } // namespace base | 98 } // namespace base |
OLD | NEW |