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

Side by Side Diff: cc/raster/task_graph_work_queue.cc

Issue 1903733003: cc: Implement states for Task for stricter control. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@land_merge_tile_task_runner
Patch Set: feedback 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 | « cc/raster/task_graph_runner_perftest.cc ('k') | cc/raster/tile_task.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "cc/raster/task_graph_work_queue.h" 5 #include "cc/raster/task_graph_work_queue.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 // Remove any old nodes that are associated with this task. The result is 137 // Remove any old nodes that are associated with this task. The result is
138 // that the old graph is left with all nodes not present in this graph, 138 // that the old graph is left with all nodes not present in this graph,
139 // which we use below to determine what tasks need to be canceled. 139 // which we use below to determine what tasks need to be canceled.
140 TaskGraph::Node::Vector::iterator old_it = std::find_if( 140 TaskGraph::Node::Vector::iterator old_it = std::find_if(
141 task_namespace.graph.nodes.begin(), task_namespace.graph.nodes.end(), 141 task_namespace.graph.nodes.begin(), task_namespace.graph.nodes.end(),
142 [node](const TaskGraph::Node& other) { 142 [node](const TaskGraph::Node& other) {
143 return node.task == other.task; 143 return node.task == other.task;
144 }); 144 });
145 if (old_it != task_namespace.graph.nodes.end()) { 145 if (old_it != task_namespace.graph.nodes.end()) {
146 std::swap(*old_it, task_namespace.graph.nodes.back()); 146 std::swap(*old_it, task_namespace.graph.nodes.back());
147 // If old task is scheduled to run again and not yet started running,
148 // reset its state to initial state as it has to be inserted in new
149 // |ready_to_run_tasks|, where it gets scheduled.
150 if (node.task->state().IsScheduled())
151 node.task->state().Reset();
147 task_namespace.graph.nodes.pop_back(); 152 task_namespace.graph.nodes.pop_back();
148 } 153 }
149 154
150 // Task is not ready to run if dependencies are not yet satisfied. 155 // Task is not ready to run if dependencies are not yet satisfied.
151 if (node.dependencies) 156 if (node.dependencies)
152 continue; 157 continue;
153 158
154 // Skip if already finished running task. 159 // Skip if already finished running task.
155 if (node.task->HasFinishedRunning()) 160 if (node.task->state().IsFinished())
156 continue; 161 continue;
157 162
158 // Skip if already running. 163 // Skip if already running.
159 if (std::any_of(task_namespace.running_tasks.begin(), 164 if (std::any_of(task_namespace.running_tasks.begin(),
160 task_namespace.running_tasks.end(), 165 task_namespace.running_tasks.end(),
161 [&node](const CategorizedTask& task) { 166 [&node](const CategorizedTask& task) {
162 return task.second == node.task; 167 return task.second == node.task;
163 })) 168 }))
164 continue; 169 continue;
165 170
171 node.task->state().DidSchedule();
166 task_namespace.ready_to_run_tasks[node.category].push_back(PrioritizedTask( 172 task_namespace.ready_to_run_tasks[node.category].push_back(PrioritizedTask(
167 node.task, &task_namespace, node.category, node.priority)); 173 node.task, &task_namespace, node.category, node.priority));
168 } 174 }
169 175
170 // Rearrange the elements in each vector within |ready_to_run_tasks| in such a 176 // Rearrange the elements in each vector within |ready_to_run_tasks| in such a
171 // way that they form a heap. 177 // way that they form a heap.
172 for (auto& it : task_namespace.ready_to_run_tasks) { 178 for (auto& it : task_namespace.ready_to_run_tasks) {
173 auto& ready_to_run_tasks = it.second; 179 auto& ready_to_run_tasks = it.second;
174 std::make_heap(ready_to_run_tasks.begin(), ready_to_run_tasks.end(), 180 std::make_heap(ready_to_run_tasks.begin(), ready_to_run_tasks.end(),
175 CompareTaskPriority); 181 CompareTaskPriority);
176 } 182 }
177 183
178 // Swap task graph. 184 // Swap task graph.
179 task_namespace.graph.Swap(graph); 185 task_namespace.graph.Swap(graph);
180 186
181 // Determine what tasks in old graph need to be canceled. 187 // Determine what tasks in old graph need to be canceled.
182 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); 188 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
183 it != graph->nodes.end(); ++it) { 189 it != graph->nodes.end(); ++it) {
184 TaskGraph::Node& node = *it; 190 TaskGraph::Node& node = *it;
185 191
186 // Skip if already finished running task. 192 // Skip if already finished running task.
187 if (node.task->HasFinishedRunning()) 193 if (node.task->state().IsFinished())
188 continue; 194 continue;
189 195
190 // Skip if already running. 196 // Skip if already running.
191 if (std::any_of(task_namespace.running_tasks.begin(), 197 if (std::any_of(task_namespace.running_tasks.begin(),
192 task_namespace.running_tasks.end(), 198 task_namespace.running_tasks.end(),
193 [&node](const CategorizedTask& task) { 199 [&node](const CategorizedTask& task) {
194 return task.second == node.task; 200 return task.second == node.task;
195 })) 201 }))
196 continue; 202 continue;
197 203
198 DCHECK(std::find(task_namespace.completed_tasks.begin(), 204 DCHECK(std::find(task_namespace.completed_tasks.begin(),
199 task_namespace.completed_tasks.end(), 205 task_namespace.completed_tasks.end(),
200 node.task) == task_namespace.completed_tasks.end()); 206 node.task) == task_namespace.completed_tasks.end());
207 node.task->state().DidCancel();
201 task_namespace.completed_tasks.push_back(node.task); 208 task_namespace.completed_tasks.push_back(node.task);
202 } 209 }
203 210
204 // Build new "ready to run" task namespaces queue. 211 // Build new "ready to run" task namespaces queue.
205 for (auto& ready_to_run_namespaces_it : ready_to_run_namespaces_) { 212 for (auto& ready_to_run_namespaces_it : ready_to_run_namespaces_) {
206 ready_to_run_namespaces_it.second.clear(); 213 ready_to_run_namespaces_it.second.clear();
207 } 214 }
208 for (auto& namespace_it : namespaces_) { 215 for (auto& namespace_it : namespaces_) {
209 auto& task_namespace = namespace_it.second; 216 auto& task_namespace = namespace_it.second;
210 for (auto& ready_to_run_tasks_it : task_namespace.ready_to_run_tasks) { 217 for (auto& ready_to_run_tasks_it : task_namespace.ready_to_run_tasks) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 // Add task namespace back to |ready_to_run_namespaces| if not empty after 258 // Add task namespace back to |ready_to_run_namespaces| if not empty after
252 // taking top priority task. 259 // taking top priority task.
253 if (!ready_to_run_tasks.empty()) { 260 if (!ready_to_run_tasks.empty()) {
254 ready_to_run_namespaces.push_back(task_namespace); 261 ready_to_run_namespaces.push_back(task_namespace);
255 std::push_heap(ready_to_run_namespaces.begin(), 262 std::push_heap(ready_to_run_namespaces.begin(),
256 ready_to_run_namespaces.end(), 263 ready_to_run_namespaces.end(),
257 CompareTaskNamespacePriority(category)); 264 CompareTaskNamespacePriority(category));
258 } 265 }
259 266
260 // Add task to |running_tasks|. 267 // Add task to |running_tasks|.
268 task.task->state().DidStart();
261 task_namespace->running_tasks.push_back( 269 task_namespace->running_tasks.push_back(
262 std::make_pair(task.category, task.task)); 270 std::make_pair(task.category, task.task));
263 271
264 return task; 272 return task;
265 } 273 }
266 274
267 void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) { 275 void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) {
268 TaskNamespace* task_namespace = completed_task.task_namespace; 276 TaskNamespace* task_namespace = completed_task.task_namespace;
269 scoped_refptr<Task> task(completed_task.task); 277 scoped_refptr<Task> task(completed_task.task);
270 278
(...skipping 14 matching lines...) Expand all
285 TaskGraph::Node& dependent_node = *it; 293 TaskGraph::Node& dependent_node = *it;
286 294
287 DCHECK_LT(0u, dependent_node.dependencies); 295 DCHECK_LT(0u, dependent_node.dependencies);
288 dependent_node.dependencies--; 296 dependent_node.dependencies--;
289 // Task is ready if it has no dependencies. Add it to |ready_to_run_tasks_|. 297 // Task is ready if it has no dependencies. Add it to |ready_to_run_tasks_|.
290 if (!dependent_node.dependencies) { 298 if (!dependent_node.dependencies) {
291 PrioritizedTask::Vector& ready_to_run_tasks = 299 PrioritizedTask::Vector& ready_to_run_tasks =
292 task_namespace->ready_to_run_tasks[dependent_node.category]; 300 task_namespace->ready_to_run_tasks[dependent_node.category];
293 301
294 bool was_empty = ready_to_run_tasks.empty(); 302 bool was_empty = ready_to_run_tasks.empty();
303 dependent_node.task->state().DidSchedule();
295 ready_to_run_tasks.push_back( 304 ready_to_run_tasks.push_back(
296 PrioritizedTask(dependent_node.task, task_namespace, 305 PrioritizedTask(dependent_node.task, task_namespace,
297 dependent_node.category, dependent_node.priority)); 306 dependent_node.category, dependent_node.priority));
298 std::push_heap(ready_to_run_tasks.begin(), ready_to_run_tasks.end(), 307 std::push_heap(ready_to_run_tasks.begin(), ready_to_run_tasks.end(),
299 CompareTaskPriority); 308 CompareTaskPriority);
300 309
301 // Task namespace is ready if it has at least one ready to run task. Add 310 // Task namespace is ready if it has at least one ready to run task. Add
302 // it to |ready_to_run_namespaces_| if it just become ready. 311 // it to |ready_to_run_namespaces_| if it just become ready.
303 if (was_empty) { 312 if (was_empty) {
304 TaskNamespace::Vector& ready_to_run_namespaces = 313 TaskNamespace::Vector& ready_to_run_namespaces =
(...skipping 14 matching lines...) Expand all
319 for (auto& it : ready_to_run_namespaces_) { 328 for (auto& it : ready_to_run_namespaces_) {
320 uint16_t category = it.first; 329 uint16_t category = it.first;
321 auto& ready_to_run_namespaces = it.second; 330 auto& ready_to_run_namespaces = it.second;
322 std::make_heap(ready_to_run_namespaces.begin(), 331 std::make_heap(ready_to_run_namespaces.begin(),
323 ready_to_run_namespaces.end(), 332 ready_to_run_namespaces.end(),
324 CompareTaskNamespacePriority(category)); 333 CompareTaskNamespacePriority(category));
325 } 334 }
326 } 335 }
327 336
328 // Finally add task to |completed_tasks_|. 337 // Finally add task to |completed_tasks_|.
338 task->state().DidFinish();
329 task_namespace->completed_tasks.push_back(task); 339 task_namespace->completed_tasks.push_back(task);
330 } 340 }
331 341
332 void TaskGraphWorkQueue::CollectCompletedTasks(NamespaceToken token, 342 void TaskGraphWorkQueue::CollectCompletedTasks(NamespaceToken token,
333 Task::Vector* completed_tasks) { 343 Task::Vector* completed_tasks) {
334 TaskNamespaceMap::iterator it = namespaces_.find(token); 344 TaskNamespaceMap::iterator it = namespaces_.find(token);
335 if (it == namespaces_.end()) 345 if (it == namespaces_.end())
336 return; 346 return;
337 347
338 TaskNamespace& task_namespace = it->second; 348 TaskNamespace& task_namespace = it->second;
(...skipping 18 matching lines...) Expand all
357 367
358 for (const TaskGraph::Node& node : graph->nodes) { 368 for (const TaskGraph::Node& node : graph->nodes) {
359 if (dependents[node.task] != node.dependencies) 369 if (dependents[node.task] != node.dependencies)
360 return true; 370 return true;
361 } 371 }
362 372
363 return false; 373 return false;
364 } 374 }
365 375
366 } // namespace cc 376 } // namespace cc
OLDNEW
« no previous file with comments | « cc/raster/task_graph_runner_perftest.cc ('k') | cc/raster/tile_task.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698