| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "platform/scheduler/base/work_queue.h" | 5 #include "platform/scheduler/base/work_queue.h" |
| 6 | 6 |
| 7 #include "platform/scheduler/base/work_queue_sets.h" | 7 #include "platform/scheduler/base/work_queue_sets.h" |
| 8 | 8 |
| 9 namespace blink { | 9 namespace blink { |
| 10 namespace scheduler { | 10 namespace scheduler { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 return &work_queue_.back(); | 43 return &work_queue_.back(); |
| 44 } | 44 } |
| 45 | 45 |
| 46 bool WorkQueue::BlockedByFence() const { | 46 bool WorkQueue::BlockedByFence() const { |
| 47 if (!fence_) | 47 if (!fence_) |
| 48 return false; | 48 return false; |
| 49 | 49 |
| 50 // If the queue is empty then any future tasks will have a higher enqueue | 50 // If the queue is empty then any future tasks will have a higher enqueue |
| 51 // order and will be blocked. The queue is also blocked if the head is past | 51 // order and will be blocked. The queue is also blocked if the head is past |
| 52 // the fence. | 52 // the fence. |
| 53 return work_queue_.empty() || work_queue_.front().enqueue_order() > fence_; | 53 return work_queue_.empty() || |
| 54 work_queue_.front().enqueue_order().sequence_num > fence_; |
| 54 } | 55 } |
| 55 | 56 |
| 56 bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const { | 57 bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const { |
| 57 if (work_queue_.empty() || BlockedByFence()) | 58 if (work_queue_.empty() || BlockedByFence()) |
| 58 return false; | 59 return false; |
| 59 // Quick sanity check. | 60 // Quick sanity check. |
| 60 DCHECK_LE(work_queue_.front().enqueue_order(), | 61 DCHECK_LE(work_queue_.front().enqueue_order(), |
| 61 work_queue_.back().enqueue_order()) | 62 work_queue_.back().enqueue_order()) |
| 62 << task_queue_->GetName() << " : " << work_queue_sets_->GetName() << " : " | 63 << task_queue_->GetName() << " : " << work_queue_sets_->GetName() << " : " |
| 63 << name_; | 64 << name_; |
| 64 *enqueue_order = work_queue_.front().enqueue_order(); | 65 *enqueue_order = work_queue_.front().enqueue_order(); |
| 65 return true; | 66 return true; |
| 66 } | 67 } |
| 67 | 68 |
| 68 void WorkQueue::Push(TaskQueueImpl::Task task) { | 69 void WorkQueue::Push(TaskQueueImpl::Task task) { |
| 69 bool was_empty = work_queue_.empty(); | 70 bool was_empty = work_queue_.empty(); |
| 70 #ifndef NDEBUG | |
| 71 DCHECK(task.enqueue_order_set()); | |
| 72 #endif | |
| 73 | 71 |
| 74 // Amoritized O(1). | 72 // Amoritized O(1). |
| 75 work_queue_.push_back(std::move(task)); | 73 work_queue_.push_back(std::move(task)); |
| 76 | 74 |
| 77 if (!was_empty) | 75 if (!was_empty) |
| 78 return; | 76 return; |
| 79 | 77 |
| 80 // If we hit the fence, pretend to WorkQueueSets that we're empty. | 78 // If we hit the fence, pretend to WorkQueueSets that we're empty. |
| 81 if (work_queue_sets_ && !BlockedByFence()) | 79 if (work_queue_sets_ && !BlockedByFence()) |
| 82 work_queue_sets_->OnTaskPushedToEmptyQueue(this); | 80 work_queue_sets_->OnTaskPushedToEmptyQueue(this); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 } | 122 } |
| 125 | 123 |
| 126 void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) { | 124 void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) { |
| 127 work_queue_sets_ = work_queue_sets; | 125 work_queue_sets_ = work_queue_sets; |
| 128 } | 126 } |
| 129 | 127 |
| 130 void WorkQueue::AssignSetIndex(size_t work_queue_set_index) { | 128 void WorkQueue::AssignSetIndex(size_t work_queue_set_index) { |
| 131 work_queue_set_index_ = work_queue_set_index; | 129 work_queue_set_index_ = work_queue_set_index; |
| 132 } | 130 } |
| 133 | 131 |
| 134 bool WorkQueue::InsertFence(EnqueueOrder fence) { | 132 bool WorkQueue::InsertFence(SequenceNumber fence) { |
| 135 DCHECK_NE(fence, 0u); | 133 DCHECK_NE(fence, 0u); |
| 136 DCHECK(fence >= fence_ || fence == 1u); | 134 DCHECK(fence >= fence_ || |
| 135 fence == static_cast<SequenceNumber>( |
| 136 EnqueueOrderSequenceNumberValues::BLOCKING_FENCE)); |
| 137 bool was_blocked_by_fence = BlockedByFence(); | 137 bool was_blocked_by_fence = BlockedByFence(); |
| 138 fence_ = fence; | 138 fence_ = fence; |
| 139 // Moving the fence forward may unblock some tasks. | 139 // Moving the fence forward may unblock some tasks. |
| 140 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence && | 140 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence && |
| 141 !BlockedByFence()) { | 141 !BlockedByFence()) { |
| 142 work_queue_sets_->OnTaskPushedToEmptyQueue(this); | 142 work_queue_sets_->OnTaskPushedToEmptyQueue(this); |
| 143 return true; | 143 return true; |
| 144 } | 144 } |
| 145 // Fence insertion may have blocked all tasks in this work queue. | 145 // Fence insertion may have blocked all tasks in this work queue. |
| 146 if (BlockedByFence()) | 146 if (BlockedByFence()) |
| 147 work_queue_sets_->OnQueueBlocked(this); | 147 work_queue_sets_->OnQueueBlocked(this); |
| 148 return false; | 148 return false; |
| 149 } | 149 } |
| 150 | 150 |
| 151 bool WorkQueue::RemoveFence() { | 151 bool WorkQueue::RemoveFence() { |
| 152 bool was_blocked_by_fence = BlockedByFence(); | 152 bool was_blocked_by_fence = BlockedByFence(); |
| 153 fence_ = 0; | 153 fence_ = 0; |
| 154 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence) { | 154 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence) { |
| 155 work_queue_sets_->OnTaskPushedToEmptyQueue(this); | 155 work_queue_sets_->OnTaskPushedToEmptyQueue(this); |
| 156 return true; | 156 return true; |
| 157 } | 157 } |
| 158 return false; | 158 return false; |
| 159 } | 159 } |
| 160 | 160 |
| 161 bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const { | 161 bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const { |
| 162 DCHECK(!work_queue_.empty()); | 162 DCHECK(!work_queue_.empty()); |
| 163 DCHECK(!other_queue->work_queue_.empty()); | 163 DCHECK(!other_queue->work_queue_.empty()); |
| 164 EnqueueOrder enqueue_order = 0; | 164 EnqueueOrder enqueue_order; |
| 165 EnqueueOrder other_enqueue_order = 0; | 165 EnqueueOrder other_enqueue_order; |
| 166 bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order); | 166 bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order); |
| 167 bool have_other_task = | 167 bool have_other_task = |
| 168 other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order); | 168 other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order); |
| 169 DCHECK(have_task); | 169 DCHECK(have_task); |
| 170 DCHECK(have_other_task); | 170 DCHECK(have_other_task); |
| 171 return enqueue_order < other_enqueue_order; | 171 return enqueue_order < other_enqueue_order; |
| 172 } | 172 } |
| 173 | 173 |
| 174 } // namespace internal | 174 } // namespace internal |
| 175 } // namespace scheduler | 175 } // namespace scheduler |
| 176 } // namespace blink | 176 } // namespace blink |
| OLD | NEW |