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

Side by Side Diff: cc/resources/task_graph_runner.cc

Issue 943813002: cc: Add TaskGraphRunner sub-namespaces with task concurrency limits. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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
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/resources/task_graph_runner.h" 5 #include "cc/resources/task_graph_runner.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 void TaskGraph::Swap(TaskGraph* other) { 127 void TaskGraph::Swap(TaskGraph* other) {
128 nodes.swap(other->nodes); 128 nodes.swap(other->nodes);
129 edges.swap(other->edges); 129 edges.swap(other->edges);
130 } 130 }
131 131
132 void TaskGraph::Reset() { 132 void TaskGraph::Reset() {
133 nodes.clear(); 133 nodes.clear();
134 edges.clear(); 134 edges.clear();
135 } 135 }
136 136
137 TaskGraphRunner::TaskNamespace::TaskNamespace() {} 137 TaskGraphRunner::TaskSubNamespace::TaskSubNamespace()
138 : task_namespace(nullptr),
139 is_in_ready_sub_namespaces(false),
140 running_task_count(0) {
141 }
142
143 TaskGraphRunner::TaskSubNamespace::~TaskSubNamespace() {
144 }
145
146 bool TaskGraphRunner::TaskSubNamespace::IsReadyToRun() const {
147 // A sub namespace is ready to run if it has ready to run tasks,
148 // and the number of running tasks in the sub namespace is not
149 // greater than the next prioritized task's |max_concurrent_tasks|.
150 return !ready_to_run_tasks.empty() &&
151 running_task_count < ready_to_run_tasks.front().max_concurrent_tasks;
152 }
153
154 TaskGraphRunner::TaskNamespace::TaskNamespace() {
155 for (TaskSubNamespace& sub_namespace : sub_namespaces)
156 sub_namespace.task_namespace = this;
157 }
138 158
139 TaskGraphRunner::TaskNamespace::~TaskNamespace() {} 159 TaskGraphRunner::TaskNamespace::~TaskNamespace() {}
140 160
141 TaskGraphRunner::TaskGraphRunner() 161 TaskGraphRunner::TaskGraphRunner()
142 : lock_(), 162 : lock_(),
143 has_ready_to_run_tasks_cv_(&lock_), 163 has_ready_to_run_tasks_cv_(&lock_),
144 has_namespaces_with_finished_running_tasks_cv_(&lock_), 164 has_namespaces_with_finished_running_tasks_cv_(&lock_),
145 next_namespace_id_(1), 165 next_namespace_id_(1),
146 shutdown_(false) {} 166 shutdown_(false) {}
147 167
148 TaskGraphRunner::~TaskGraphRunner() { 168 TaskGraphRunner::~TaskGraphRunner() {
149 { 169 {
150 base::AutoLock lock(lock_); 170 base::AutoLock lock(lock_);
151 171
152 DCHECK_EQ(0u, ready_to_run_namespaces_.size()); 172 DCHECK_EQ(0u, ready_to_run_sub_namespaces_.size());
153 DCHECK_EQ(0u, namespaces_.size()); 173 DCHECK_EQ(0u, namespaces_.size());
154 } 174 }
155 } 175 }
156 176
157 NamespaceToken TaskGraphRunner::GetNamespaceToken() { 177 NamespaceToken TaskGraphRunner::GetNamespaceToken() {
158 base::AutoLock lock(lock_); 178 base::AutoLock lock(lock_);
159 179
160 NamespaceToken token(next_namespace_id_++); 180 NamespaceToken token(next_namespace_id_++);
161 DCHECK(namespaces_.find(token.id_) == namespaces_.end()); 181 DCHECK(namespaces_.find(token.id_) == namespaces_.end());
162 return token; 182 return token;
(...skipping 25 matching lines...) Expand all
188 it != task_namespace.completed_tasks.end(); 208 it != task_namespace.completed_tasks.end();
189 ++it) { 209 ++it) {
190 for (DependentIterator node_it(graph, it->get()); node_it; ++node_it) { 210 for (DependentIterator node_it(graph, it->get()); node_it; ++node_it) {
191 TaskGraph::Node& node = *node_it; 211 TaskGraph::Node& node = *node_it;
192 DCHECK_LT(0u, node.dependencies); 212 DCHECK_LT(0u, node.dependencies);
193 node.dependencies--; 213 node.dependencies--;
194 } 214 }
195 } 215 }
196 216
197 // Build new "ready to run" queue and remove nodes from old graph. 217 // Build new "ready to run" queue and remove nodes from old graph.
198 task_namespace.ready_to_run_tasks.clear(); 218 for (TaskSubNamespace& sub_namespace : task_namespace.sub_namespaces)
219 sub_namespace.ready_to_run_tasks.clear();
220
199 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); 221 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
200 it != graph->nodes.end(); 222 it != graph->nodes.end();
201 ++it) { 223 ++it) {
202 TaskGraph::Node& node = *it; 224 TaskGraph::Node& node = *it;
203 225
204 // Remove any old nodes that are associated with this task. The result is 226 // Remove any old nodes that are associated with this task. The result is
205 // that the old graph is left with all nodes not present in this graph, 227 // that the old graph is left with all nodes not present in this graph,
206 // which we use below to determine what tasks need to be canceled. 228 // which we use below to determine what tasks need to be canceled.
207 TaskGraph::Node::Vector::iterator old_it = 229 TaskGraph::Node::Vector::iterator old_it =
208 std::find_if(task_namespace.graph.nodes.begin(), 230 std::find_if(task_namespace.graph.nodes.begin(),
(...skipping 11 matching lines...) Expand all
220 // Skip if already finished running task. 242 // Skip if already finished running task.
221 if (node.task->HasFinishedRunning()) 243 if (node.task->HasFinishedRunning())
222 continue; 244 continue;
223 245
224 // Skip if already running. 246 // Skip if already running.
225 if (std::find(task_namespace.running_tasks.begin(), 247 if (std::find(task_namespace.running_tasks.begin(),
226 task_namespace.running_tasks.end(), 248 task_namespace.running_tasks.end(),
227 node.task) != task_namespace.running_tasks.end()) 249 node.task) != task_namespace.running_tasks.end())
228 continue; 250 continue;
229 251
230 task_namespace.ready_to_run_tasks.push_back( 252 task_namespace.sub_namespaces[node.sub_namespace]
231 PrioritizedTask(node.task, node.priority)); 253 .ready_to_run_tasks.push_back(PrioritizedTask(
254 node.task, node.priority, node.max_concurrent_tasks));
232 } 255 }
233 256
234 // Rearrange the elements in |ready_to_run_tasks| in such a way that they 257 // Prioritize tasks in each sub namespace.
235 // form a heap. 258 for (TaskSubNamespace& sub_namespace : task_namespace.sub_namespaces) {
236 std::make_heap(task_namespace.ready_to_run_tasks.begin(), 259 if (!sub_namespace.ready_to_run_tasks.empty()) {
237 task_namespace.ready_to_run_tasks.end(), 260 // Rearrange the elements in |ready_to_run_tasks| in
238 CompareTaskPriority); 261 // such a way that they form a heap.
262 std::make_heap(sub_namespace.ready_to_run_tasks.begin(),
263 sub_namespace.ready_to_run_tasks.end(),
264 CompareTaskPriority);
265 }
266 }
239 267
240 // Swap task graph. 268 // Swap task graph.
241 task_namespace.graph.Swap(graph); 269 task_namespace.graph.Swap(graph);
242 270
243 // Determine what tasks in old graph need to be canceled. 271 // Determine what tasks in old graph need to be canceled.
244 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); 272 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
245 it != graph->nodes.end(); 273 it != graph->nodes.end();
246 ++it) { 274 ++it) {
247 TaskGraph::Node& node = *it; 275 TaskGraph::Node& node = *it;
248 276
249 // Skip if already finished running task. 277 // Skip if already finished running task.
250 if (node.task->HasFinishedRunning()) 278 if (node.task->HasFinishedRunning())
251 continue; 279 continue;
252 280
253 // Skip if already running. 281 // Skip if already running.
254 if (std::find(task_namespace.running_tasks.begin(), 282 if (std::find(task_namespace.running_tasks.begin(),
255 task_namespace.running_tasks.end(), 283 task_namespace.running_tasks.end(),
256 node.task) != task_namespace.running_tasks.end()) 284 node.task) != task_namespace.running_tasks.end())
257 continue; 285 continue;
258 286
259 DCHECK(std::find(task_namespace.completed_tasks.begin(), 287 DCHECK(std::find(task_namespace.completed_tasks.begin(),
260 task_namespace.completed_tasks.end(), 288 task_namespace.completed_tasks.end(),
261 node.task) == task_namespace.completed_tasks.end()); 289 node.task) == task_namespace.completed_tasks.end());
262 task_namespace.completed_tasks.push_back(node.task); 290 task_namespace.completed_tasks.push_back(node.task);
263 } 291 }
264 292
265 // Build new "ready to run" task namespaces queue. 293 // Build new "ready to run" task namespaces queue.
266 ready_to_run_namespaces_.clear(); 294 ready_to_run_sub_namespaces_.clear();
267 for (TaskNamespaceMap::iterator it = namespaces_.begin(); 295 for (TaskNamespaceMap::iterator it = namespaces_.begin();
268 it != namespaces_.end(); 296 it != namespaces_.end();
269 ++it) { 297 ++it) {
270 if (!it->second.ready_to_run_tasks.empty()) 298 for (TaskSubNamespace& sub_namespace : it->second.sub_namespaces) {
271 ready_to_run_namespaces_.push_back(&it->second); 299 if (sub_namespace.IsReadyToRun()) {
300 ready_to_run_sub_namespaces_.push_back(&sub_namespace);
301 sub_namespace.is_in_ready_sub_namespaces = true;
302 } else {
303 sub_namespace.is_in_ready_sub_namespaces = false;
304 }
305 }
272 } 306 }
273 307
274 // Rearrange the task namespaces in |ready_to_run_namespaces_| in such a way 308 // Rearrange the task namespaces in |ready_to_run_namespaces_| in such a way
275 // that they form a heap. 309 // that they form a heap.
276 std::make_heap(ready_to_run_namespaces_.begin(), 310 std::make_heap(ready_to_run_sub_namespaces_.begin(),
277 ready_to_run_namespaces_.end(), 311 ready_to_run_sub_namespaces_.end(),
278 CompareTaskNamespacePriority); 312 CompareTaskSubNamespacePriority);
279 313
280 // If there is more work available, wake up worker thread. 314 // If there is more work available, wake up worker thread.
281 if (!ready_to_run_namespaces_.empty()) 315 if (!ready_to_run_sub_namespaces_.empty())
282 has_ready_to_run_tasks_cv_.Signal(); 316 has_ready_to_run_tasks_cv_.Signal();
283 } 317 }
284 } 318 }
285 319
286 void TaskGraphRunner::WaitForTasksToFinishRunning(NamespaceToken token) { 320 void TaskGraphRunner::WaitForTasksToFinishRunning(NamespaceToken token) {
287 TRACE_EVENT0("cc", "TaskGraphRunner::WaitForTasksToFinishRunning"); 321 TRACE_EVENT0("cc", "TaskGraphRunner::WaitForTasksToFinishRunning");
288 322
289 DCHECK(token.IsValid()); 323 DCHECK(token.IsValid());
290 324
291 { 325 {
(...skipping 27 matching lines...) Expand all
319 if (it == namespaces_.end()) 353 if (it == namespaces_.end())
320 return; 354 return;
321 355
322 TaskNamespace& task_namespace = it->second; 356 TaskNamespace& task_namespace = it->second;
323 357
324 DCHECK_EQ(0u, completed_tasks->size()); 358 DCHECK_EQ(0u, completed_tasks->size());
325 completed_tasks->swap(task_namespace.completed_tasks); 359 completed_tasks->swap(task_namespace.completed_tasks);
326 if (!HasFinishedRunningTasksInNamespace(&task_namespace)) 360 if (!HasFinishedRunningTasksInNamespace(&task_namespace))
327 return; 361 return;
328 362
329 // Remove namespace if finished running tasks. 363 // Remove empty namespace.
330 DCHECK_EQ(0u, task_namespace.completed_tasks.size());
331 DCHECK_EQ(0u, task_namespace.ready_to_run_tasks.size());
332 DCHECK_EQ(0u, task_namespace.running_tasks.size());
333 namespaces_.erase(it); 364 namespaces_.erase(it);
334 } 365 }
335 } 366 }
336 367
337 void TaskGraphRunner::Shutdown() { 368 void TaskGraphRunner::Shutdown() {
338 base::AutoLock lock(lock_); 369 base::AutoLock lock(lock_);
339 370
340 DCHECK_EQ(0u, ready_to_run_namespaces_.size()); 371 DCHECK_EQ(0u, ready_to_run_sub_namespaces_.size());
341 DCHECK_EQ(0u, namespaces_.size()); 372 DCHECK_EQ(0u, namespaces_.size());
342 373
343 DCHECK(!shutdown_); 374 DCHECK(!shutdown_);
344 shutdown_ = true; 375 shutdown_ = true;
345 376
346 // Wake up a worker so it knows it should exit. This will cause all workers 377 // Wake up a worker so it knows it should exit. This will cause all workers
347 // to exit as each will wake up another worker before exiting. 378 // to exit as each will wake up another worker before exiting.
348 has_ready_to_run_tasks_cv_.Signal(); 379 has_ready_to_run_tasks_cv_.Signal();
349 } 380 }
350 381
351 void TaskGraphRunner::Run() { 382 void TaskGraphRunner::Run() {
352 base::AutoLock lock(lock_); 383 base::AutoLock lock(lock_);
353 384
354 while (true) { 385 while (true) {
355 if (ready_to_run_namespaces_.empty()) { 386 if (ready_to_run_sub_namespaces_.empty()) {
356 // Exit when shutdown is set and no more tasks are pending. 387 // Exit when shutdown is set and no more tasks are pending.
357 if (shutdown_) 388 if (shutdown_)
358 break; 389 break;
359 390
360 // Wait for more tasks. 391 // Wait for more tasks.
361 has_ready_to_run_tasks_cv_.Wait(); 392 has_ready_to_run_tasks_cv_.Wait();
362 continue; 393 continue;
363 } 394 }
364 395
365 RunTaskWithLockAcquired(); 396 RunTaskWithLockAcquired();
366 } 397 }
367 398
368 // We noticed we should exit. Wake up the next worker so it knows it should 399 // We noticed we should exit. Wake up the next worker so it knows it should
369 // exit as well (because the Shutdown() code only signals once). 400 // exit as well (because the Shutdown() code only signals once).
370 has_ready_to_run_tasks_cv_.Signal(); 401 has_ready_to_run_tasks_cv_.Signal();
371 } 402 }
372 403
373 void TaskGraphRunner::RunUntilIdle() { 404 void TaskGraphRunner::RunUntilIdle() {
374 base::AutoLock lock(lock_); 405 base::AutoLock lock(lock_);
375 406
376 while (!ready_to_run_namespaces_.empty()) 407 while (!ready_to_run_sub_namespaces_.empty())
377 RunTaskWithLockAcquired(); 408 RunTaskWithLockAcquired();
378 } 409 }
379 410
380 void TaskGraphRunner::RunTaskWithLockAcquired() { 411 void TaskGraphRunner::RunTaskWithLockAcquired() {
381 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); 412 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask");
382 413
383 lock_.AssertAcquired(); 414 lock_.AssertAcquired();
384 DCHECK(!ready_to_run_namespaces_.empty()); 415 DCHECK(!ready_to_run_sub_namespaces_.empty());
385 416
386 // Take top priority TaskNamespace from |ready_to_run_namespaces_|. 417 // Take top priority TaskSubNamespace from |ready_to_run_sub_namespaces_|.
387 std::pop_heap(ready_to_run_namespaces_.begin(), 418 std::pop_heap(ready_to_run_sub_namespaces_.begin(),
388 ready_to_run_namespaces_.end(), 419 ready_to_run_sub_namespaces_.end(),
389 CompareTaskNamespacePriority); 420 CompareTaskSubNamespacePriority);
390 TaskNamespace* task_namespace = ready_to_run_namespaces_.back(); 421 TaskSubNamespace* sub_namespace = ready_to_run_sub_namespaces_.back();
391 ready_to_run_namespaces_.pop_back(); 422 ready_to_run_sub_namespaces_.pop_back();
392 DCHECK(!task_namespace->ready_to_run_tasks.empty()); 423 sub_namespace->is_in_ready_sub_namespaces = false;
424
425 TaskNamespace* task_namespace = sub_namespace->task_namespace;
393 426
394 // Take top priority task from |ready_to_run_tasks|. 427 // Take top priority task from |ready_to_run_tasks|.
395 std::pop_heap(task_namespace->ready_to_run_tasks.begin(), 428 DCHECK(sub_namespace->IsReadyToRun());
396 task_namespace->ready_to_run_tasks.end(), 429 std::pop_heap(sub_namespace->ready_to_run_tasks.begin(),
397 CompareTaskPriority); 430 sub_namespace->ready_to_run_tasks.end(), CompareTaskPriority);
398 scoped_refptr<Task> task(task_namespace->ready_to_run_tasks.back().task);
399 task_namespace->ready_to_run_tasks.pop_back();
400 431
401 // Add task namespace back to |ready_to_run_namespaces_| if not empty after 432 PrioritizedTask& prioritized_task = sub_namespace->ready_to_run_tasks.back();
402 // taking top priority task. 433 scoped_refptr<Task> task(prioritized_task.task);
403 if (!task_namespace->ready_to_run_tasks.empty()) { 434 sub_namespace->ready_to_run_tasks.pop_back();
404 ready_to_run_namespaces_.push_back(task_namespace); 435
405 std::push_heap(ready_to_run_namespaces_.begin(), 436 // Update number of concurrently running tasks in sub namespace.
406 ready_to_run_namespaces_.end(), 437 sub_namespace->running_task_count++;
407 CompareTaskNamespacePriority); 438 DCHECK_LE(sub_namespace->running_task_count,
439 prioritized_task.max_concurrent_tasks);
440
441 // Add |sub_namespace| back to |ready_to_run_sub_namespaces_| if it's
442 // still ready to run.
443 if (sub_namespace->IsReadyToRun()) {
444 ready_to_run_sub_namespaces_.push_back(sub_namespace);
445 std::push_heap(ready_to_run_sub_namespaces_.begin(),
446 ready_to_run_sub_namespaces_.end(),
447 CompareTaskSubNamespacePriority);
448 sub_namespace->is_in_ready_sub_namespaces = true;
408 } 449 }
409 450
410 // Add task to |running_tasks|. 451 // Add task to |running_tasks|.
411 task_namespace->running_tasks.push_back(task.get()); 452 task_namespace->running_tasks.push_back(task.get());
412 453
413 // There may be more work available, so wake up another worker thread. 454 // There may be more work available, so wake up another worker thread.
414 has_ready_to_run_tasks_cv_.Signal(); 455 has_ready_to_run_tasks_cv_.Signal();
415 456
416 // Call WillRun() before releasing |lock_| and running task. 457 // Call WillRun() before releasing |lock_| and running task.
417 task->WillRun(); 458 task->WillRun();
418 459
419 { 460 {
420 base::AutoUnlock unlock(lock_); 461 base::AutoUnlock unlock(lock_);
421 462
422 task->RunOnWorkerThread(); 463 task->RunOnWorkerThread();
423 } 464 }
424 465
425 // This will mark task as finished running. 466 // This will mark task as finished running.
426 task->DidRun(); 467 task->DidRun();
427 468
469 // Update number of concurrently running tasks in sub namespace.
470 sub_namespace->running_task_count--;
471
472 // If sub namespace became ready to run, add it to
473 // |ready_to_run_sub_namespaces_|.
474 if (!sub_namespace->is_in_ready_sub_namespaces &&
475 sub_namespace->IsReadyToRun()) {
476 ready_to_run_sub_namespaces_.push_back(sub_namespace);
477 std::push_heap(ready_to_run_sub_namespaces_.begin(),
478 ready_to_run_sub_namespaces_.end(),
479 CompareTaskSubNamespacePriority);
480 sub_namespace->is_in_ready_sub_namespaces = true;
481 }
482
428 // Remove task from |running_tasks|. 483 // Remove task from |running_tasks|.
429 TaskVector::iterator it = std::find(task_namespace->running_tasks.begin(), 484 TaskVector::iterator it = std::find(task_namespace->running_tasks.begin(),
430 task_namespace->running_tasks.end(), 485 task_namespace->running_tasks.end(),
431 task.get()); 486 task.get());
432 DCHECK(it != task_namespace->running_tasks.end()); 487 DCHECK(it != task_namespace->running_tasks.end());
433 std::swap(*it, task_namespace->running_tasks.back()); 488 std::swap(*it, task_namespace->running_tasks.back());
434 task_namespace->running_tasks.pop_back(); 489 task_namespace->running_tasks.pop_back();
435 490
436 // Now iterate over all dependents to decrement dependencies and check if they 491 // Now iterate over all dependents to decrement dependencies and check if they
437 // are ready to run. 492 // are ready to run.
438 bool ready_to_run_namespaces_has_heap_properties = true; 493 bool ready_to_run_sub_namespaces_has_heap_properties = true;
439 for (DependentIterator it(&task_namespace->graph, task.get()); it; ++it) { 494 for (DependentIterator it(&task_namespace->graph, task.get()); it; ++it) {
440 TaskGraph::Node& dependent_node = *it; 495 TaskGraph::Node& dependent_node = *it;
441 496
442 DCHECK_LT(0u, dependent_node.dependencies); 497 DCHECK_LT(0u, dependent_node.dependencies);
443 dependent_node.dependencies--; 498 dependent_node.dependencies--;
444 // Task is ready if it has no dependencies. Add it to |ready_to_run_tasks_|. 499 // Task is ready if it has no dependencies. Add it to |ready_to_run_tasks|.
445 if (!dependent_node.dependencies) { 500 if (!dependent_node.dependencies) {
446 bool was_empty = task_namespace->ready_to_run_tasks.empty(); 501 TaskSubNamespace& dependent_sub_namespace =
447 task_namespace->ready_to_run_tasks.push_back( 502 task_namespace->sub_namespaces[dependent_node.sub_namespace];
448 PrioritizedTask(dependent_node.task, dependent_node.priority)); 503
449 std::push_heap(task_namespace->ready_to_run_tasks.begin(), 504 dependent_sub_namespace.ready_to_run_tasks.push_back(
450 task_namespace->ready_to_run_tasks.end(), 505 PrioritizedTask(dependent_node.task, dependent_node.priority,
506 dependent_node.max_concurrent_tasks));
507 std::push_heap(dependent_sub_namespace.ready_to_run_tasks.begin(),
508 dependent_sub_namespace.ready_to_run_tasks.end(),
451 CompareTaskPriority); 509 CompareTaskPriority);
452 // Task namespace is ready if it has at least one ready to run task. Add 510
453 // it to |ready_to_run_namespaces_| if it just become ready. 511 // If sub namespace became ready to run, add it to
454 if (was_empty) { 512 // |ready_to_run_sub_namespaces_|.
455 DCHECK(std::find(ready_to_run_namespaces_.begin(), 513 if (!dependent_sub_namespace.is_in_ready_sub_namespaces &&
456 ready_to_run_namespaces_.end(), 514 dependent_sub_namespace.IsReadyToRun()) {
457 task_namespace) == ready_to_run_namespaces_.end()); 515 ready_to_run_sub_namespaces_.push_back(&dependent_sub_namespace);
458 ready_to_run_namespaces_.push_back(task_namespace); 516 dependent_sub_namespace.is_in_ready_sub_namespaces = true;
459 } 517 }
460 ready_to_run_namespaces_has_heap_properties = false; 518
519 ready_to_run_sub_namespaces_has_heap_properties = false;
461 } 520 }
462 } 521 }
463 522
464 // Rearrange the task namespaces in |ready_to_run_namespaces_| in such a way 523 // Rearrange the sub namespaces in |ready_to_run_sub_namespaces_| in such a
524 // way
danakj 2015/02/23 18:45:01 wrapping
465 // that they yet again form a heap. 525 // that they yet again form a heap.
466 if (!ready_to_run_namespaces_has_heap_properties) { 526 if (!ready_to_run_sub_namespaces_has_heap_properties) {
467 std::make_heap(ready_to_run_namespaces_.begin(), 527 std::make_heap(ready_to_run_sub_namespaces_.begin(),
468 ready_to_run_namespaces_.end(), 528 ready_to_run_sub_namespaces_.end(),
469 CompareTaskNamespacePriority); 529 CompareTaskSubNamespacePriority);
470 } 530 }
471 531
472 // Finally add task to |completed_tasks_|. 532 // Finally add task to |completed_tasks_|.
473 task_namespace->completed_tasks.push_back(task); 533 task_namespace->completed_tasks.push_back(task);
474 534
475 // If namespace has finished running all tasks, wake up origin thread. 535 // If namespace has finished running all tasks, wake up origin thread.
476 if (HasFinishedRunningTasksInNamespace(task_namespace)) 536 if (HasFinishedRunningTasksInNamespace(task_namespace))
477 has_namespaces_with_finished_running_tasks_cv_.Signal(); 537 has_namespaces_with_finished_running_tasks_cv_.Signal();
478 } 538 }
479 539
480 } // namespace cc 540 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698