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

Side by Side Diff: runtime/vm/thread_pool_test.cc

Issue 1270323002: Revert VM thread cleanup (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « runtime/vm/thread_pool.cc ('k') | runtime/vm/verified_memory_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 class ThreadPoolTestPeer {
16 public:
17 // When the pool has an exit monitor, workers notify a monitor just
18 // before they exit. This is only used in tests to make sure that
19 // Shutdown works.
20 static void SetExitMonitor(Monitor* exit_monitor, int* exit_count) {
21 ThreadPool::exit_monitor_ = exit_monitor;
22 ThreadPool::exit_count_ = exit_count;
23 }
24 };
25
26
15 UNIT_TEST_CASE(ThreadPool_Create) { 27 UNIT_TEST_CASE(ThreadPool_Create) {
16 ThreadPool thread_pool; 28 ThreadPool thread_pool;
17 } 29 }
18 30
19 31
20 class TestTask : public ThreadPool::Task { 32 class TestTask : public ThreadPool::Task {
21 public: 33 public:
22 TestTask(Monitor* sync, bool* done) 34 TestTask(Monitor* sync, bool* done)
23 : sync_(sync), done_(done) { 35 : sync_(sync), done_(done) {
24 } 36 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 while (!done[i]) { 81 while (!done[i]) {
70 ml.Wait(); 82 ml.Wait();
71 } 83 }
72 EXPECT(done[i]); 84 EXPECT(done[i]);
73 } 85 }
74 } 86 }
75 87
76 88
77 class SleepTask : public ThreadPool::Task { 89 class SleepTask : public ThreadPool::Task {
78 public: 90 public:
79 explicit SleepTask( 91 explicit SleepTask(int millis)
80 Monitor* sync, int* started_count, int* slept_count, int millis) 92 : millis_(millis) {
81 : sync_(sync),
82 started_count_(started_count),
83 slept_count_(slept_count),
84 millis_(millis) {
85 } 93 }
86 94
87 virtual void Run() { 95 virtual void Run() {
88 {
89 MonitorLocker ml(sync_);
90 *started_count_ = *started_count_ + 1;
91 ml.Notify();
92 }
93 // Sleep so we can be sure the ThreadPool destructor blocks until we're
94 // done.
95 OS::Sleep(millis_); 96 OS::Sleep(millis_);
96 {
97 MonitorLocker ml(sync_);
98 *slept_count_ = *slept_count_ + 1;
99 // No notification here. The main thread is blocked in ThreadPool
100 // shutdown waiting for this thread to finish.
101 }
102 } 97 }
103 98
104 private: 99 private:
105 Monitor* sync_;
106 int* started_count_;
107 int* slept_count_;
108 int millis_; 100 int millis_;
109 }; 101 };
110 102
111 103
112 UNIT_TEST_CASE(ThreadPool_WorkerShutdown) { 104 UNIT_TEST_CASE(ThreadPool_WorkerShutdown) {
113 const int kTaskCount = 10; 105 Monitor exit_sync;
114 Monitor sync; 106 int exit_count = 0;
115 int slept_count = 0; 107 MonitorLocker ml(&exit_sync);
116 int started_count = 0;
117 108
118 // Set up the ThreadPool so that workers notify before they exit. 109 // Set up the ThreadPool so that workers notify before they exit.
119 ThreadPool* thread_pool = new ThreadPool(); 110 ThreadPool* thread_pool = new ThreadPool();
111 ThreadPoolTestPeer::SetExitMonitor(&exit_sync, &exit_count);
120 112
121 // Run a single task. 113 // Run a single task.
122 for (int i = 0; i < kTaskCount; i++) { 114 thread_pool->Run(new SleepTask(2));
123 thread_pool->Run(new SleepTask(&sync, &started_count, &slept_count, 2));
124 }
125 115
126 { 116 // Kill the thread pool.
127 // Wait for everybody to start.
128 MonitorLocker ml(&sync);
129 while (started_count < kTaskCount) {
130 ml.Wait();
131 }
132 }
133
134 // Kill the thread pool while the workers are sleeping.
135 delete thread_pool; 117 delete thread_pool;
136 thread_pool = NULL; 118 thread_pool = NULL;
137 119
138 int final_count = 0; 120 // Wait for the workers to terminate.
139 { 121 while (exit_count == 0) {
140 MonitorLocker ml(&sync); 122 ml.Wait();
141 final_count = slept_count;
142 } 123 }
143 124 EXPECT_EQ(1, exit_count);
144 // We should have waited for all the workers to finish, so they all should
145 // have had a chance to increment slept_count.
146 EXPECT_EQ(kTaskCount, final_count);
147 } 125 }
148 126
149 127
150 UNIT_TEST_CASE(ThreadPool_WorkerTimeout) { 128 UNIT_TEST_CASE(ThreadPool_WorkerTimeout) {
151 // Adjust the worker timeout so that we timeout quickly. 129 // Adjust the worker timeout so that we timeout quickly.
152 int saved_timeout = FLAG_worker_timeout_millis; 130 int saved_timeout = FLAG_worker_timeout_millis;
153 FLAG_worker_timeout_millis = 1; 131 FLAG_worker_timeout_millis = 1;
154 132
155 ThreadPool thread_pool; 133 ThreadPool thread_pool;
156 EXPECT_EQ(0U, thread_pool.workers_started()); 134 EXPECT_EQ(0U, thread_pool.workers_started());
(...skipping 30 matching lines...) Expand all
187 SpawnTask(ThreadPool* pool, Monitor* sync, int todo, int total, int* done) 165 SpawnTask(ThreadPool* pool, Monitor* sync, int todo, int total, int* done)
188 : pool_(pool), sync_(sync), todo_(todo), total_(total), done_(done) { 166 : pool_(pool), sync_(sync), todo_(todo), total_(total), done_(done) {
189 } 167 }
190 168
191 virtual void Run() { 169 virtual void Run() {
192 todo_--; // Subtract one for current task. 170 todo_--; // Subtract one for current task.
193 int child_todo = todo_ / 2; 171 int child_todo = todo_ / 2;
194 172
195 // Spawn 0-2 children. 173 // Spawn 0-2 children.
196 if (todo_ > 0) { 174 if (todo_ > 0) {
197 pool_->Run(new SpawnTask( 175 pool_->Run(
198 pool_, sync_, todo_ - child_todo, total_, done_)); 176 new SpawnTask(pool_, sync_, todo_ - child_todo, total_, done_));
199 } 177 }
200 if (todo_ > 1) { 178 if (todo_ > 1) {
201 pool_->Run(new SpawnTask(pool_, sync_, child_todo, total_, done_)); 179 pool_->Run(
180 new SpawnTask(pool_, sync_, child_todo, total_, done_));
202 } 181 }
203 182
204 { 183 {
205 MonitorLocker ml(sync_); 184 MonitorLocker ml(sync_);
206 (*done_)++; 185 (*done_)++;
207 if (*done_ >= total_) { 186 if (*done_ >= total_) {
208 ml.Notify(); 187 ml.Notify();
209 } 188 }
210 } 189 }
211 } 190 }
(...skipping 16 matching lines...) Expand all
228 new SpawnTask(&thread_pool, &sync, kTotalTasks, kTotalTasks, &done)); 207 new SpawnTask(&thread_pool, &sync, kTotalTasks, kTotalTasks, &done));
229 { 208 {
230 MonitorLocker ml(&sync); 209 MonitorLocker ml(&sync);
231 while (done < kTotalTasks) { 210 while (done < kTotalTasks) {
232 ml.Wait(); 211 ml.Wait();
233 } 212 }
234 } 213 }
235 EXPECT_EQ(kTotalTasks, done); 214 EXPECT_EQ(kTotalTasks, done);
236 } 215 }
237 216
217
238 } // namespace dart 218 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/thread_pool.cc ('k') | runtime/vm/verified_memory_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698