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" | |
9 #include "vm/profiler.h" | 8 #include "vm/profiler.h" |
10 #include "vm/safepoint.h" | 9 #include "vm/safepoint.h" |
11 #include "vm/stack_frame.h" | 10 #include "vm/stack_frame.h" |
12 #include "vm/thread_pool.h" | 11 #include "vm/thread_pool.h" |
| 12 #include "vm/unit_test.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 VM_UNIT_TEST_CASE(Mutex) { | 16 VM_UNIT_TEST_CASE(Mutex) { |
17 // This unit test case needs a running isolate. | 17 // This unit test case needs a running isolate. |
18 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, | 18 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, |
19 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); | 19 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); |
20 | 20 |
21 Mutex* mutex = new Mutex(); | 21 Mutex* mutex = new Mutex(); |
22 mutex->Lock(); | 22 mutex->Lock(); |
23 EXPECT_EQ(false, mutex->TryLock()); | 23 EXPECT_EQ(false, mutex->TryLock()); |
24 mutex->Unlock(); | 24 mutex->Unlock(); |
25 EXPECT_EQ(true, mutex->TryLock()); | 25 EXPECT_EQ(true, mutex->TryLock()); |
26 mutex->Unlock(); | 26 mutex->Unlock(); |
27 { | 27 { |
28 MutexLocker ml(mutex); | 28 MutexLocker ml(mutex); |
29 EXPECT_EQ(false, mutex->TryLock()); | 29 EXPECT_EQ(false, mutex->TryLock()); |
30 } | 30 } |
31 // The isolate shutdown and the destruction of the mutex are out-of-order on | 31 // The isolate shutdown and the destruction of the mutex are out-of-order on |
32 // purpose. | 32 // purpose. |
33 Dart_ShutdownIsolate(); | 33 Dart_ShutdownIsolate(); |
34 delete mutex; | 34 delete mutex; |
35 } | 35 } |
36 | 36 |
37 | |
38 VM_UNIT_TEST_CASE(Monitor) { | 37 VM_UNIT_TEST_CASE(Monitor) { |
39 // This unit test case needs a running isolate. | 38 // This unit test case needs a running isolate. |
40 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, | 39 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, |
41 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); | 40 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); |
42 OSThread* thread = OSThread::Current(); | 41 OSThread* thread = OSThread::Current(); |
43 // Thread interrupter interferes with this test, disable interrupts. | 42 // Thread interrupter interferes with this test, disable interrupts. |
44 thread->DisableThreadInterrupts(); | 43 thread->DisableThreadInterrupts(); |
45 Monitor* monitor = new Monitor(); | 44 Monitor* monitor = new Monitor(); |
46 monitor->Enter(); | 45 monitor->Enter(); |
47 monitor->Exit(); | 46 monitor->Exit(); |
(...skipping 26 matching lines...) Expand all Loading... |
74 attempts++; | 73 attempts++; |
75 } | 74 } |
76 EXPECT_LT(attempts, kNumAttempts); | 75 EXPECT_LT(attempts, kNumAttempts); |
77 | 76 |
78 // The isolate shutdown and the destruction of the mutex are out-of-order on | 77 // The isolate shutdown and the destruction of the mutex are out-of-order on |
79 // purpose. | 78 // purpose. |
80 Dart_ShutdownIsolate(); | 79 Dart_ShutdownIsolate(); |
81 delete monitor; | 80 delete monitor; |
82 } | 81 } |
83 | 82 |
84 | |
85 class ObjectCounter : public ObjectPointerVisitor { | 83 class ObjectCounter : public ObjectPointerVisitor { |
86 public: | 84 public: |
87 explicit ObjectCounter(Isolate* isolate, const Object* obj) | 85 explicit ObjectCounter(Isolate* isolate, const Object* obj) |
88 : ObjectPointerVisitor(isolate), obj_(obj), count_(0) {} | 86 : ObjectPointerVisitor(isolate), obj_(obj), count_(0) {} |
89 | 87 |
90 virtual void VisitPointers(RawObject** first, RawObject** last) { | 88 virtual void VisitPointers(RawObject** first, RawObject** last) { |
91 for (RawObject** current = first; current <= last; ++current) { | 89 for (RawObject** current = first; current <= last; ++current) { |
92 if (*current == obj_->raw()) { | 90 if (*current == obj_->raw()) { |
93 ++count_; | 91 ++count_; |
94 } | 92 } |
95 } | 93 } |
96 } | 94 } |
97 | 95 |
98 intptr_t count() const { return count_; } | 96 intptr_t count() const { return count_; } |
99 | 97 |
100 private: | 98 private: |
101 const Object* obj_; | 99 const Object* obj_; |
102 intptr_t count_; | 100 intptr_t count_; |
103 }; | 101 }; |
104 | 102 |
105 | |
106 class TaskWithZoneAllocation : public ThreadPool::Task { | 103 class TaskWithZoneAllocation : public ThreadPool::Task { |
107 public: | 104 public: |
108 TaskWithZoneAllocation(Isolate* isolate, | 105 TaskWithZoneAllocation(Isolate* isolate, |
109 Monitor* monitor, | 106 Monitor* monitor, |
110 bool* done, | 107 bool* done, |
111 intptr_t id) | 108 intptr_t id) |
112 : isolate_(isolate), monitor_(monitor), done_(done), id_(id) {} | 109 : isolate_(isolate), monitor_(monitor), done_(done), id_(id) {} |
113 virtual void Run() { | 110 virtual void Run() { |
114 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | 111 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); |
115 { | 112 { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } | 162 } |
166 } | 163 } |
167 | 164 |
168 private: | 165 private: |
169 Isolate* isolate_; | 166 Isolate* isolate_; |
170 Monitor* monitor_; | 167 Monitor* monitor_; |
171 bool* done_; | 168 bool* done_; |
172 intptr_t id_; | 169 intptr_t id_; |
173 }; | 170 }; |
174 | 171 |
175 | |
176 ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) { | 172 ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) { |
177 const int kTaskCount = 100; | 173 const int kTaskCount = 100; |
178 Monitor sync[kTaskCount]; | 174 Monitor sync[kTaskCount]; |
179 bool done[kTaskCount]; | 175 bool done[kTaskCount]; |
180 Isolate* isolate = Thread::Current()->isolate(); | 176 Isolate* isolate = Thread::Current()->isolate(); |
181 EXPECT(isolate->heap()->GrowthControlState()); | 177 EXPECT(isolate->heap()->GrowthControlState()); |
182 isolate->heap()->DisableGrowthControl(); | 178 isolate->heap()->DisableGrowthControl(); |
183 for (int i = 0; i < kTaskCount; i++) { | 179 for (int i = 0; i < kTaskCount; i++) { |
184 done[i] = false; | 180 done[i] = false; |
185 Dart::thread_pool()->Run( | 181 Dart::thread_pool()->Run( |
(...skipping 11 matching lines...) Expand all Loading... |
197 ml.Wait(); | 193 ml.Wait(); |
198 } | 194 } |
199 EXPECT(done[i]); | 195 EXPECT(done[i]); |
200 if (i % 10 == 0) { | 196 if (i % 10 == 0) { |
201 Thread::EnterIsolate(isolate); | 197 Thread::EnterIsolate(isolate); |
202 } | 198 } |
203 EXPECT(bar.Equals("bar")); | 199 EXPECT(bar.Equals("bar")); |
204 } | 200 } |
205 } | 201 } |
206 | 202 |
207 | |
208 #ifndef PRODUCT | 203 #ifndef PRODUCT |
209 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { | 204 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { |
210 public: | 205 public: |
211 SimpleTaskWithZoneAllocation(intptr_t id, | 206 SimpleTaskWithZoneAllocation(intptr_t id, |
212 Isolate* isolate, | 207 Isolate* isolate, |
213 Thread** thread_ptr, | 208 Thread** thread_ptr, |
214 Monitor* sync, | 209 Monitor* sync, |
215 Monitor* monitor, | 210 Monitor* monitor, |
216 intptr_t* done_count, | 211 intptr_t* done_count, |
217 bool* wait) | 212 bool* wait) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 | 274 |
280 intptr_t id_; | 275 intptr_t id_; |
281 Isolate* isolate_; | 276 Isolate* isolate_; |
282 Thread** thread_ptr_; | 277 Thread** thread_ptr_; |
283 Monitor* sync_; | 278 Monitor* sync_; |
284 Monitor* monitor_; | 279 Monitor* monitor_; |
285 intptr_t* done_count_; | 280 intptr_t* done_count_; |
286 bool* wait_; | 281 bool* wait_; |
287 }; | 282 }; |
288 | 283 |
289 | |
290 TEST_CASE(ManySimpleTasksWithZones) { | 284 TEST_CASE(ManySimpleTasksWithZones) { |
291 const int kTaskCount = 10; | 285 const int kTaskCount = 10; |
292 Monitor monitor; | 286 Monitor monitor; |
293 Monitor sync; | 287 Monitor sync; |
294 Thread* threads[kTaskCount]; | 288 Thread* threads[kTaskCount]; |
295 Isolate* isolate = Thread::Current()->isolate(); | 289 Isolate* isolate = Thread::Current()->isolate(); |
296 intptr_t done_count = 0; | 290 intptr_t done_count = 0; |
297 bool wait = true; | 291 bool wait = true; |
298 | 292 |
299 EXPECT(isolate->heap()->GrowthControlState()); | 293 EXPECT(isolate->heap()->GrowthControlState()); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 // Now wait for them all to exit before destroying the isolate. | 346 // Now wait for them all to exit before destroying the isolate. |
353 { | 347 { |
354 MonitorLocker ml(&monitor); | 348 MonitorLocker ml(&monitor); |
355 while (done_count < kTaskCount) { | 349 while (done_count < kTaskCount) { |
356 ml.Wait(); | 350 ml.Wait(); |
357 } | 351 } |
358 } | 352 } |
359 } | 353 } |
360 #endif | 354 #endif |
361 | 355 |
362 | |
363 TEST_CASE(ThreadRegistry) { | 356 TEST_CASE(ThreadRegistry) { |
364 Isolate* orig = Thread::Current()->isolate(); | 357 Isolate* orig = Thread::Current()->isolate(); |
365 Zone* orig_zone = Thread::Current()->zone(); | 358 Zone* orig_zone = Thread::Current()->zone(); |
366 char* orig_str = orig_zone->PrintToString("foo"); | 359 char* orig_str = orig_zone->PrintToString("foo"); |
367 Dart_ExitIsolate(); | 360 Dart_ExitIsolate(); |
368 // Create and enter a new isolate. | 361 // Create and enter a new isolate. |
369 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, | 362 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, |
370 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); | 363 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); |
371 Zone* zone0 = Thread::Current()->zone(); | 364 Zone* zone0 = Thread::Current()->zone(); |
372 EXPECT(zone0 != orig_zone); | 365 EXPECT(zone0 != orig_zone); |
373 Dart_ShutdownIsolate(); | 366 Dart_ShutdownIsolate(); |
374 // Create and enter yet another isolate. | 367 // Create and enter yet another isolate. |
375 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, | 368 Dart_CreateIsolate(NULL, NULL, bin::core_isolate_snapshot_data, |
376 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); | 369 bin::core_isolate_snapshot_instructions, NULL, NULL, NULL); |
377 { | 370 { |
378 // Create a stack resource this time, and exercise it. | 371 // Create a stack resource this time, and exercise it. |
379 StackZone stack_zone(Thread::Current()); | 372 StackZone stack_zone(Thread::Current()); |
380 Zone* zone1 = Thread::Current()->zone(); | 373 Zone* zone1 = Thread::Current()->zone(); |
381 EXPECT(zone1 != zone0); | 374 EXPECT(zone1 != zone0); |
382 EXPECT(zone1 != orig_zone); | 375 EXPECT(zone1 != orig_zone); |
383 } | 376 } |
384 Dart_ShutdownIsolate(); | 377 Dart_ShutdownIsolate(); |
385 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig)); | 378 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig)); |
386 // Original zone should be preserved. | 379 // Original zone should be preserved. |
387 EXPECT_EQ(orig_zone, Thread::Current()->zone()); | 380 EXPECT_EQ(orig_zone, Thread::Current()->zone()); |
388 EXPECT_STREQ("foo", orig_str); | 381 EXPECT_STREQ("foo", orig_str); |
389 } | 382 } |
390 | 383 |
391 | |
392 // A helper thread that alternatingly cooperates and organizes | 384 // A helper thread that alternatingly cooperates and organizes |
393 // safepoint rendezvous. At rendezvous, it explicitly visits the | 385 // safepoint rendezvous. At rendezvous, it explicitly visits the |
394 // stacks looking for a specific marker (Smi) to verify that the expected | 386 // stacks looking for a specific marker (Smi) to verify that the expected |
395 // number threads are actually visited. The task is "done" when it has | 387 // number threads are actually visited. The task is "done" when it has |
396 // successfully made all other tasks and the main thread rendezvous (may | 388 // successfully made all other tasks and the main thread rendezvous (may |
397 // not happen in the first rendezvous, since tasks are still starting up). | 389 // not happen in the first rendezvous, since tasks are still starting up). |
398 class SafepointTestTask : public ThreadPool::Task { | 390 class SafepointTestTask : public ThreadPool::Task { |
399 public: | 391 public: |
400 static const intptr_t kTaskCount; | 392 static const intptr_t kTaskCount; |
401 | 393 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 | 463 |
472 private: | 464 private: |
473 Isolate* isolate_; | 465 Isolate* isolate_; |
474 Monitor* monitor_; | 466 Monitor* monitor_; |
475 intptr_t* expected_count_; // # copies of kUniqueSmi we expect to visit. | 467 intptr_t* expected_count_; // # copies of kUniqueSmi we expect to visit. |
476 intptr_t* total_done_; // # tasks that successfully safepointed once. | 468 intptr_t* total_done_; // # tasks that successfully safepointed once. |
477 intptr_t* exited_; // # tasks that are no longer running. | 469 intptr_t* exited_; // # tasks that are no longer running. |
478 bool local_done_; // this task has successfully safepointed >= once. | 470 bool local_done_; // this task has successfully safepointed >= once. |
479 }; | 471 }; |
480 | 472 |
481 | |
482 const intptr_t SafepointTestTask::kTaskCount = 5; | 473 const intptr_t SafepointTestTask::kTaskCount = 5; |
483 | 474 |
484 | |
485 // Test rendezvous of: | 475 // Test rendezvous of: |
486 // - helpers in VM code, | 476 // - helpers in VM code, |
487 // - main thread in pure Dart, | 477 // - main thread in pure Dart, |
488 // organized by | 478 // organized by |
489 // - helpers. | 479 // - helpers. |
490 TEST_CASE(SafepointTestDart) { | 480 TEST_CASE(SafepointTestDart) { |
491 Isolate* isolate = Thread::Current()->isolate(); | 481 Isolate* isolate = Thread::Current()->isolate(); |
492 Monitor monitor; | 482 Monitor monitor; |
493 intptr_t expected_count = 0; | 483 intptr_t expected_count = 0; |
494 intptr_t total_done = 0; | 484 intptr_t total_done = 0; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 { | 516 { |
527 MonitorLocker ml(&monitor); | 517 MonitorLocker ml(&monitor); |
528 while (exited != SafepointTestTask::kTaskCount) { | 518 while (exited != SafepointTestTask::kTaskCount) { |
529 ml.Wait(); | 519 ml.Wait(); |
530 } | 520 } |
531 EXPECT_EQ(SafepointTestTask::kTaskCount, total_done); | 521 EXPECT_EQ(SafepointTestTask::kTaskCount, total_done); |
532 EXPECT_EQ(SafepointTestTask::kTaskCount, exited); | 522 EXPECT_EQ(SafepointTestTask::kTaskCount, exited); |
533 } | 523 } |
534 } | 524 } |
535 | 525 |
536 | |
537 // Test rendezvous of: | 526 // Test rendezvous of: |
538 // - helpers in VM code, and | 527 // - helpers in VM code, and |
539 // - main thread in VM code, | 528 // - main thread in VM code, |
540 // organized by | 529 // organized by |
541 // - helpers. | 530 // - helpers. |
542 ISOLATE_UNIT_TEST_CASE(SafepointTestVM) { | 531 ISOLATE_UNIT_TEST_CASE(SafepointTestVM) { |
543 Isolate* isolate = thread->isolate(); | 532 Isolate* isolate = thread->isolate(); |
544 Monitor monitor; | 533 Monitor monitor; |
545 intptr_t expected_count = 0; | 534 intptr_t expected_count = 0; |
546 intptr_t total_done = 0; | 535 intptr_t total_done = 0; |
547 intptr_t exited = 0; | 536 intptr_t exited = 0; |
548 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { | 537 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { |
549 Dart::thread_pool()->Run(new SafepointTestTask( | 538 Dart::thread_pool()->Run(new SafepointTestTask( |
550 isolate, &monitor, &expected_count, &total_done, &exited)); | 539 isolate, &monitor, &expected_count, &total_done, &exited)); |
551 } | 540 } |
552 String& label = String::Handle(String::New("foo")); | 541 String& label = String::Handle(String::New("foo")); |
553 UserTag& tag = UserTag::Handle(UserTag::New(label)); | 542 UserTag& tag = UserTag::Handle(UserTag::New(label)); |
554 isolate->set_current_tag(tag); | 543 isolate->set_current_tag(tag); |
555 MonitorLocker ml(&monitor); | 544 MonitorLocker ml(&monitor); |
556 while (exited != SafepointTestTask::kTaskCount) { | 545 while (exited != SafepointTestTask::kTaskCount) { |
557 ml.WaitWithSafepointCheck(thread); | 546 ml.WaitWithSafepointCheck(thread); |
558 } | 547 } |
559 } | 548 } |
560 | 549 |
561 | |
562 // Test case for recursive safepoint operations. | 550 // Test case for recursive safepoint operations. |
563 ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest1) { | 551 ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest1) { |
564 intptr_t count = 0; | 552 intptr_t count = 0; |
565 { | 553 { |
566 SafepointOperationScope safepoint_scope(thread); | 554 SafepointOperationScope safepoint_scope(thread); |
567 count += 1; | 555 count += 1; |
568 { | 556 { |
569 SafepointOperationScope safepoint_scope(thread); | 557 SafepointOperationScope safepoint_scope(thread); |
570 count += 1; | 558 count += 1; |
571 { | 559 { |
572 SafepointOperationScope safepoint_scope(thread); | 560 SafepointOperationScope safepoint_scope(thread); |
573 count += 1; | 561 count += 1; |
574 } | 562 } |
575 } | 563 } |
576 } | 564 } |
577 EXPECT(count == 3); | 565 EXPECT(count == 3); |
578 } | 566 } |
579 | 567 |
580 | |
581 ISOLATE_UNIT_TEST_CASE(ThreadIterator_Count) { | 568 ISOLATE_UNIT_TEST_CASE(ThreadIterator_Count) { |
582 intptr_t thread_count_0 = 0; | 569 intptr_t thread_count_0 = 0; |
583 intptr_t thread_count_1 = 0; | 570 intptr_t thread_count_1 = 0; |
584 | 571 |
585 { | 572 { |
586 OSThreadIterator ti; | 573 OSThreadIterator ti; |
587 while (ti.HasNext()) { | 574 while (ti.HasNext()) { |
588 OSThread* thread = ti.Next(); | 575 OSThread* thread = ti.Next(); |
589 EXPECT(thread != NULL); | 576 EXPECT(thread != NULL); |
590 thread_count_0++; | 577 thread_count_0++; |
591 } | 578 } |
592 } | 579 } |
593 | 580 |
594 { | 581 { |
595 OSThreadIterator ti; | 582 OSThreadIterator ti; |
596 while (ti.HasNext()) { | 583 while (ti.HasNext()) { |
597 OSThread* thread = ti.Next(); | 584 OSThread* thread = ti.Next(); |
598 EXPECT(thread != NULL); | 585 EXPECT(thread != NULL); |
599 thread_count_1++; | 586 thread_count_1++; |
600 } | 587 } |
601 } | 588 } |
602 | 589 |
603 EXPECT(thread_count_0 > 0); | 590 EXPECT(thread_count_0 > 0); |
604 EXPECT(thread_count_1 > 0); | 591 EXPECT(thread_count_1 > 0); |
605 EXPECT(thread_count_0 >= thread_count_1); | 592 EXPECT(thread_count_0 >= thread_count_1); |
606 } | 593 } |
607 | 594 |
608 | |
609 ISOLATE_UNIT_TEST_CASE(ThreadIterator_FindSelf) { | 595 ISOLATE_UNIT_TEST_CASE(ThreadIterator_FindSelf) { |
610 OSThread* current = OSThread::Current(); | 596 OSThread* current = OSThread::Current(); |
611 EXPECT(OSThread::IsThreadInList(current->id())); | 597 EXPECT(OSThread::IsThreadInList(current->id())); |
612 } | 598 } |
613 | 599 |
614 | |
615 struct ThreadIteratorTestParams { | 600 struct ThreadIteratorTestParams { |
616 ThreadId spawned_thread_id; | 601 ThreadId spawned_thread_id; |
617 ThreadJoinId spawned_thread_join_id; | 602 ThreadJoinId spawned_thread_join_id; |
618 Monitor* monitor; | 603 Monitor* monitor; |
619 }; | 604 }; |
620 | 605 |
621 | |
622 void ThreadIteratorTestMain(uword parameter) { | 606 void ThreadIteratorTestMain(uword parameter) { |
623 ThreadIteratorTestParams* params = | 607 ThreadIteratorTestParams* params = |
624 reinterpret_cast<ThreadIteratorTestParams*>(parameter); | 608 reinterpret_cast<ThreadIteratorTestParams*>(parameter); |
625 OSThread* thread = OSThread::Current(); | 609 OSThread* thread = OSThread::Current(); |
626 EXPECT(thread != NULL); | 610 EXPECT(thread != NULL); |
627 | 611 |
628 MonitorLocker ml(params->monitor); | 612 MonitorLocker ml(params->monitor); |
629 params->spawned_thread_id = thread->id(); | 613 params->spawned_thread_id = thread->id(); |
630 params->spawned_thread_join_id = OSThread::GetCurrentThreadJoinId(thread); | 614 params->spawned_thread_join_id = OSThread::GetCurrentThreadJoinId(thread); |
631 EXPECT(params->spawned_thread_id != OSThread::kInvalidThreadId); | 615 EXPECT(params->spawned_thread_id != OSThread::kInvalidThreadId); |
632 EXPECT(OSThread::IsThreadInList(thread->id())); | 616 EXPECT(OSThread::IsThreadInList(thread->id())); |
633 ml.Notify(); | 617 ml.Notify(); |
634 } | 618 } |
635 | 619 |
636 | |
637 // NOTE: This test case also verifies that known TLS destructors are called | 620 // NOTE: This test case also verifies that known TLS destructors are called |
638 // on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details. | 621 // on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details. |
639 TEST_CASE(ThreadIterator_AddFindRemove) { | 622 TEST_CASE(ThreadIterator_AddFindRemove) { |
640 ThreadIteratorTestParams params; | 623 ThreadIteratorTestParams params; |
641 params.spawned_thread_id = OSThread::kInvalidThreadId; | 624 params.spawned_thread_id = OSThread::kInvalidThreadId; |
642 params.monitor = new Monitor(); | 625 params.monitor = new Monitor(); |
643 | 626 |
644 { | 627 { |
645 MonitorLocker ml(params.monitor); | 628 MonitorLocker ml(params.monitor); |
646 EXPECT(params.spawned_thread_id == OSThread::kInvalidThreadId); | 629 EXPECT(params.spawned_thread_id == OSThread::kInvalidThreadId); |
647 // Spawn thread and wait to receive the thread id. | 630 // Spawn thread and wait to receive the thread id. |
648 OSThread::Start("ThreadIteratorTest", ThreadIteratorTestMain, | 631 OSThread::Start("ThreadIteratorTest", ThreadIteratorTestMain, |
649 reinterpret_cast<uword>(¶ms)); | 632 reinterpret_cast<uword>(¶ms)); |
650 while (params.spawned_thread_id == OSThread::kInvalidThreadId) { | 633 while (params.spawned_thread_id == OSThread::kInvalidThreadId) { |
651 ml.Wait(); | 634 ml.Wait(); |
652 } | 635 } |
653 EXPECT(params.spawned_thread_id != OSThread::kInvalidThreadId); | 636 EXPECT(params.spawned_thread_id != OSThread::kInvalidThreadId); |
654 EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId); | 637 EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId); |
655 OSThread::Join(params.spawned_thread_join_id); | 638 OSThread::Join(params.spawned_thread_join_id); |
656 } | 639 } |
657 | 640 |
658 EXPECT(!OSThread::IsThreadInList(params.spawned_thread_id)) | 641 EXPECT(!OSThread::IsThreadInList(params.spawned_thread_id)) |
659 | 642 |
660 delete params.monitor; | 643 delete params.monitor; |
661 } | 644 } |
662 | 645 |
663 | |
664 // Test rendezvous of: | 646 // Test rendezvous of: |
665 // - helpers in VM code, and | 647 // - helpers in VM code, and |
666 // - main thread in VM code, | 648 // - main thread in VM code, |
667 // organized by | 649 // organized by |
668 // - main thread, and | 650 // - main thread, and |
669 // - helpers. | 651 // - helpers. |
670 ISOLATE_UNIT_TEST_CASE(SafepointTestVM2) { | 652 ISOLATE_UNIT_TEST_CASE(SafepointTestVM2) { |
671 Isolate* isolate = thread->isolate(); | 653 Isolate* isolate = thread->isolate(); |
672 Monitor monitor; | 654 Monitor monitor; |
673 intptr_t expected_count = 0; | 655 intptr_t expected_count = 0; |
(...skipping 15 matching lines...) Expand all Loading... |
689 } while (!all_helpers); | 671 } while (!all_helpers); |
690 String& label = String::Handle(String::New("foo")); | 672 String& label = String::Handle(String::New("foo")); |
691 UserTag& tag = UserTag::Handle(UserTag::New(label)); | 673 UserTag& tag = UserTag::Handle(UserTag::New(label)); |
692 isolate->set_current_tag(tag); | 674 isolate->set_current_tag(tag); |
693 MonitorLocker ml(&monitor); | 675 MonitorLocker ml(&monitor); |
694 while (exited != SafepointTestTask::kTaskCount) { | 676 while (exited != SafepointTestTask::kTaskCount) { |
695 ml.WaitWithSafepointCheck(thread); | 677 ml.WaitWithSafepointCheck(thread); |
696 } | 678 } |
697 } | 679 } |
698 | 680 |
699 | |
700 // Test recursive safepoint operation scopes with other threads trying | 681 // Test recursive safepoint operation scopes with other threads trying |
701 // to also start a safepoint operation scope. | 682 // to also start a safepoint operation scope. |
702 ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest2) { | 683 ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest2) { |
703 Isolate* isolate = thread->isolate(); | 684 Isolate* isolate = thread->isolate(); |
704 Monitor monitor; | 685 Monitor monitor; |
705 intptr_t expected_count = 0; | 686 intptr_t expected_count = 0; |
706 intptr_t total_done = 0; | 687 intptr_t total_done = 0; |
707 intptr_t exited = 0; | 688 intptr_t exited = 0; |
708 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { | 689 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { |
709 Dart::thread_pool()->Run(new SafepointTestTask( | 690 Dart::thread_pool()->Run(new SafepointTestTask( |
(...skipping 19 matching lines...) Expand all Loading... |
729 { | 710 { |
730 SafepointOperationScope safepoint_scope(thread); | 711 SafepointOperationScope safepoint_scope(thread); |
731 MonitorLocker ml(&monitor); | 712 MonitorLocker ml(&monitor); |
732 if (exited == SafepointTestTask::kTaskCount) { | 713 if (exited == SafepointTestTask::kTaskCount) { |
733 all_exited = true; | 714 all_exited = true; |
734 } | 715 } |
735 } | 716 } |
736 } while (!all_exited); | 717 } while (!all_exited); |
737 } | 718 } |
738 | 719 |
739 | |
740 class AllocAndGCTask : public ThreadPool::Task { | 720 class AllocAndGCTask : public ThreadPool::Task { |
741 public: | 721 public: |
742 AllocAndGCTask(Isolate* isolate, Monitor* done_monitor, bool* done) | 722 AllocAndGCTask(Isolate* isolate, Monitor* done_monitor, bool* done) |
743 : isolate_(isolate), done_monitor_(done_monitor), done_(done) {} | 723 : isolate_(isolate), done_monitor_(done_monitor), done_(done) {} |
744 | 724 |
745 virtual void Run() { | 725 virtual void Run() { |
746 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | 726 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); |
747 { | 727 { |
748 Thread* thread = Thread::Current(); | 728 Thread* thread = Thread::Current(); |
749 StackZone stack_zone(thread); | 729 StackZone stack_zone(thread); |
(...skipping 12 matching lines...) Expand all Loading... |
762 ml.Notify(); | 742 ml.Notify(); |
763 } | 743 } |
764 } | 744 } |
765 | 745 |
766 private: | 746 private: |
767 Isolate* isolate_; | 747 Isolate* isolate_; |
768 Monitor* done_monitor_; | 748 Monitor* done_monitor_; |
769 bool* done_; | 749 bool* done_; |
770 }; | 750 }; |
771 | 751 |
772 | |
773 ISOLATE_UNIT_TEST_CASE(HelperAllocAndGC) { | 752 ISOLATE_UNIT_TEST_CASE(HelperAllocAndGC) { |
774 Monitor done_monitor; | 753 Monitor done_monitor; |
775 bool done = false; | 754 bool done = false; |
776 Isolate* isolate = thread->isolate(); | 755 Isolate* isolate = thread->isolate(); |
777 Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done)); | 756 Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done)); |
778 { | 757 { |
779 while (true) { | 758 while (true) { |
780 TransitionVMToBlocked transition(thread); | 759 TransitionVMToBlocked transition(thread); |
781 MonitorLocker ml(&done_monitor); | 760 MonitorLocker ml(&done_monitor); |
782 if (done) { | 761 if (done) { |
783 break; | 762 break; |
784 } | 763 } |
785 } | 764 } |
786 } | 765 } |
787 } | 766 } |
788 | 767 |
789 } // namespace dart | 768 } // namespace dart |
OLD | NEW |