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

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

Issue 1903133003: TaskScheduler: Avoid Sequence refcount bump in GetWork() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compile (why did this compile locally?! Created 4 years, 7 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.h ('k') | base/task_scheduler/priority_queue_unittest.cc » ('j') | 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 <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"
11 11
12 namespace base { 12 namespace base {
13 namespace internal { 13 namespace internal {
14 14
15 PriorityQueue::SequenceAndSortKey::SequenceAndSortKey() 15 // A class combining a Sequence and the SequenceSortKey that determines its
16 : sort_key(TaskPriority::LOWEST, TimeTicks()) {} 16 // position in a PriorityQueue. Instances are only mutable via take_sequence()
17 // which can only be called once and renders its instance invalid after the
18 // call.
19 class PriorityQueue::SequenceAndSortKey {
20 public:
21 SequenceAndSortKey(scoped_refptr<Sequence>&& sequence,
22 const SequenceSortKey& sort_key)
23 : sequence_(sequence), sort_key_(sort_key) {
24 DCHECK(sequence_);
25 }
17 26
18 PriorityQueue::SequenceAndSortKey::SequenceAndSortKey( 27 // Note: while |sequence_| should always be non-null post-move (i.e. we
19 scoped_refptr<Sequence> sequence, 28 // shouldn't be moving an invalid SequenceAndSortKey around), there can't be a
20 const SequenceSortKey& sort_key) 29 // DCHECK(sequence_) on moves as the Windows STL moves elements on pop instead
21 : sequence(std::move(sequence)), sort_key(sort_key) {} 30 // of overwriting them: resulting in the move of a SequenceAndSortKey with a
31 // null |sequence_| in Transaction::Pop()'s implementation.
32 SequenceAndSortKey(SequenceAndSortKey&& other) = default;
33 SequenceAndSortKey& operator=(SequenceAndSortKey&& other) = default;
22 34
23 PriorityQueue::SequenceAndSortKey::~SequenceAndSortKey() = default; 35 // Extracts |sequence_| from this object. This object is invalid after this
36 // call.
37 scoped_refptr<Sequence> take_sequence() {
38 DCHECK(sequence_);
39 return std::move(sequence_);
40 }
41
42 // Compares this SequenceAndSortKey to |other| based on their respective
43 // |sort_key_|.
44 bool operator<(const SequenceAndSortKey& other) const {
45 return sort_key_ < other.sort_key_;
46 }
47 bool operator>(const SequenceAndSortKey& other) const {
48 return other < *this;
49 }
50
51 const SequenceSortKey& sort_key() const { return sort_key_; }
52
53 private:
54 scoped_refptr<Sequence> sequence_;
55 SequenceSortKey sort_key_;
56
57 DISALLOW_COPY_AND_ASSIGN(SequenceAndSortKey);
58 };
24 59
25 PriorityQueue::Transaction::Transaction(PriorityQueue* outer_queue) 60 PriorityQueue::Transaction::Transaction(PriorityQueue* outer_queue)
26 : auto_lock_(outer_queue->container_lock_), outer_queue_(outer_queue) { 61 : auto_lock_(outer_queue->container_lock_), outer_queue_(outer_queue) {
27 DCHECK(CalledOnValidThread()); 62 DCHECK(CalledOnValidThread());
28 } 63 }
29 64
30 PriorityQueue::Transaction::~Transaction() { 65 PriorityQueue::Transaction::~Transaction() {
31 DCHECK(CalledOnValidThread()); 66 DCHECK(CalledOnValidThread());
32 } 67 }
33 68
34 void PriorityQueue::Transaction::Push( 69 void PriorityQueue::Transaction::Push(
35 std::unique_ptr<SequenceAndSortKey> sequence_and_sort_key) { 70 scoped_refptr<Sequence> sequence,
71 const SequenceSortKey& sequence_sort_key) {
36 DCHECK(CalledOnValidThread()); 72 DCHECK(CalledOnValidThread());
37 DCHECK(!sequence_and_sort_key->is_null()); 73 outer_queue_->container_.emplace(std::move(sequence), sequence_sort_key);
38
39 outer_queue_->container_.push(std::move(sequence_and_sort_key));
40 } 74 }
41 75
42 const PriorityQueue::SequenceAndSortKey& PriorityQueue::Transaction::Peek() 76 const SequenceSortKey& PriorityQueue::Transaction::PeekSortKey() const {
43 const {
44 DCHECK(CalledOnValidThread()); 77 DCHECK(CalledOnValidThread());
45 78 DCHECK(!IsEmpty());
46 // TODO(fdoray): Add an IsEmpty() method to Transaction and require Peek() to 79 return outer_queue_->container_.top().sort_key();
47 // be called on a non-empty PriorityQueue only.
48 if (outer_queue_->container_.empty())
49 return outer_queue_->empty_sequence_and_sort_key_;
50
51 return *outer_queue_->container_.top();
52 } 80 }
53 81
54 void PriorityQueue::Transaction::Pop() { 82 scoped_refptr<Sequence> PriorityQueue::Transaction::PopSequence() {
55 DCHECK(CalledOnValidThread()); 83 DCHECK(CalledOnValidThread());
56 DCHECK(!outer_queue_->container_.empty()); 84 DCHECK(!IsEmpty());
85
86 // The const_cast on top() is okay since the SequenceAndSortKey is
87 // transactionally being popped from |container_| right after and taking its
88 // Sequence does not alter its sort order (a requirement for the Windows STL's
89 // consistency debug-checks for std::priority_queue::top()).
90 scoped_refptr<Sequence> sequence =
91 const_cast<PriorityQueue::SequenceAndSortKey&>(
92 outer_queue_->container_.top())
93 .take_sequence();
57 outer_queue_->container_.pop(); 94 outer_queue_->container_.pop();
95 return sequence;
96 }
97
98 bool PriorityQueue::Transaction::IsEmpty() const {
99 return outer_queue_->container_.empty();
58 } 100 }
59 101
60 PriorityQueue::PriorityQueue() = default; 102 PriorityQueue::PriorityQueue() = default;
61 103
62 PriorityQueue::PriorityQueue(const PriorityQueue* predecessor_priority_queue) 104 PriorityQueue::PriorityQueue(const PriorityQueue* predecessor_priority_queue)
63 : container_lock_(&predecessor_priority_queue->container_lock_) { 105 : container_lock_(&predecessor_priority_queue->container_lock_) {
64 DCHECK(predecessor_priority_queue); 106 DCHECK(predecessor_priority_queue);
65 } 107 }
66 108
67 PriorityQueue::~PriorityQueue() = default; 109 PriorityQueue::~PriorityQueue() = default;
68 110
69 std::unique_ptr<PriorityQueue::Transaction> PriorityQueue::BeginTransaction() { 111 std::unique_ptr<PriorityQueue::Transaction> PriorityQueue::BeginTransaction() {
70 return WrapUnique(new Transaction(this)); 112 return WrapUnique(new Transaction(this));
71 } 113 }
72 114
73 } // namespace internal 115 } // namespace internal
74 } // namespace base 116 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/priority_queue.h ('k') | base/task_scheduler/priority_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698