OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/os.h" | 5 #include "vm/os.h" |
6 #include "vm/lockers.h" | 6 #include "vm/lockers.h" |
7 #include "vm/thread_pool.h" | 7 #include "vm/thread_pool.h" |
8 #include "vm/unit_test.h" | 8 #include "vm/unit_test.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
11 | 11 |
12 DECLARE_FLAG(int, worker_timeout_millis); | 12 DECLARE_FLAG(int, worker_timeout_millis); |
13 | 13 |
14 | 14 |
15 UNIT_TEST_CASE(ThreadPool_Create) { | 15 UNIT_TEST_CASE(ThreadPool_Create) { |
16 ThreadPool thread_pool; | 16 ThreadPool thread_pool; |
17 } | 17 } |
18 | 18 |
19 | 19 |
20 class TestTask : public ThreadPool::Task { | 20 class TestTask : public ThreadPool::Task { |
21 public: | 21 public: |
22 TestTask(Monitor* sync, bool* done) | 22 TestTask(Monitor* sync, bool* done) : sync_(sync), done_(done) {} |
23 : sync_(sync), done_(done) { | |
24 } | |
25 | 23 |
26 // Before running the task, *done_ should be true. This lets the caller | 24 // Before running the task, *done_ should be true. This lets the caller |
27 // ASSERT things knowing that the thread is still around. To unblock the | 25 // ASSERT things knowing that the thread is still around. To unblock the |
28 // thread, the caller should take the lock, set *done_ to false, and Notify() | 26 // thread, the caller should take the lock, set *done_ to false, and Notify() |
29 // the monitor. | 27 // the monitor. |
30 virtual void Run() { | 28 virtual void Run() { |
31 { | 29 { |
32 MonitorLocker ml(sync_); | 30 MonitorLocker ml(sync_); |
33 while (*done_) { | 31 while (*done_) { |
34 ml.Wait(); | 32 ml.Wait(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 } | 85 } |
88 } | 86 } |
89 | 87 |
90 | 88 |
91 class SleepTask : public ThreadPool::Task { | 89 class SleepTask : public ThreadPool::Task { |
92 public: | 90 public: |
93 SleepTask(Monitor* sync, int* started_count, int* slept_count, int millis) | 91 SleepTask(Monitor* sync, int* started_count, int* slept_count, int millis) |
94 : sync_(sync), | 92 : sync_(sync), |
95 started_count_(started_count), | 93 started_count_(started_count), |
96 slept_count_(slept_count), | 94 slept_count_(slept_count), |
97 millis_(millis) { | 95 millis_(millis) {} |
98 } | |
99 | 96 |
100 virtual void Run() { | 97 virtual void Run() { |
101 { | 98 { |
102 MonitorLocker ml(sync_); | 99 MonitorLocker ml(sync_); |
103 *started_count_ = *started_count_ + 1; | 100 *started_count_ = *started_count_ + 1; |
104 ml.Notify(); | 101 ml.Notify(); |
105 } | 102 } |
106 // Sleep so we can be sure the ThreadPool destructor blocks until we're | 103 // Sleep so we can be sure the ThreadPool destructor blocks until we're |
107 // done. | 104 // done. |
108 OS::Sleep(millis_); | 105 OS::Sleep(millis_); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 waited += 1; | 190 waited += 1; |
194 } | 191 } |
195 EXPECT_EQ(1U, thread_pool.workers_stopped()); | 192 EXPECT_EQ(1U, thread_pool.workers_stopped()); |
196 FLAG_worker_timeout_millis = saved_timeout; | 193 FLAG_worker_timeout_millis = saved_timeout; |
197 } | 194 } |
198 | 195 |
199 | 196 |
200 class SpawnTask : public ThreadPool::Task { | 197 class SpawnTask : public ThreadPool::Task { |
201 public: | 198 public: |
202 SpawnTask(ThreadPool* pool, Monitor* sync, int todo, int total, int* done) | 199 SpawnTask(ThreadPool* pool, Monitor* sync, int todo, int total, int* done) |
203 : pool_(pool), sync_(sync), todo_(todo), total_(total), done_(done) { | 200 : pool_(pool), sync_(sync), todo_(todo), total_(total), done_(done) {} |
204 } | |
205 | 201 |
206 virtual void Run() { | 202 virtual void Run() { |
207 todo_--; // Subtract one for current task. | 203 todo_--; // Subtract one for current task. |
208 int child_todo = todo_ / 2; | 204 int child_todo = todo_ / 2; |
209 | 205 |
210 // Spawn 0-2 children. | 206 // Spawn 0-2 children. |
211 if (todo_ > 0) { | 207 if (todo_ > 0) { |
212 pool_->Run(new SpawnTask( | 208 pool_->Run( |
213 pool_, sync_, todo_ - child_todo, total_, done_)); | 209 new SpawnTask(pool_, sync_, todo_ - child_todo, total_, done_)); |
214 } | 210 } |
215 if (todo_ > 1) { | 211 if (todo_ > 1) { |
216 pool_->Run(new SpawnTask(pool_, sync_, child_todo, total_, done_)); | 212 pool_->Run(new SpawnTask(pool_, sync_, child_todo, total_, done_)); |
217 } | 213 } |
218 | 214 |
219 { | 215 { |
220 MonitorLocker ml(sync_); | 216 MonitorLocker ml(sync_); |
221 (*done_)++; | 217 (*done_)++; |
222 if (*done_ >= total_) { | 218 if (*done_ >= total_) { |
223 ml.Notify(); | 219 ml.Notify(); |
(...skipping 20 matching lines...) Expand all Loading... |
244 { | 240 { |
245 MonitorLocker ml(&sync); | 241 MonitorLocker ml(&sync); |
246 while (done < kTotalTasks) { | 242 while (done < kTotalTasks) { |
247 ml.Wait(); | 243 ml.Wait(); |
248 } | 244 } |
249 } | 245 } |
250 EXPECT_EQ(kTotalTasks, done); | 246 EXPECT_EQ(kTotalTasks, done); |
251 } | 247 } |
252 | 248 |
253 } // namespace dart | 249 } // namespace dart |
OLD | NEW |