| 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 |