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

Side by Side Diff: cc/base/worker_pool_perftest.cc

Issue 14689004: Re-land: cc: Cancel and re-prioritize worker pool tasks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Check and prevent worker pool reentrancy during dispatch of completion callbacks Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « cc/base/worker_pool.cc ('k') | cc/base/worker_pool_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
(Empty)
1 // Copyright 2013 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/base/worker_pool.h"
6
7 #include "base/time.h"
8 #include "cc/base/completion_event.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace cc {
12
13 namespace {
14
15 static const int kTimeLimitMillis = 2000;
16 static const int kWarmupRuns = 5;
17 static const int kTimeCheckInterval = 10;
18
19 class PerfTaskImpl : public internal::WorkerPoolTask {
20 public:
21 explicit PerfTaskImpl(internal::WorkerPoolTask::TaskVector* dependencies)
22 : internal::WorkerPoolTask(dependencies) {}
23
24 // Overridden from internal::WorkerPoolTask:
25 virtual void RunOnThread(unsigned thread_index) OVERRIDE {}
26 virtual void DispatchCompletionCallback() OVERRIDE {}
27
28 private:
29 virtual ~PerfTaskImpl() {}
30 };
31
32 class PerfControlTaskImpl : public internal::WorkerPoolTask {
33 public:
34 explicit PerfControlTaskImpl(
35 internal::WorkerPoolTask::TaskVector* dependencies)
36 : internal::WorkerPoolTask(dependencies),
37 did_start_(new CompletionEvent),
38 can_finish_(new CompletionEvent) {}
39
40 // Overridden from internal::WorkerPoolTask:
41 virtual void RunOnThread(unsigned thread_index) OVERRIDE {
42 did_start_->Signal();
43 can_finish_->Wait();
44 }
45 virtual void DispatchCompletionCallback() OVERRIDE {}
46
47 void WaitForTaskToStartRunning() {
48 did_start_->Wait();
49 }
50
51 void AllowTaskToFinish() {
52 can_finish_->Signal();
53 }
54
55 private:
56 virtual ~PerfControlTaskImpl() {}
57
58 scoped_ptr<CompletionEvent> did_start_;
59 scoped_ptr<CompletionEvent> can_finish_;
60 };
61
62 class PerfWorkerPool : public WorkerPool {
63 public:
64 PerfWorkerPool() : WorkerPool(1, base::TimeDelta::FromDays(1024), "test") {}
65 virtual ~PerfWorkerPool() {}
66
67 static scoped_ptr<PerfWorkerPool> Create() {
68 return make_scoped_ptr(new PerfWorkerPool);
69 }
70
71 void ScheduleTasks(internal::WorkerPoolTask* root) {
72 WorkerPool::ScheduleTasks(root);
73 }
74 };
75
76 class WorkerPoolPerfTest : public testing::Test,
77 public WorkerPoolClient {
78 public:
79 WorkerPoolPerfTest() : num_runs_(0) {}
80
81 // Overridden from testing::Test:
82 virtual void SetUp() OVERRIDE {
83 worker_pool_ = PerfWorkerPool::Create();
84 worker_pool_->SetClient(this);
85 }
86 virtual void TearDown() OVERRIDE {
87 worker_pool_->Shutdown();
88 }
89
90 // Overridden from WorkerPoolClient:
91 virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() OVERRIDE {}
92
93 void EndTest() {
94 elapsed_ = base::TimeTicks::HighResNow() - start_time_;
95 }
96
97 void AfterTest(const std::string test_name) {
98 // Format matches chrome/test/perf/perf_test.h:PrintResult
99 printf("*RESULT %s: %.2f runs/s\n",
100 test_name.c_str(),
101 num_runs_ / elapsed_.InSecondsF());
102 }
103
104 void BuildTaskGraph(internal::WorkerPoolTask::TaskVector* dependencies,
105 unsigned current_depth,
106 unsigned max_depth,
107 unsigned num_children_per_node) {
108 internal::WorkerPoolTask::TaskVector children;
109 if (current_depth < max_depth) {
110 for (unsigned i = 0; i < num_children_per_node; ++i) {
111 BuildTaskGraph(&children,
112 current_depth + 1,
113 max_depth,
114 num_children_per_node);
115 }
116 } else if (leaf_task_) {
117 children.push_back(leaf_task_);
118 }
119 dependencies->push_back(make_scoped_refptr(new PerfTaskImpl(&children)));
120 }
121
122 bool DidRun() {
123 ++num_runs_;
124 if (num_runs_ == kWarmupRuns)
125 start_time_ = base::TimeTicks::HighResNow();
126
127 if (!start_time_.is_null() && (num_runs_ % kTimeCheckInterval) == 0) {
128 base::TimeDelta elapsed = base::TimeTicks::HighResNow() - start_time_;
129 if (elapsed >= base::TimeDelta::FromMilliseconds(kTimeLimitMillis)) {
130 elapsed_ = elapsed;
131 return false;
132 }
133 }
134
135 return true;
136 }
137
138 void RunBuildTaskGraphTest(const std::string test_name,
139 unsigned max_depth,
140 unsigned num_children_per_node) {
141 start_time_ = base::TimeTicks();
142 num_runs_ = 0;
143 do {
144 internal::WorkerPoolTask::TaskVector children;
145 BuildTaskGraph(&children, 0, max_depth, num_children_per_node);
146 } while (DidRun());
147
148 AfterTest(test_name);
149 }
150
151 void RunScheduleTasksTest(const std::string test_name,
152 unsigned max_depth,
153 unsigned num_children_per_node) {
154 start_time_ = base::TimeTicks();
155 num_runs_ = 0;
156 do {
157 internal::WorkerPoolTask::TaskVector empty;
158 leaf_task_ = make_scoped_refptr(new PerfControlTaskImpl(&empty));
159 internal::WorkerPoolTask::TaskVector children;
160 BuildTaskGraph(&children, 0, max_depth, num_children_per_node);
161 scoped_refptr<PerfTaskImpl> root_task(
162 make_scoped_refptr(new PerfTaskImpl(&children)));
163
164 worker_pool_->ScheduleTasks(root_task);
165 leaf_task_->WaitForTaskToStartRunning();
166 worker_pool_->ScheduleTasks(NULL);
167 worker_pool_->CheckForCompletedTasks();
168 leaf_task_->AllowTaskToFinish();
169 } while (DidRun());
170
171 AfterTest(test_name);
172 }
173
174 void RunExecuteTasksTest(const std::string test_name,
175 unsigned max_depth,
176 unsigned num_children_per_node) {
177 start_time_ = base::TimeTicks();
178 num_runs_ = 0;
179 do {
180 internal::WorkerPoolTask::TaskVector children;
181 BuildTaskGraph(&children, 0, max_depth, num_children_per_node);
182 scoped_refptr<PerfControlTaskImpl> root_task(
183 make_scoped_refptr(new PerfControlTaskImpl(&children)));
184
185 worker_pool_->ScheduleTasks(root_task);
186 root_task->WaitForTaskToStartRunning();
187 root_task->AllowTaskToFinish();
188 worker_pool_->CheckForCompletedTasks();
189 } while (DidRun());
190
191 AfterTest(test_name);
192 }
193
194 protected:
195 scoped_ptr<PerfWorkerPool> worker_pool_;
196 scoped_refptr<PerfControlTaskImpl> leaf_task_;
197 base::TimeTicks start_time_;
198 base::TimeDelta elapsed_;
199 int num_runs_;
200 };
201
202 TEST_F(WorkerPoolPerfTest, BuildTaskGraph) {
203 RunBuildTaskGraphTest("build_task_graph_1_10", 1, 10);
204 RunBuildTaskGraphTest("build_task_graph_1_1000", 1, 1000);
205 RunBuildTaskGraphTest("build_task_graph_2_10", 2, 10);
206 RunBuildTaskGraphTest("build_task_graph_5_5", 5, 5);
207 RunBuildTaskGraphTest("build_task_graph_10_2", 10, 2);
208 RunBuildTaskGraphTest("build_task_graph_1000_1", 1000, 1);
209 RunBuildTaskGraphTest("build_task_graph_10_1", 10, 1);
210 }
211
212 TEST_F(WorkerPoolPerfTest, ScheduleTasks) {
213 RunScheduleTasksTest("schedule_tasks_1_10", 1, 10);
214 RunScheduleTasksTest("schedule_tasks_1_1000", 1, 1000);
215 RunScheduleTasksTest("schedule_tasks_2_10", 2, 10);
216 RunScheduleTasksTest("schedule_tasks_5_5", 5, 5);
217 RunScheduleTasksTest("schedule_tasks_10_2", 10, 2);
218 RunScheduleTasksTest("schedule_tasks_1000_1", 1000, 1);
219 RunScheduleTasksTest("schedule_tasks_10_1", 10, 1);
220 }
221
222 TEST_F(WorkerPoolPerfTest, ExecuteTasks) {
223 RunExecuteTasksTest("execute_tasks_1_10", 1, 10);
224 RunExecuteTasksTest("execute_tasks_1_1000", 1, 1000);
225 RunExecuteTasksTest("execute_tasks_2_10", 2, 10);
226 RunExecuteTasksTest("execute_tasks_5_5", 5, 5);
227 RunExecuteTasksTest("execute_tasks_10_2", 10, 2);
228 RunExecuteTasksTest("execute_tasks_1000_1", 1000, 1);
229 RunExecuteTasksTest("execute_tasks_10_1", 10, 1);
230 }
231
232 } // namespace
233
234 } // namespace cc
OLDNEW
« no previous file with comments | « cc/base/worker_pool.cc ('k') | cc/base/worker_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698