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

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

Issue 1449133002: TaskGraphRunner refactor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: feedback Created 5 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/raster/single_thread_task_graph_runner.h"
6
7 #include <string>
8
9 #include "base/threading/simple_thread.h"
10 #include "base/threading/thread_restrictions.h"
11 #include "base/trace_event/trace_event.h"
12
13 namespace cc {
14
15 SingleThreadTaskGraphRunner::SingleThreadTaskGraphRunner()
16 : lock_(),
17 has_ready_to_run_tasks_cv_(&lock_),
18 has_namespaces_with_finished_running_tasks_cv_(&lock_),
19 shutdown_(false) {}
20
21 SingleThreadTaskGraphRunner::~SingleThreadTaskGraphRunner() {}
22
23 void SingleThreadTaskGraphRunner::Start(
24 const std::string& thread_name,
25 const base::SimpleThread::Options& thread_options) {
26 thread_.reset(
27 new base::DelegateSimpleThread(this, thread_name, thread_options));
28 thread_->Start();
29 }
30
31 void SingleThreadTaskGraphRunner::Shutdown() {
32 {
33 base::AutoLock lock(lock_);
34
35 DCHECK(!work_queue_.HasReadyToRunTasks());
36 DCHECK(!work_queue_.HasAnyNamespaces());
37
38 DCHECK(!shutdown_);
39 shutdown_ = true;
40
41 // Wake up the worker so it knows it should exit.
42 has_ready_to_run_tasks_cv_.Signal();
43 }
44 thread_->Join();
45 }
46
47 NamespaceToken SingleThreadTaskGraphRunner::GetNamespaceToken() {
48 base::AutoLock lock(lock_);
49 return work_queue_.GetNamespaceToken();
50 }
51
52 void SingleThreadTaskGraphRunner::ScheduleTasks(NamespaceToken token,
53 TaskGraph* graph) {
54 TRACE_EVENT2("cc", "SingleThreadTaskGraphRunner::ScheduleTasks", "num_nodes",
55 graph->nodes.size(), "num_edges", graph->edges.size());
56
57 DCHECK(token.IsValid());
58 DCHECK(!TaskGraphWorkQueue::DependencyMismatch(graph));
59
60 {
61 base::AutoLock lock(lock_);
62
63 DCHECK(!shutdown_);
64
65 work_queue_.ScheduleTasks(token, graph);
66
67 // If there is more work available, wake up the worker thread.
68 if (work_queue_.HasReadyToRunTasks())
69 has_ready_to_run_tasks_cv_.Signal();
70 }
71 }
72
73 void SingleThreadTaskGraphRunner::WaitForTasksToFinishRunning(
74 NamespaceToken token) {
75 TRACE_EVENT0("cc",
76 "SingleThreadTaskGraphRunner::WaitForTasksToFinishRunning");
77
78 DCHECK(token.IsValid());
79
80 {
81 base::AutoLock lock(lock_);
82 base::ThreadRestrictions::ScopedAllowWait allow_wait;
83
84 auto* task_namespace = work_queue_.GetNamespaceForToken(token);
85
86 if (!task_namespace)
87 return;
88
89 while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace))
90 has_namespaces_with_finished_running_tasks_cv_.Wait();
91
92 // There may be other namespaces that have finished running tasks, so wake
93 // up another origin thread.
94 has_namespaces_with_finished_running_tasks_cv_.Signal();
95 }
96 }
97
98 void SingleThreadTaskGraphRunner::CollectCompletedTasks(
99 NamespaceToken token,
100 Task::Vector* completed_tasks) {
101 TRACE_EVENT0("cc", "SingleThreadTaskGraphRunner::CollectCompletedTasks");
102
103 DCHECK(token.IsValid());
104
105 {
106 base::AutoLock lock(lock_);
107 work_queue_.CollectCompletedTasks(token, completed_tasks);
108 }
109 }
110
111 void SingleThreadTaskGraphRunner::Run() {
112 base::AutoLock lock(lock_);
113
114 while (true) {
115 if (!work_queue_.HasReadyToRunTasks()) {
116 // Exit when shutdown is set and no more tasks are pending.
117 if (shutdown_)
118 break;
119
120 // Wait for more tasks.
121 has_ready_to_run_tasks_cv_.Wait();
122 continue;
123 }
124
125 RunTaskWithLockAcquired();
126 }
127 }
128
129 void SingleThreadTaskGraphRunner::RunTaskWithLockAcquired() {
130 TRACE_EVENT0("toplevel",
131 "SingleThreadTaskGraphRunner::RunTaskWithLockAcquired");
132
133 lock_.AssertAcquired();
134
135 auto prioritized_task = work_queue_.GetNextTaskToRun();
136 Task* task = prioritized_task.task;
137
138 // Call WillRun() before releasing |lock_| and running task.
139 task->WillRun();
140
141 {
142 base::AutoUnlock unlock(lock_);
143 task->RunOnWorkerThread();
144 }
145
146 // This will mark task as finished running.
147 task->DidRun();
148
149 work_queue_.CompleteTask(prioritized_task);
150
151 // If namespace has finished running all tasks, wake up origin thread.
152 if (work_queue_.HasFinishedRunningTasksInNamespace(
153 prioritized_task.task_namespace))
154 has_namespaces_with_finished_running_tasks_cv_.Signal();
155 }
156
157 } // namespace cc
OLDNEW
« no previous file with comments | « cc/raster/single_thread_task_graph_runner.h ('k') | cc/raster/single_thread_task_graph_runner_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698