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" |
| 11 #include "vm/stack_frame.h" |
10 #include "vm/thread_pool.h" | 12 #include "vm/thread_pool.h" |
11 #include "vm/thread_registry.h" | |
12 | 13 |
13 namespace dart { | 14 namespace dart { |
14 | 15 |
15 UNIT_TEST_CASE(Mutex) { | 16 UNIT_TEST_CASE(Mutex) { |
16 // This unit test case needs a running isolate. | 17 // This unit test case needs a running isolate. |
17 Dart_CreateIsolate( | 18 Dart_CreateIsolate( |
18 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 19 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); |
19 | 20 |
20 Mutex* mutex = new Mutex(); | 21 Mutex* mutex = new Mutex(); |
21 mutex->Lock(); | 22 mutex->Lock(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } | 166 } |
166 | 167 |
167 private: | 168 private: |
168 Isolate* isolate_; | 169 Isolate* isolate_; |
169 Monitor* monitor_; | 170 Monitor* monitor_; |
170 bool* done_; | 171 bool* done_; |
171 intptr_t id_; | 172 intptr_t id_; |
172 }; | 173 }; |
173 | 174 |
174 | 175 |
175 TEST_CASE(ManyTasksWithZones) { | 176 VM_TEST_CASE(ManyTasksWithZones) { |
176 const int kTaskCount = 100; | 177 const int kTaskCount = 100; |
177 Monitor sync[kTaskCount]; | 178 Monitor sync[kTaskCount]; |
178 bool done[kTaskCount]; | 179 bool done[kTaskCount]; |
179 Isolate* isolate = Thread::Current()->isolate(); | 180 Isolate* isolate = Thread::Current()->isolate(); |
180 EXPECT(isolate->heap()->GrowthControlState()); | 181 EXPECT(isolate->heap()->GrowthControlState()); |
181 isolate->heap()->DisableGrowthControl(); | 182 isolate->heap()->DisableGrowthControl(); |
182 for (int i = 0; i < kTaskCount; i++) { | 183 for (int i = 0; i < kTaskCount; i++) { |
183 done[i] = false; | 184 done[i] = false; |
184 Dart::thread_pool()->Run( | 185 Dart::thread_pool()->Run( |
185 new TaskWithZoneAllocation(isolate, &sync[i], &done[i], i)); | 186 new TaskWithZoneAllocation(isolate, &sync[i], &done[i], i)); |
(...skipping 15 matching lines...) Expand all Loading... |
201 } | 202 } |
202 EXPECT(bar.Equals("bar")); | 203 EXPECT(bar.Equals("bar")); |
203 } | 204 } |
204 } | 205 } |
205 | 206 |
206 | 207 |
207 TEST_CASE(ThreadRegistry) { | 208 TEST_CASE(ThreadRegistry) { |
208 Isolate* orig = Thread::Current()->isolate(); | 209 Isolate* orig = Thread::Current()->isolate(); |
209 Zone* orig_zone = Thread::Current()->zone(); | 210 Zone* orig_zone = Thread::Current()->zone(); |
210 char* orig_str = orig_zone->PrintToString("foo"); | 211 char* orig_str = orig_zone->PrintToString("foo"); |
211 Thread::ExitIsolate(); | 212 Dart_ExitIsolate(); |
212 // Create and enter a new isolate. | 213 // Create and enter a new isolate. |
213 Dart_CreateIsolate( | 214 Dart_CreateIsolate( |
214 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 215 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); |
215 Zone* zone0 = Thread::Current()->zone(); | 216 Zone* zone0 = Thread::Current()->zone(); |
216 EXPECT(zone0 != orig_zone); | 217 EXPECT(zone0 != orig_zone); |
217 Dart_ShutdownIsolate(); | 218 Dart_ShutdownIsolate(); |
218 // Create and enter yet another isolate. | 219 // Create and enter yet another isolate. |
219 Dart_CreateIsolate( | 220 Dart_CreateIsolate( |
220 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 221 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); |
221 { | 222 { |
222 // Create a stack resource this time, and exercise it. | 223 // Create a stack resource this time, and exercise it. |
223 StackZone stack_zone(Thread::Current()); | 224 StackZone stack_zone(Thread::Current()); |
224 Zone* zone1 = Thread::Current()->zone(); | 225 Zone* zone1 = Thread::Current()->zone(); |
225 EXPECT(zone1 != zone0); | 226 EXPECT(zone1 != zone0); |
226 EXPECT(zone1 != orig_zone); | 227 EXPECT(zone1 != orig_zone); |
227 } | 228 } |
228 Dart_ShutdownIsolate(); | 229 Dart_ShutdownIsolate(); |
229 Thread::EnterIsolate(orig); | 230 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig)); |
230 // Original zone should be preserved. | 231 // Original zone should be preserved. |
231 EXPECT_EQ(orig_zone, Thread::Current()->zone()); | 232 EXPECT_EQ(orig_zone, Thread::Current()->zone()); |
232 EXPECT_STREQ("foo", orig_str); | 233 EXPECT_STREQ("foo", orig_str); |
233 } | 234 } |
234 | 235 |
235 | 236 |
236 // A helper thread that alternatingly cooperates and organizes | 237 // A helper thread that alternatingly cooperates and organizes |
237 // safepoint rendezvous. At rendezvous, it explicitly visits the | 238 // safepoint rendezvous. At rendezvous, it explicitly visits the |
238 // stacks looking for a specific marker (Smi) to verify that the expected | 239 // stacks looking for a specific marker (Smi) to verify that the expected |
239 // number threads are actually visited. The task is "done" when it has | 240 // number threads are actually visited. The task is "done" when it has |
240 // successfully made all other tasks and the main thread rendezvous (may | 241 // successfully made all other tasks and the main thread rendezvous (may |
241 // not happen in the first rendezvous, since tasks are still starting up). | 242 // not happen in the first rendezvous, since tasks are still starting up). |
242 class SafepointTestTask : public ThreadPool::Task { | 243 class SafepointTestTask : public ThreadPool::Task { |
243 public: | 244 public: |
244 static const intptr_t kTaskCount; | 245 static const intptr_t kTaskCount; |
245 | 246 |
246 SafepointTestTask(Isolate* isolate, | 247 SafepointTestTask(Isolate* isolate, |
247 Mutex* mutex, | 248 Monitor* monitor, |
248 intptr_t* expected_count, | 249 intptr_t* expected_count, |
249 intptr_t* total_done, | 250 intptr_t* total_done, |
250 intptr_t* exited) | 251 intptr_t* exited) |
251 : isolate_(isolate), | 252 : isolate_(isolate), |
252 mutex_(mutex), | 253 monitor_(monitor), |
253 expected_count_(expected_count), | 254 expected_count_(expected_count), |
254 total_done_(total_done), | 255 total_done_(total_done), |
255 exited_(exited), | 256 exited_(exited), |
256 local_done_(false) {} | 257 local_done_(false) {} |
257 | 258 |
258 virtual void Run() { | 259 virtual void Run() { |
259 Thread::EnterIsolateAsHelper(isolate_); | 260 Thread::EnterIsolateAsHelper(isolate_); |
260 { | 261 { |
261 MutexLocker ml(mutex_); | 262 MonitorLocker ml(monitor_); |
262 ++*expected_count_; | 263 ++*expected_count_; |
263 } | 264 } |
264 for (int i = 0; ; ++i) { | 265 Thread* thread = Thread::Current(); |
265 Thread* thread = Thread::Current(); | 266 for (int i = reinterpret_cast<intptr_t>(thread); ; ++i) { |
266 StackZone stack_zone(thread); | 267 StackZone stack_zone(thread); |
267 Zone* zone = thread->zone(); | 268 Zone* zone = thread->zone(); |
268 HANDLESCOPE(thread); | 269 HANDLESCOPE(thread); |
269 const intptr_t kUniqueSmi = 928327281; | 270 const intptr_t kUniqueSmi = 928327281; |
270 Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi)); | 271 Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi)); |
271 if ((i % 100) != 0) { | 272 if ((i % 100) != 0) { |
272 // Usually, we just cooperate. | 273 // Usually, we just cooperate. |
273 isolate_->thread_registry()->CheckSafepoint(); | 274 TransitionVMToBlocked transition(thread); |
274 } else { | 275 } else { |
275 // But occasionally, organize a rendezvous. | 276 // But occasionally, organize a rendezvous. |
276 isolate_->thread_registry()->SafepointThreads(); | 277 SafepointOperationScope safepoint_scope(thread); |
277 ObjectCounter counter(isolate_, &smi); | 278 ObjectCounter counter(isolate_, &smi); |
278 isolate_->IterateObjectPointers( | 279 isolate_->IterateObjectPointers( |
279 &counter, | 280 &counter, |
280 StackFrameIterator::kValidateFrames); | 281 StackFrameIterator::kValidateFrames); |
281 { | 282 { |
282 MutexLocker ml(mutex_); | 283 MonitorLocker ml(monitor_); |
283 EXPECT_EQ(*expected_count_, counter.count()); | 284 EXPECT_EQ(*expected_count_, counter.count()); |
284 } | 285 } |
285 UserTag& tag = UserTag::Handle(zone, isolate_->current_tag()); | 286 UserTag& tag = UserTag::Handle(zone, isolate_->current_tag()); |
286 if (tag.raw() != isolate_->default_tag()) { | 287 if (tag.raw() != isolate_->default_tag()) { |
287 String& label = String::Handle(zone, tag.label()); | 288 String& label = String::Handle(zone, tag.label()); |
288 EXPECT(label.Equals("foo")); | 289 EXPECT(label.Equals("foo")); |
289 MutexLocker ml(mutex_); | 290 MonitorLocker ml(monitor_); |
290 if (*expected_count_ == kTaskCount && !local_done_) { | 291 if (*expected_count_ == kTaskCount && !local_done_) { |
291 // Success for the first time! Remember that we are done, and | 292 // Success for the first time! Remember that we are done, and |
292 // update the total count. | 293 // update the total count. |
293 local_done_ = true; | 294 local_done_ = true; |
294 ++*total_done_; | 295 ++*total_done_; |
295 } | 296 } |
296 } | 297 } |
297 isolate_->thread_registry()->ResumeAllThreads(); | |
298 } | 298 } |
299 // Check whether everyone is done. | 299 // Check whether everyone is done. |
300 { | 300 { |
301 MutexLocker ml(mutex_); | 301 MonitorLocker ml(monitor_); |
302 if (*total_done_ == kTaskCount) { | 302 if (*total_done_ == kTaskCount) { |
303 // Another task might be at SafepointThreads when resuming. Ensure its | 303 // Another task might be at SafepointThreads when resuming. Ensure its |
304 // expectation reflects reality, since we pop our handles here. | 304 // expectation reflects reality, since we pop our handles here. |
305 --*expected_count_; | 305 --*expected_count_; |
306 break; | 306 break; |
307 } | 307 } |
308 } | 308 } |
309 } | 309 } |
310 Thread::ExitIsolateAsHelper(); | 310 Thread::ExitIsolateAsHelper(); |
311 { | 311 { |
312 MutexLocker ml(mutex_); | 312 MonitorLocker ml(monitor_); |
313 ++*exited_; | 313 ++*exited_; |
| 314 ml.Notify(); |
314 } | 315 } |
315 } | 316 } |
316 | 317 |
317 private: | 318 private: |
318 Isolate* isolate_; | 319 Isolate* isolate_; |
319 Mutex* mutex_; | 320 Monitor* monitor_; |
320 intptr_t* expected_count_; // # copies of kUniqueSmi we expect to visit. | 321 intptr_t* expected_count_; // # copies of kUniqueSmi we expect to visit. |
321 intptr_t* total_done_; // # tasks that successfully safepointed once. | 322 intptr_t* total_done_; // # tasks that successfully safepointed once. |
322 intptr_t* exited_; // # tasks that are no longer running. | 323 intptr_t* exited_; // # tasks that are no longer running. |
323 bool local_done_; // this task has successfully safepointed >= once. | 324 bool local_done_; // this task has successfully safepointed >= once. |
324 }; | 325 }; |
325 | 326 |
326 | 327 |
327 const intptr_t SafepointTestTask::kTaskCount = 5; | 328 const intptr_t SafepointTestTask::kTaskCount = 5; |
328 | 329 |
329 | 330 |
330 // Test rendezvous of: | 331 // Test rendezvous of: |
331 // - helpers in VM code, | 332 // - helpers in VM code, |
332 // - main thread in pure Dart, | 333 // - main thread in pure Dart, |
333 // organized by | 334 // organized by |
334 // - helpers. | 335 // - helpers. |
335 TEST_CASE(SafepointTestDart) { | 336 TEST_CASE(SafepointTestDart) { |
336 Isolate* isolate = Thread::Current()->isolate(); | 337 Isolate* isolate = Thread::Current()->isolate(); |
337 Mutex mutex; | 338 Monitor monitor; |
338 intptr_t expected_count = 0; | 339 intptr_t expected_count = 0; |
339 intptr_t total_done = 0; | 340 intptr_t total_done = 0; |
340 intptr_t exited = 0; | 341 intptr_t exited = 0; |
341 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { | 342 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { |
342 Dart::thread_pool()->Run(new SafepointTestTask( | 343 Dart::thread_pool()->Run(new SafepointTestTask( |
343 isolate, &mutex, &expected_count, &total_done, &exited)); | 344 isolate, &monitor, &expected_count, &total_done, &exited)); |
344 } | 345 } |
345 // Run Dart code on the main thread long enough to allow all helpers | 346 // Run Dart code on the main thread long enough to allow all helpers |
346 // to get their verification done and exit. Use a specific UserTag | 347 // to get their verification done and exit. Use a specific UserTag |
347 // to enable the helpers to verify that the main thread is | 348 // to enable the helpers to verify that the main thread is |
348 // successfully interrupted in the pure Dart loop. | 349 // successfully interrupted in the pure Dart loop. |
349 #if defined(USING_SIMULATOR) | 350 #if defined(USING_SIMULATOR) |
350 const intptr_t kLoopCount = 12345678; | 351 const intptr_t kLoopCount = 12345678; |
351 #else | 352 #else |
352 const intptr_t kLoopCount = 1234567890; | 353 const intptr_t kLoopCount = 1234567890; |
353 #endif // USING_SIMULATOR | 354 #endif // USING_SIMULATOR |
354 char buffer[1024]; | 355 char buffer[1024]; |
355 OS::SNPrint(buffer, sizeof(buffer), | 356 OS::SNPrint(buffer, sizeof(buffer), |
356 "import 'dart:developer';\n" | 357 "import 'dart:developer';\n" |
357 "int dummy = 0;\n" | 358 "int dummy = 0;\n" |
358 "main() {\n" | 359 "main() {\n" |
359 " new UserTag('foo').makeCurrent();\n" | 360 " new UserTag('foo').makeCurrent();\n" |
360 " for (dummy = 0; dummy < %" Pd "; ++dummy) {\n" | 361 " for (dummy = 0; dummy < %" Pd "; ++dummy) {\n" |
361 " dummy += (dummy & 1);\n" | 362 " dummy += (dummy & 1);\n" |
362 " }\n" | 363 " }\n" |
363 "}\n", kLoopCount); | 364 "}\n", kLoopCount); |
364 Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); | 365 Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); |
365 EXPECT_VALID(lib); | 366 EXPECT_VALID(lib); |
366 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 367 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
367 EXPECT_VALID(result); | 368 EXPECT_VALID(result); |
368 // Ensure we looped long enough to allow all helpers to succeed and exit. | 369 // Ensure we looped long enough to allow all helpers to succeed and exit. |
369 { | 370 { |
370 MutexLocker ml(&mutex); | 371 MonitorLocker ml(&monitor); |
| 372 while (exited != SafepointTestTask::kTaskCount) { |
| 373 ml.Wait(); |
| 374 } |
371 EXPECT_EQ(SafepointTestTask::kTaskCount, total_done); | 375 EXPECT_EQ(SafepointTestTask::kTaskCount, total_done); |
372 EXPECT_EQ(SafepointTestTask::kTaskCount, exited); | 376 EXPECT_EQ(SafepointTestTask::kTaskCount, exited); |
373 } | 377 } |
374 } | 378 } |
375 | 379 |
376 | 380 |
377 // Test rendezvous of: | 381 // Test rendezvous of: |
378 // - helpers in VM code, and | 382 // - helpers in VM code, and |
379 // - main thread in VM code, | 383 // - main thread in VM code, |
380 // organized by | 384 // organized by |
381 // - helpers. | 385 // - helpers. |
382 TEST_CASE(SafepointTestVM) { | 386 VM_TEST_CASE(SafepointTestVM) { |
383 Isolate* isolate = thread->isolate(); | 387 Isolate* isolate = thread->isolate(); |
384 Mutex mutex; | 388 Monitor monitor; |
385 intptr_t expected_count = 0; | 389 intptr_t expected_count = 0; |
386 intptr_t total_done = 0; | 390 intptr_t total_done = 0; |
387 intptr_t exited = 0; | 391 intptr_t exited = 0; |
388 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { | 392 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { |
389 Dart::thread_pool()->Run(new SafepointTestTask( | 393 Dart::thread_pool()->Run(new SafepointTestTask( |
390 isolate, &mutex, &expected_count, &total_done, &exited)); | 394 isolate, &monitor, &expected_count, &total_done, &exited)); |
391 } | 395 } |
392 String& label = String::Handle(String::New("foo")); | 396 String& label = String::Handle(String::New("foo")); |
393 UserTag& tag = UserTag::Handle(UserTag::New(label)); | 397 UserTag& tag = UserTag::Handle(UserTag::New(label)); |
394 isolate->set_current_tag(tag); | 398 isolate->set_current_tag(tag); |
395 while (true) { | 399 MonitorLocker ml(&monitor); |
396 isolate->thread_registry()->CheckSafepoint(); | 400 while (exited != SafepointTestTask::kTaskCount) { |
397 MutexLocker ml(&mutex); | 401 ml.WaitWithSafepointCheck(thread); |
398 if (exited == SafepointTestTask::kTaskCount) { | |
399 break; | |
400 } | |
401 } | 402 } |
402 } | 403 } |
403 | 404 |
404 | 405 |
405 TEST_CASE(ThreadIterator_Count) { | 406 VM_TEST_CASE(ThreadIterator_Count) { |
406 intptr_t thread_count_0 = 0; | 407 intptr_t thread_count_0 = 0; |
407 intptr_t thread_count_1 = 0; | 408 intptr_t thread_count_1 = 0; |
408 | 409 |
409 { | 410 { |
410 OSThreadIterator ti; | 411 OSThreadIterator ti; |
411 while (ti.HasNext()) { | 412 while (ti.HasNext()) { |
412 OSThread* thread = ti.Next(); | 413 OSThread* thread = ti.Next(); |
413 EXPECT(thread != NULL); | 414 EXPECT(thread != NULL); |
414 thread_count_0++; | 415 thread_count_0++; |
415 } | 416 } |
416 } | 417 } |
417 | 418 |
418 { | 419 { |
419 OSThreadIterator ti; | 420 OSThreadIterator ti; |
420 while (ti.HasNext()) { | 421 while (ti.HasNext()) { |
421 OSThread* thread = ti.Next(); | 422 OSThread* thread = ti.Next(); |
422 EXPECT(thread != NULL); | 423 EXPECT(thread != NULL); |
423 thread_count_1++; | 424 thread_count_1++; |
424 } | 425 } |
425 } | 426 } |
426 | 427 |
427 EXPECT(thread_count_0 > 0); | 428 EXPECT(thread_count_0 > 0); |
428 EXPECT(thread_count_1 > 0); | 429 EXPECT(thread_count_1 > 0); |
429 EXPECT(thread_count_0 >= thread_count_1); | 430 EXPECT(thread_count_0 >= thread_count_1); |
430 } | 431 } |
431 | 432 |
432 | 433 |
433 TEST_CASE(ThreadIterator_FindSelf) { | 434 VM_TEST_CASE(ThreadIterator_FindSelf) { |
434 OSThread* current = OSThread::Current(); | 435 OSThread* current = OSThread::Current(); |
435 EXPECT(OSThread::IsThreadInList(current->join_id())); | 436 EXPECT(OSThread::IsThreadInList(current->join_id())); |
436 } | 437 } |
437 | 438 |
438 | 439 |
439 struct ThreadIteratorTestParams { | 440 struct ThreadIteratorTestParams { |
440 ThreadId spawned_thread_join_id; | 441 ThreadId spawned_thread_join_id; |
441 Monitor* monitor; | 442 Monitor* monitor; |
442 }; | 443 }; |
443 | 444 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 delete params.monitor; | 484 delete params.monitor; |
484 } | 485 } |
485 | 486 |
486 | 487 |
487 // Test rendezvous of: | 488 // Test rendezvous of: |
488 // - helpers in VM code, and | 489 // - helpers in VM code, and |
489 // - main thread in VM code, | 490 // - main thread in VM code, |
490 // organized by | 491 // organized by |
491 // - main thread, and | 492 // - main thread, and |
492 // - helpers. | 493 // - helpers. |
493 TEST_CASE(SafepointTestVM2) { | 494 VM_TEST_CASE(SafepointTestVM2) { |
494 Isolate* isolate = thread->isolate(); | 495 Isolate* isolate = thread->isolate(); |
495 Mutex mutex; | 496 Monitor monitor; |
496 intptr_t expected_count = 0; | 497 intptr_t expected_count = 0; |
497 intptr_t total_done = 0; | 498 intptr_t total_done = 0; |
498 intptr_t exited = 0; | 499 intptr_t exited = 0; |
499 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { | 500 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { |
500 Dart::thread_pool()->Run(new SafepointTestTask( | 501 Dart::thread_pool()->Run(new SafepointTestTask( |
501 isolate, &mutex, &expected_count, &total_done, &exited)); | 502 isolate, &monitor, &expected_count, &total_done, &exited)); |
502 } | 503 } |
503 bool all_helpers = false; | 504 bool all_helpers = false; |
504 do { | 505 do { |
505 isolate->thread_registry()->SafepointThreads(); | 506 SafepointOperationScope safepoint_scope(thread); |
506 { | 507 { |
507 MutexLocker ml(&mutex); | 508 MonitorLocker ml(&monitor); |
508 if (expected_count == SafepointTestTask::kTaskCount) { | 509 if (expected_count == SafepointTestTask::kTaskCount) { |
509 all_helpers = true; | 510 all_helpers = true; |
510 } | 511 } |
511 } | 512 } |
512 isolate->thread_registry()->ResumeAllThreads(); | |
513 } while (!all_helpers); | 513 } while (!all_helpers); |
514 String& label = String::Handle(String::New("foo")); | 514 String& label = String::Handle(String::New("foo")); |
515 UserTag& tag = UserTag::Handle(UserTag::New(label)); | 515 UserTag& tag = UserTag::Handle(UserTag::New(label)); |
516 isolate->set_current_tag(tag); | 516 isolate->set_current_tag(tag); |
517 while (true) { | 517 MonitorLocker ml(&monitor); |
518 isolate->thread_registry()->CheckSafepoint(); | 518 while (exited != SafepointTestTask::kTaskCount) { |
519 MutexLocker ml(&mutex); | 519 ml.WaitWithSafepointCheck(thread); |
520 if (exited == SafepointTestTask::kTaskCount) { | |
521 break; | |
522 } | |
523 } | 520 } |
524 } | 521 } |
525 | 522 |
526 | 523 |
527 class AllocAndGCTask : public ThreadPool::Task { | 524 class AllocAndGCTask : public ThreadPool::Task { |
528 public: | 525 public: |
529 AllocAndGCTask(Isolate* isolate, | 526 AllocAndGCTask(Isolate* isolate, |
530 Monitor* done_monitor, | 527 Monitor* done_monitor, |
531 bool* done) | 528 bool* done) |
532 : isolate_(isolate), | 529 : isolate_(isolate), |
(...skipping 22 matching lines...) Expand all Loading... |
555 } | 552 } |
556 } | 553 } |
557 | 554 |
558 private: | 555 private: |
559 Isolate* isolate_; | 556 Isolate* isolate_; |
560 Monitor* done_monitor_; | 557 Monitor* done_monitor_; |
561 bool* done_; | 558 bool* done_; |
562 }; | 559 }; |
563 | 560 |
564 | 561 |
565 TEST_CASE(HelperAllocAndGC) { | 562 VM_TEST_CASE(HelperAllocAndGC) { |
566 Monitor done_monitor; | 563 Monitor done_monitor; |
567 bool done = false; | 564 bool done = false; |
568 Isolate* isolate = Thread::Current()->isolate(); | 565 Isolate* isolate = thread->isolate(); |
569 Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done)); | 566 Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done)); |
570 { | 567 { |
571 while (true) { | 568 while (true) { |
572 isolate->thread_registry()->CheckSafepoint(); | 569 TransitionVMToBlocked transition(thread); |
573 MonitorLocker ml(&done_monitor); | 570 MonitorLocker ml(&done_monitor); |
574 if (done) { | 571 if (done) { |
575 break; | 572 break; |
576 } | 573 } |
577 } | 574 } |
578 } | 575 } |
579 } | 576 } |
580 | 577 |
581 } // namespace dart | 578 } // namespace dart |
OLD | NEW |