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 "platform/assert.h" | 5 #include "platform/assert.h" |
6 #include "vm/isolate.h" | 6 #include "vm/isolate.h" |
7 #include "vm/lockers.h" | 7 #include "vm/lockers.h" |
8 #include "vm/unit_test.h" | 8 #include "vm/unit_test.h" |
9 #include "vm/profiler.h" | 9 #include "vm/profiler.h" |
10 #include "vm/safepoint.h" | 10 #include "vm/safepoint.h" |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 } | 198 } |
199 EXPECT(done[i]); | 199 EXPECT(done[i]); |
200 if (i % 10 == 0) { | 200 if (i % 10 == 0) { |
201 Thread::EnterIsolate(isolate); | 201 Thread::EnterIsolate(isolate); |
202 } | 202 } |
203 EXPECT(bar.Equals("bar")); | 203 EXPECT(bar.Equals("bar")); |
204 } | 204 } |
205 } | 205 } |
206 | 206 |
207 | 207 |
208 #ifndef RELEASE | |
209 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { | |
210 public: | |
211 SimpleTaskWithZoneAllocation(Isolate* isolate, | |
212 Thread** thread_ptr, | |
213 Monitor* sync, | |
214 Monitor* monitor, | |
215 bool* done, | |
216 bool* wait) | |
217 : isolate_(isolate), | |
218 thread_ptr_(thread_ptr), | |
219 sync_(sync), | |
220 monitor_(monitor), | |
221 done_(done), | |
222 wait_(wait) {} | |
223 | |
224 virtual void Run() { | |
225 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | |
226 { | |
227 Thread* thread = Thread::Current(); | |
228 *thread_ptr_ = thread; | |
229 | |
230 // Create a zone (which is also a stack resource) and exercise it a bit. | |
231 StackZone stack_zone(thread); | |
232 HANDLESCOPE(thread); | |
233 Zone* zone = thread->zone(); | |
234 EXPECT_EQ(zone, stack_zone.GetZone()); | |
235 ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1); | |
236 GrowableArray<bool> a1(zone, 1); | |
237 for (intptr_t i = 0; i < 100000; ++i) { | |
238 a0->Add(true); | |
239 a1.Add(true); | |
240 } | |
241 // Let the main thread know we're done with memory ops on this thread. | |
242 { | |
243 MonitorLocker ml(monitor_); | |
244 *done_ = true; | |
245 ml.Notify(); | |
246 } | |
247 // Wait for the go-ahead from the main thread to exit. | |
248 { | |
249 MonitorLocker sync_ml(sync_); | |
250 while (*wait_) { | |
251 sync_ml.Wait(); | |
252 } | |
253 } | |
254 } | |
255 Thread::ExitIsolateAsHelper(); | |
256 // Notify the main thread that this thread has exited. | |
257 { | |
258 MonitorLocker ml(monitor_); | |
259 *done_ = true; | |
260 ml.Notify(); | |
261 } | |
262 } | |
263 | |
264 private: | |
265 Isolate* isolate_; | |
266 Thread** thread_ptr_; | |
267 Monitor* sync_; | |
268 Monitor* monitor_; | |
269 Monitor* done_monitor_; | |
270 bool* done_; | |
271 bool* wait_; | |
272 }; | |
273 | |
274 | |
275 VM_TEST_CASE(ManySimpleTasksWithZones) { | |
276 const int kTaskCount = 10; | |
277 Monitor monitor[kTaskCount]; | |
278 Monitor sync; | |
279 Thread* threads[kTaskCount + 1]; | |
280 Isolate* isolate = Thread::Current()->isolate(); | |
281 bool done[kTaskCount]; | |
282 bool wait = true; | |
283 threads[kTaskCount] = Thread::Current(); | |
284 | |
285 EXPECT(isolate->heap()->GrowthControlState()); | |
286 isolate->heap()->DisableGrowthControl(); | |
287 for (int i = 0; i < kTaskCount; i++) { | |
288 done[i] = false; | |
289 Dart::thread_pool()->Run(new SimpleTaskWithZoneAllocation( | |
290 isolate, &threads[i], &sync, &monitor[i], &done[i], &wait)); | |
291 } | |
292 // Wait until all spawned tasks finish their memory operations. | |
293 for (int i = 0; i < kTaskCount; i++) { | |
294 MonitorLocker ml(&monitor[i]); | |
295 while (!done[i]) { | |
296 ml.Wait(); | |
297 } | |
298 // Reset flag to be reused later. | |
299 done[i] = false; | |
300 } | |
siva
2016/12/07 22:12:53
Why does this have to use so many monitors one for
| |
301 | |
302 JSONStream stream; | |
303 Isolate::PrintAllIsolatesMemoryInfoToJSONLocked(&stream); | |
304 const char* json = stream.ToCString(); | |
305 | |
306 // Confirm all expected entries are in the JSON output. | |
307 for (int i = 0; i < kTaskCount + 1; i++) { | |
308 Thread* thread = threads[i]; | |
309 Isolate* thread_isolate = thread->isolate(); | |
310 // Buffer can handle any possible input length given types. | |
311 char thread_address_buf[96]; | |
312 char isolate_address_buf[64]; | |
313 intptr_t thread_zone_size_total = 0; | |
314 Zone* top_zone = thread->zone(); | |
315 | |
316 // Check that all zones are present with correct sizes. | |
317 while (top_zone != NULL) { | |
318 char zone_info_buf[64]; | |
319 snprintf(zone_info_buf, sizeof(zone_info_buf), | |
320 "\"address\":\"0x%" Px "\",\"size\":%ld", | |
321 reinterpret_cast<uword>(top_zone), top_zone->SizeInBytes()); | |
322 | |
323 EXPECT_SUBSTRING(zone_info_buf, json); | |
324 thread_zone_size_total += top_zone->SizeInBytes(); | |
325 top_zone = top_zone->previous(); | |
326 } | |
327 | |
328 // Check the thread exists and is the correct size. | |
329 snprintf(thread_address_buf, sizeof(thread_address_buf), | |
330 "\"thread_address\":\"0x%" Px | |
331 "\",\"thread_zone_size_total\":\"%ld\"", | |
332 reinterpret_cast<uword>(thread), thread_zone_size_total); | |
333 | |
334 // Ensure the isolate for each thread is valid. | |
335 snprintf(isolate_address_buf, sizeof(isolate_address_buf), | |
336 "\"isolate_address\":\"0x%" Px "\"", | |
337 reinterpret_cast<uword>(thread_isolate)); | |
338 | |
339 EXPECT_SUBSTRING(thread_address_buf, json); | |
340 EXPECT_SUBSTRING(isolate_address_buf, json); | |
341 } | |
342 | |
343 // Unblock the tasks so they can finish. | |
344 { | |
345 MonitorLocker sync_ml(&sync); | |
346 wait = false; | |
347 sync_ml.NotifyAll(); | |
348 } | |
349 // Now wait for them all to exit before destroying the isolate. | |
350 for (int i = 0; i < kTaskCount; i++) { | |
351 MonitorLocker ml(&monitor[i]); | |
352 while (!done[i]) { | |
353 ml.Wait(); | |
354 } | |
355 } | |
siva
2016/12/07 22:12:53
Ditto comment about waiting for tasks to exit, cou
| |
356 } | |
357 #endif | |
358 | |
359 | |
208 TEST_CASE(ThreadRegistry) { | 360 TEST_CASE(ThreadRegistry) { |
209 Isolate* orig = Thread::Current()->isolate(); | 361 Isolate* orig = Thread::Current()->isolate(); |
210 Zone* orig_zone = Thread::Current()->zone(); | 362 Zone* orig_zone = Thread::Current()->zone(); |
211 char* orig_str = orig_zone->PrintToString("foo"); | 363 char* orig_str = orig_zone->PrintToString("foo"); |
212 Dart_ExitIsolate(); | 364 Dart_ExitIsolate(); |
213 // Create and enter a new isolate. | 365 // Create and enter a new isolate. |
214 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, | 366 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
215 NULL); | 367 NULL); |
216 Zone* zone0 = Thread::Current()->zone(); | 368 Zone* zone0 = Thread::Current()->zone(); |
217 EXPECT(zone0 != orig_zone); | 369 EXPECT(zone0 != orig_zone); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
625 TransitionVMToBlocked transition(thread); | 777 TransitionVMToBlocked transition(thread); |
626 MonitorLocker ml(&done_monitor); | 778 MonitorLocker ml(&done_monitor); |
627 if (done) { | 779 if (done) { |
628 break; | 780 break; |
629 } | 781 } |
630 } | 782 } |
631 } | 783 } |
632 } | 784 } |
633 | 785 |
634 } // namespace dart | 786 } // namespace dart |
OLD | NEW |