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 #if defined(DEBUG) | |
zra
2016/12/08 18:54:13
ditto
bkonyi
2016/12/08 20:58:32
Done.
| |
209 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { | |
210 public: | |
211 SimpleTaskWithZoneAllocation(intptr_t id, | |
212 Isolate* isolate, | |
213 Thread** thread_ptr, | |
214 Monitor* sync, | |
215 Monitor* monitor, | |
216 intptr_t* done_count, | |
217 bool* wait) | |
218 : id_(id), | |
219 isolate_(isolate), | |
220 thread_ptr_(thread_ptr), | |
221 sync_(sync), | |
222 monitor_(monitor), | |
223 done_count_(done_count), | |
224 wait_(wait) {} | |
225 | |
226 virtual void Run() { | |
227 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | |
228 { | |
229 Thread* thread = Thread::Current(); | |
230 *thread_ptr_ = thread; | |
231 CreateStackZones(id_); | |
232 } | |
233 Thread::ExitIsolateAsHelper(); | |
234 // Notify the main thread that this thread has exited. | |
235 { | |
236 MonitorLocker ml(monitor_); | |
237 *done_count_ += 1; | |
238 ml.Notify(); | |
239 } | |
240 } | |
241 | |
242 private: | |
243 void CreateStackZones(intptr_t num) { | |
244 Thread* thread = Thread::Current(); | |
245 *thread_ptr_ = thread; | |
246 | |
247 StackZone stack_zone(thread); | |
248 HANDLESCOPE(thread); | |
249 Zone* zone = thread->zone(); | |
250 EXPECT_EQ(zone, stack_zone.GetZone()); | |
251 | |
252 // Create a zone (which is also a stack resource) and exercise it a bit. | |
253 ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1); | |
254 GrowableArray<bool> a1(zone, 1); | |
255 for (intptr_t i = 0; i < 1000 * num + id_; ++i) { | |
256 a0->Add(true); | |
257 a1.Add(true); | |
258 } | |
259 | |
260 num -= 1; | |
261 if (num != 0) { | |
262 CreateStackZones(num); | |
263 return; | |
264 } | |
265 { | |
266 // Let the main thread know we're done with memory ops on this thread. | |
267 MonitorLocker ml(monitor_); | |
268 *done_count_ += 1; | |
269 ml.Notify(); | |
270 } | |
271 // Wait for the go-ahead from the main thread to exit. | |
272 { | |
273 MonitorLocker sync_ml(sync_); | |
274 while (*wait_) { | |
275 sync_ml.Wait(); | |
276 } | |
277 } | |
278 } | |
zra
2016/12/08 18:54:13
missing newline.
bkonyi
2016/12/08 20:58:32
Done.
| |
279 intptr_t id_; | |
280 Isolate* isolate_; | |
281 Thread** thread_ptr_; | |
282 Monitor* sync_; | |
283 Monitor* monitor_; | |
284 intptr_t* done_count_; | |
285 bool* wait_; | |
286 }; | |
287 | |
288 | |
289 TEST_CASE(ManySimpleTasksWithZones) { | |
290 const int kTaskCount = 10; | |
291 Monitor monitor; | |
292 Monitor sync; | |
293 Thread* threads[kTaskCount + 1]; | |
294 Isolate* isolate = Thread::Current()->isolate(); | |
295 intptr_t done_count = 0; | |
296 bool wait = true; | |
297 threads[kTaskCount] = Thread::Current(); | |
298 | |
299 EXPECT(isolate->heap()->GrowthControlState()); | |
300 isolate->heap()->DisableGrowthControl(); | |
301 for (int i = 0; i < kTaskCount; i++) { | |
zra
2016/12/08 18:54:13
intptr_t i
bkonyi
2016/12/08 20:58:32
Done.
| |
302 Dart::thread_pool()->Run(new SimpleTaskWithZoneAllocation( | |
303 (i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait)); | |
304 } | |
305 // Wait until all spawned tasks finish their memory operations. | |
306 { | |
307 MonitorLocker ml(&monitor); | |
308 while (done_count < kTaskCount) { | |
309 ml.Wait(); | |
310 } | |
311 // Reset the done counter for use later. | |
312 done_count = 0; | |
313 } | |
314 | |
315 JSONStream stream; | |
316 Service::PrintJSONForVM(&stream, false); | |
317 const char* json = stream.ToCString(); | |
318 | |
319 // Confirm all expected entries are in the JSON output. | |
320 for (int i = 0; i < kTaskCount + 1; i++) { | |
zra
2016/12/08 18:54:13
intptr_t i
bkonyi
2016/12/08 20:58:32
Done.
| |
321 Thread* thread = threads[i]; | |
322 Isolate* thread_isolate = thread->isolate(); | |
323 // Buffer can handle any possible input length given types. | |
324 char thread_address_buf[96]; | |
325 char isolate_address_buf[64]; | |
326 Zone* top_zone = thread->zone(); | |
327 | |
328 // Check that all zones are present with correct sizes. | |
329 while (top_zone != NULL) { | |
330 char zone_info_buf[96]; | |
331 OS::SNPrint(zone_info_buf, sizeof(zone_info_buf), | |
332 "\"type\":\"_Zone\"," | |
333 "\"capacity\":%ld," | |
334 "\"used\":%ld", | |
335 top_zone->SizeInBytes(), top_zone->UsedSizeInBytes()); | |
336 | |
337 EXPECT_SUBSTRING(zone_info_buf, json); | |
338 top_zone = top_zone->previous(); | |
339 } | |
340 | |
341 // Check the thread exists and is the correct size. | |
342 OS::SNPrint(thread_address_buf, sizeof(thread_address_buf), | |
343 "\"type\":\"_Thread\"," | |
344 "\"id\":\"threads\\/%" Pd64 "", | |
345 thread->os_thread()->trace_id()); | |
346 | |
347 // Ensure the isolate for each thread is valid. | |
348 OS::SNPrint(isolate_address_buf, sizeof(isolate_address_buf), | |
349 "\"type\":\"Isolate\"," | |
350 "\"fixedId\":true," | |
351 "\"id\":\"isolates\\/%" Pd64 "", | |
352 static_cast<int64_t>(thread_isolate->main_port())); | |
353 | |
354 EXPECT_SUBSTRING(thread_address_buf, json); | |
355 EXPECT_SUBSTRING(isolate_address_buf, json); | |
356 } | |
357 | |
358 // Unblock the tasks so they can finish. | |
359 { | |
360 MonitorLocker sync_ml(&sync); | |
361 wait = false; | |
362 sync_ml.NotifyAll(); | |
363 } | |
364 // Now wait for them all to exit before destroying the isolate. | |
365 { | |
366 MonitorLocker ml(&monitor); | |
367 while (done_count < kTaskCount) { | |
368 ml.Wait(); | |
369 } | |
370 } | |
371 } | |
372 #endif | |
373 | |
374 | |
208 TEST_CASE(ThreadRegistry) { | 375 TEST_CASE(ThreadRegistry) { |
209 Isolate* orig = Thread::Current()->isolate(); | 376 Isolate* orig = Thread::Current()->isolate(); |
210 Zone* orig_zone = Thread::Current()->zone(); | 377 Zone* orig_zone = Thread::Current()->zone(); |
211 char* orig_str = orig_zone->PrintToString("foo"); | 378 char* orig_str = orig_zone->PrintToString("foo"); |
212 Dart_ExitIsolate(); | 379 Dart_ExitIsolate(); |
213 // Create and enter a new isolate. | 380 // Create and enter a new isolate. |
214 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, | 381 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
215 NULL); | 382 NULL); |
216 Zone* zone0 = Thread::Current()->zone(); | 383 Zone* zone0 = Thread::Current()->zone(); |
217 EXPECT(zone0 != orig_zone); | 384 EXPECT(zone0 != orig_zone); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
625 TransitionVMToBlocked transition(thread); | 792 TransitionVMToBlocked transition(thread); |
626 MonitorLocker ml(&done_monitor); | 793 MonitorLocker ml(&done_monitor); |
627 if (done) { | 794 if (done) { |
628 break; | 795 break; |
629 } | 796 } |
630 } | 797 } |
631 } | 798 } |
632 } | 799 } |
633 | 800 |
634 } // namespace dart | 801 } // namespace dart |
OLD | NEW |