| 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" |
| 11 #include "vm/stack_frame.h" | 11 #include "vm/stack_frame.h" |
| 12 #include "vm/thread_pool.h" | 12 #include "vm/thread_pool.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 UNIT_TEST_CASE(Mutex) { | 16 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( | 18 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
| 19 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 19 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 | 37 |
| 38 UNIT_TEST_CASE(Monitor) { | 38 UNIT_TEST_CASE(Monitor) { |
| 39 // This unit test case needs a running isolate. | 39 // This unit test case needs a running isolate. |
| 40 Dart_CreateIsolate( | 40 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
| 41 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 41 NULL); |
| 42 OSThread* thread = OSThread::Current(); | 42 OSThread* thread = OSThread::Current(); |
| 43 // Thread interrupter interferes with this test, disable interrupts. | 43 // Thread interrupter interferes with this test, disable interrupts. |
| 44 thread->DisableThreadInterrupts(); | 44 thread->DisableThreadInterrupts(); |
| 45 Monitor* monitor = new Monitor(); | 45 Monitor* monitor = new Monitor(); |
| 46 monitor->Enter(); | 46 monitor->Enter(); |
| 47 monitor->Exit(); | 47 monitor->Exit(); |
| 48 EXPECT_EQ(true, monitor->TryEnter()); | 48 EXPECT_EQ(true, monitor->TryEnter()); |
| 49 monitor->Exit(); | 49 monitor->Exit(); |
| 50 | 50 |
| 51 const int kNumAttempts = 5; | 51 const int kNumAttempts = 5; |
| 52 int attempts = 0; | 52 int attempts = 0; |
| 53 while (attempts < kNumAttempts) { | 53 while (attempts < kNumAttempts) { |
| 54 MonitorLocker ml(monitor); | 54 MonitorLocker ml(monitor); |
| 55 int64_t start = OS::GetCurrentTimeMillis(); | 55 int64_t start = OS::GetCurrentTimeMillis(); |
| 56 int64_t wait_time = 2017; | 56 int64_t wait_time = 2017; |
| 57 Monitor::WaitResult wait_result = ml.Wait(wait_time); | 57 Monitor::WaitResult wait_result = ml.Wait(wait_time); |
| 58 int64_t stop = OS::GetCurrentTimeMillis(); | 58 int64_t stop = OS::GetCurrentTimeMillis(); |
| 59 | 59 |
| 60 // We expect to be timing out here. | 60 // We expect to be timing out here. |
| 61 EXPECT_EQ(Monitor::kTimedOut, wait_result); | 61 EXPECT_EQ(Monitor::kTimedOut, wait_result); |
| 62 | 62 |
| 63 // Check whether this attempt falls within the exptected time limits. | 63 // Check whether this attempt falls within the exptected time limits. |
| 64 int64_t wakeup_time = stop - start; | 64 int64_t wakeup_time = stop - start; |
| 65 OS::Print("wakeup_time: %" Pd64 "\n", wakeup_time); | 65 OS::Print("wakeup_time: %" Pd64 "\n", wakeup_time); |
| 66 const int kAcceptableTimeJitter = 20; // Measured in milliseconds. | 66 const int kAcceptableTimeJitter = 20; // Measured in milliseconds. |
| 67 const int kAcceptableWakeupDelay = 150; // Measured in milliseconds. | 67 const int kAcceptableWakeupDelay = 150; // Measured in milliseconds. |
| 68 if (((wait_time - kAcceptableTimeJitter) <= wakeup_time) && | 68 if (((wait_time - kAcceptableTimeJitter) <= wakeup_time) && |
| 69 (wakeup_time <= (wait_time + kAcceptableWakeupDelay))) { | 69 (wakeup_time <= (wait_time + kAcceptableWakeupDelay))) { |
| 70 break; | 70 break; |
| 71 } | 71 } |
| 72 | 72 |
| 73 // Record the attempt. | 73 // Record the attempt. |
| 74 attempts++; | 74 attempts++; |
| 75 } | 75 } |
| 76 EXPECT_LT(attempts, kNumAttempts); | 76 EXPECT_LT(attempts, kNumAttempts); |
| 77 | 77 |
| 78 // The isolate shutdown and the destruction of the mutex are out-of-order on | 78 // The isolate shutdown and the destruction of the mutex are out-of-order on |
| 79 // purpose. | 79 // purpose. |
| 80 Dart_ShutdownIsolate(); | 80 Dart_ShutdownIsolate(); |
| 81 delete monitor; | 81 delete monitor; |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 class ObjectCounter : public ObjectPointerVisitor { | 85 class ObjectCounter : public ObjectPointerVisitor { |
| 86 public: | 86 public: |
| 87 explicit ObjectCounter(Isolate* isolate, const Object* obj) | 87 explicit ObjectCounter(Isolate* isolate, const Object* obj) |
| 88 : ObjectPointerVisitor(isolate), obj_(obj), count_(0) { } | 88 : ObjectPointerVisitor(isolate), obj_(obj), count_(0) {} |
| 89 | 89 |
| 90 virtual void VisitPointers(RawObject** first, RawObject** last) { | 90 virtual void VisitPointers(RawObject** first, RawObject** last) { |
| 91 for (RawObject** current = first; current <= last; ++current) { | 91 for (RawObject** current = first; current <= last; ++current) { |
| 92 if (*current == obj_->raw()) { | 92 if (*current == obj_->raw()) { |
| 93 ++count_; | 93 ++count_; |
| 94 } | 94 } |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 intptr_t count() const { return count_; } | 98 intptr_t count() const { return count_; } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 112 : isolate_(isolate), monitor_(monitor), done_(done), id_(id) {} | 112 : isolate_(isolate), monitor_(monitor), done_(done), id_(id) {} |
| 113 virtual void Run() { | 113 virtual void Run() { |
| 114 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | 114 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); |
| 115 { | 115 { |
| 116 Thread* thread = Thread::Current(); | 116 Thread* thread = Thread::Current(); |
| 117 // Create a zone (which is also a stack resource) and exercise it a bit. | 117 // Create a zone (which is also a stack resource) and exercise it a bit. |
| 118 StackZone stack_zone(thread); | 118 StackZone stack_zone(thread); |
| 119 HANDLESCOPE(thread); | 119 HANDLESCOPE(thread); |
| 120 Zone* zone = thread->zone(); | 120 Zone* zone = thread->zone(); |
| 121 EXPECT_EQ(zone, stack_zone.GetZone()); | 121 EXPECT_EQ(zone, stack_zone.GetZone()); |
| 122 ZoneGrowableArray<bool>* a0 = new(zone) ZoneGrowableArray<bool>(zone, 1); | 122 ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1); |
| 123 GrowableArray<bool> a1(zone, 1); | 123 GrowableArray<bool> a1(zone, 1); |
| 124 for (intptr_t i = 0; i < 100000; ++i) { | 124 for (intptr_t i = 0; i < 100000; ++i) { |
| 125 a0->Add(true); | 125 a0->Add(true); |
| 126 a1.Add(true); | 126 a1.Add(true); |
| 127 } | 127 } |
| 128 // Check that we can create handles and allocate in old space. | 128 // Check that we can create handles and allocate in old space. |
| 129 String& str = String::Handle(zone, String::New("old", Heap::kOld)); | 129 String& str = String::Handle(zone, String::New("old", Heap::kOld)); |
| 130 EXPECT(str.Equals("old")); | 130 EXPECT(str.Equals("old")); |
| 131 | 131 |
| 132 const intptr_t unique_smi = id_ + 928327281; | 132 const intptr_t unique_smi = id_ + 928327281; |
| 133 Smi& smi = Smi::Handle(zone, Smi::New(unique_smi)); | 133 Smi& smi = Smi::Handle(zone, Smi::New(unique_smi)); |
| 134 EXPECT(smi.Value() == unique_smi); | 134 EXPECT(smi.Value() == unique_smi); |
| 135 { | 135 { |
| 136 ObjectCounter counter(isolate_, &smi); | 136 ObjectCounter counter(isolate_, &smi); |
| 137 // Ensure that our particular zone is visited. | 137 // Ensure that our particular zone is visited. |
| 138 isolate_->IterateObjectPointers( | 138 isolate_->IterateObjectPointers(&counter, |
| 139 &counter, | 139 StackFrameIterator::kValidateFrames); |
| 140 StackFrameIterator::kValidateFrames); | |
| 141 EXPECT_EQ(1, counter.count()); | 140 EXPECT_EQ(1, counter.count()); |
| 142 } | 141 } |
| 143 char* unique_chars = zone->PrintToString("unique_str_%" Pd, id_); | 142 char* unique_chars = zone->PrintToString("unique_str_%" Pd, id_); |
| 144 String& unique_str = String::Handle(zone); | 143 String& unique_str = String::Handle(zone); |
| 145 { | 144 { |
| 146 // String::New may create additional handles in the topmost scope that | 145 // String::New may create additional handles in the topmost scope that |
| 147 // we don't want to count, so wrap this in its own scope. | 146 // we don't want to count, so wrap this in its own scope. |
| 148 HANDLESCOPE(thread); | 147 HANDLESCOPE(thread); |
| 149 unique_str = String::New(unique_chars, Heap::kOld); | 148 unique_str = String::New(unique_chars, Heap::kOld); |
| 150 } | 149 } |
| 151 EXPECT(unique_str.Equals(unique_chars)); | 150 EXPECT(unique_str.Equals(unique_chars)); |
| 152 { | 151 { |
| 153 ObjectCounter str_counter(isolate_, &unique_str); | 152 ObjectCounter str_counter(isolate_, &unique_str); |
| 154 // Ensure that our particular zone is visited. | 153 // Ensure that our particular zone is visited. |
| 155 isolate_->IterateObjectPointers( | 154 isolate_->IterateObjectPointers(&str_counter, |
| 156 &str_counter, | 155 StackFrameIterator::kValidateFrames); |
| 157 StackFrameIterator::kValidateFrames); | |
| 158 // We should visit the string object exactly once. | 156 // We should visit the string object exactly once. |
| 159 EXPECT_EQ(1, str_counter.count()); | 157 EXPECT_EQ(1, str_counter.count()); |
| 160 } | 158 } |
| 161 } | 159 } |
| 162 Thread::ExitIsolateAsHelper(); | 160 Thread::ExitIsolateAsHelper(); |
| 163 { | 161 { |
| 164 MonitorLocker ml(monitor_); | 162 MonitorLocker ml(monitor_); |
| 165 *done_ = true; | 163 *done_ = true; |
| 166 ml.Notify(); | 164 ml.Notify(); |
| 167 } | 165 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 204 } |
| 207 } | 205 } |
| 208 | 206 |
| 209 | 207 |
| 210 TEST_CASE(ThreadRegistry) { | 208 TEST_CASE(ThreadRegistry) { |
| 211 Isolate* orig = Thread::Current()->isolate(); | 209 Isolate* orig = Thread::Current()->isolate(); |
| 212 Zone* orig_zone = Thread::Current()->zone(); | 210 Zone* orig_zone = Thread::Current()->zone(); |
| 213 char* orig_str = orig_zone->PrintToString("foo"); | 211 char* orig_str = orig_zone->PrintToString("foo"); |
| 214 Dart_ExitIsolate(); | 212 Dart_ExitIsolate(); |
| 215 // Create and enter a new isolate. | 213 // Create and enter a new isolate. |
| 216 Dart_CreateIsolate( | 214 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
| 217 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 215 NULL); |
| 218 Zone* zone0 = Thread::Current()->zone(); | 216 Zone* zone0 = Thread::Current()->zone(); |
| 219 EXPECT(zone0 != orig_zone); | 217 EXPECT(zone0 != orig_zone); |
| 220 Dart_ShutdownIsolate(); | 218 Dart_ShutdownIsolate(); |
| 221 // Create and enter yet another isolate. | 219 // Create and enter yet another isolate. |
| 222 Dart_CreateIsolate( | 220 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
| 223 NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL); | 221 NULL); |
| 224 { | 222 { |
| 225 // Create a stack resource this time, and exercise it. | 223 // Create a stack resource this time, and exercise it. |
| 226 StackZone stack_zone(Thread::Current()); | 224 StackZone stack_zone(Thread::Current()); |
| 227 Zone* zone1 = Thread::Current()->zone(); | 225 Zone* zone1 = Thread::Current()->zone(); |
| 228 EXPECT(zone1 != zone0); | 226 EXPECT(zone1 != zone0); |
| 229 EXPECT(zone1 != orig_zone); | 227 EXPECT(zone1 != orig_zone); |
| 230 } | 228 } |
| 231 Dart_ShutdownIsolate(); | 229 Dart_ShutdownIsolate(); |
| 232 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig)); | 230 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig)); |
| 233 // Original zone should be preserved. | 231 // Original zone should be preserved. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 244 // 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). |
| 245 class SafepointTestTask : public ThreadPool::Task { | 243 class SafepointTestTask : public ThreadPool::Task { |
| 246 public: | 244 public: |
| 247 static const intptr_t kTaskCount; | 245 static const intptr_t kTaskCount; |
| 248 | 246 |
| 249 SafepointTestTask(Isolate* isolate, | 247 SafepointTestTask(Isolate* isolate, |
| 250 Monitor* monitor, | 248 Monitor* monitor, |
| 251 intptr_t* expected_count, | 249 intptr_t* expected_count, |
| 252 intptr_t* total_done, | 250 intptr_t* total_done, |
| 253 intptr_t* exited) | 251 intptr_t* exited) |
| 254 : isolate_(isolate), | 252 : isolate_(isolate), |
| 255 monitor_(monitor), | 253 monitor_(monitor), |
| 256 expected_count_(expected_count), | 254 expected_count_(expected_count), |
| 257 total_done_(total_done), | 255 total_done_(total_done), |
| 258 exited_(exited), | 256 exited_(exited), |
| 259 local_done_(false) {} | 257 local_done_(false) {} |
| 260 | 258 |
| 261 virtual void Run() { | 259 virtual void Run() { |
| 262 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | 260 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); |
| 263 { | 261 { |
| 264 MonitorLocker ml(monitor_); | 262 MonitorLocker ml(monitor_); |
| 265 ++*expected_count_; | 263 ++*expected_count_; |
| 266 } | 264 } |
| 267 Thread* thread = Thread::Current(); | 265 Thread* thread = Thread::Current(); |
| 268 for (int i = reinterpret_cast<intptr_t>(thread); ; ++i) { | 266 for (int i = reinterpret_cast<intptr_t>(thread);; ++i) { |
| 269 StackZone stack_zone(thread); | 267 StackZone stack_zone(thread); |
| 270 Zone* zone = thread->zone(); | 268 Zone* zone = thread->zone(); |
| 271 HANDLESCOPE(thread); | 269 HANDLESCOPE(thread); |
| 272 const intptr_t kUniqueSmi = 928327281; | 270 const intptr_t kUniqueSmi = 928327281; |
| 273 Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi)); | 271 Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi)); |
| 274 if ((i % 100) != 0) { | 272 if ((i % 100) != 0) { |
| 275 // Usually, we just cooperate. | 273 // Usually, we just cooperate. |
| 276 TransitionVMToBlocked transition(thread); | 274 TransitionVMToBlocked transition(thread); |
| 277 } else { | 275 } else { |
| 278 // But occasionally, organize a rendezvous. | 276 // But occasionally, organize a rendezvous. |
| 279 SafepointOperationScope safepoint_scope(thread); | 277 SafepointOperationScope safepoint_scope(thread); |
| 280 ObjectCounter counter(isolate_, &smi); | 278 ObjectCounter counter(isolate_, &smi); |
| 281 isolate_->IterateObjectPointers( | 279 isolate_->IterateObjectPointers(&counter, |
| 282 &counter, | 280 StackFrameIterator::kValidateFrames); |
| 283 StackFrameIterator::kValidateFrames); | |
| 284 { | 281 { |
| 285 MonitorLocker ml(monitor_); | 282 MonitorLocker ml(monitor_); |
| 286 EXPECT_EQ(*expected_count_, counter.count()); | 283 EXPECT_EQ(*expected_count_, counter.count()); |
| 287 } | 284 } |
| 288 UserTag& tag = UserTag::Handle(zone, isolate_->current_tag()); | 285 UserTag& tag = UserTag::Handle(zone, isolate_->current_tag()); |
| 289 if (tag.raw() != isolate_->default_tag()) { | 286 if (tag.raw() != isolate_->default_tag()) { |
| 290 String& label = String::Handle(zone, tag.label()); | 287 String& label = String::Handle(zone, tag.label()); |
| 291 EXPECT(label.Equals("foo")); | 288 EXPECT(label.Equals("foo")); |
| 292 MonitorLocker ml(monitor_); | 289 MonitorLocker ml(monitor_); |
| 293 if (*expected_count_ == kTaskCount && !local_done_) { | 290 if (*expected_count_ == kTaskCount && !local_done_) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 TEST_CASE(SafepointTestDart) { | 335 TEST_CASE(SafepointTestDart) { |
| 339 Isolate* isolate = Thread::Current()->isolate(); | 336 Isolate* isolate = Thread::Current()->isolate(); |
| 340 Monitor monitor; | 337 Monitor monitor; |
| 341 intptr_t expected_count = 0; | 338 intptr_t expected_count = 0; |
| 342 intptr_t total_done = 0; | 339 intptr_t total_done = 0; |
| 343 intptr_t exited = 0; | 340 intptr_t exited = 0; |
| 344 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { | 341 for (int i = 0; i < SafepointTestTask::kTaskCount; i++) { |
| 345 Dart::thread_pool()->Run(new SafepointTestTask( | 342 Dart::thread_pool()->Run(new SafepointTestTask( |
| 346 isolate, &monitor, &expected_count, &total_done, &exited)); | 343 isolate, &monitor, &expected_count, &total_done, &exited)); |
| 347 } | 344 } |
| 348 // Run Dart code on the main thread long enough to allow all helpers | 345 // Run Dart code on the main thread long enough to allow all helpers |
| 349 // to get their verification done and exit. Use a specific UserTag | 346 // to get their verification done and exit. Use a specific UserTag |
| 350 // to enable the helpers to verify that the main thread is | 347 // to enable the helpers to verify that the main thread is |
| 351 // successfully interrupted in the pure Dart loop. | 348 // successfully interrupted in the pure Dart loop. |
| 352 #if defined(USING_SIMULATOR) | 349 #if defined(USING_SIMULATOR) |
| 353 const intptr_t kLoopCount = 12345678; | 350 const intptr_t kLoopCount = 12345678; |
| 354 #else | 351 #else |
| 355 const intptr_t kLoopCount = 1234567890; | 352 const intptr_t kLoopCount = 1234567890; |
| 356 #endif // USING_SIMULATOR | 353 #endif // USING_SIMULATOR |
| 357 char buffer[1024]; | 354 char buffer[1024]; |
| 358 OS::SNPrint(buffer, sizeof(buffer), | 355 OS::SNPrint(buffer, sizeof(buffer), |
| 359 "import 'dart:developer';\n" | 356 "import 'dart:developer';\n" |
| 360 "int dummy = 0;\n" | 357 "int dummy = 0;\n" |
| 361 "main() {\n" | 358 "main() {\n" |
| 362 " new UserTag('foo').makeCurrent();\n" | 359 " new UserTag('foo').makeCurrent();\n" |
| 363 " for (dummy = 0; dummy < %" Pd "; ++dummy) {\n" | 360 " for (dummy = 0; dummy < %" Pd |
| 364 " dummy += (dummy & 1);\n" | 361 "; ++dummy) {\n" |
| 365 " }\n" | 362 " dummy += (dummy & 1);\n" |
| 366 "}\n", kLoopCount); | 363 " }\n" |
| 364 "}\n", |
| 365 kLoopCount); |
| 367 Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); | 366 Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); |
| 368 EXPECT_VALID(lib); | 367 EXPECT_VALID(lib); |
| 369 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 368 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 370 EXPECT_VALID(result); | 369 EXPECT_VALID(result); |
| 371 // Ensure we looped long enough to allow all helpers to succeed and exit. | 370 // Ensure we looped long enough to allow all helpers to succeed and exit. |
| 372 { | 371 { |
| 373 MonitorLocker ml(&monitor); | 372 MonitorLocker ml(&monitor); |
| 374 while (exited != SafepointTestTask::kTaskCount) { | 373 while (exited != SafepointTestTask::kTaskCount) { |
| 375 ml.Wait(); | 374 ml.Wait(); |
| 376 } | 375 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 // on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details. | 483 // on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details. |
| 485 TEST_CASE(ThreadIterator_AddFindRemove) { | 484 TEST_CASE(ThreadIterator_AddFindRemove) { |
| 486 ThreadIteratorTestParams params; | 485 ThreadIteratorTestParams params; |
| 487 params.spawned_thread_id = OSThread::kInvalidThreadId; | 486 params.spawned_thread_id = OSThread::kInvalidThreadId; |
| 488 params.monitor = new Monitor(); | 487 params.monitor = new Monitor(); |
| 489 | 488 |
| 490 { | 489 { |
| 491 MonitorLocker ml(params.monitor); | 490 MonitorLocker ml(params.monitor); |
| 492 EXPECT(params.spawned_thread_id == OSThread::kInvalidThreadId); | 491 EXPECT(params.spawned_thread_id == OSThread::kInvalidThreadId); |
| 493 // Spawn thread and wait to receive the thread id. | 492 // Spawn thread and wait to receive the thread id. |
| 494 OSThread::Start("ThreadIteratorTest", | 493 OSThread::Start("ThreadIteratorTest", ThreadIteratorTestMain, |
| 495 ThreadIteratorTestMain, | |
| 496 reinterpret_cast<uword>(¶ms)); | 494 reinterpret_cast<uword>(¶ms)); |
| 497 while (params.spawned_thread_id == OSThread::kInvalidThreadId) { | 495 while (params.spawned_thread_id == OSThread::kInvalidThreadId) { |
| 498 ml.Wait(); | 496 ml.Wait(); |
| 499 } | 497 } |
| 500 EXPECT(params.spawned_thread_id != OSThread::kInvalidThreadId); | 498 EXPECT(params.spawned_thread_id != OSThread::kInvalidThreadId); |
| 501 EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId); | 499 EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId); |
| 502 OSThread::Join(params.spawned_thread_join_id); | 500 OSThread::Join(params.spawned_thread_join_id); |
| 503 } | 501 } |
| 504 | 502 |
| 505 EXPECT(!OSThread::IsThreadInList(params.spawned_thread_id)) | 503 EXPECT(!OSThread::IsThreadInList(params.spawned_thread_id)) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 if (exited == SafepointTestTask::kTaskCount) { | 577 if (exited == SafepointTestTask::kTaskCount) { |
| 580 all_exited = true; | 578 all_exited = true; |
| 581 } | 579 } |
| 582 } | 580 } |
| 583 } while (!all_exited); | 581 } while (!all_exited); |
| 584 } | 582 } |
| 585 | 583 |
| 586 | 584 |
| 587 class AllocAndGCTask : public ThreadPool::Task { | 585 class AllocAndGCTask : public ThreadPool::Task { |
| 588 public: | 586 public: |
| 589 AllocAndGCTask(Isolate* isolate, | 587 AllocAndGCTask(Isolate* isolate, Monitor* done_monitor, bool* done) |
| 590 Monitor* done_monitor, | 588 : isolate_(isolate), done_monitor_(done_monitor), done_(done) {} |
| 591 bool* done) | |
| 592 : isolate_(isolate), | |
| 593 done_monitor_(done_monitor), | |
| 594 done_(done) { | |
| 595 } | |
| 596 | 589 |
| 597 virtual void Run() { | 590 virtual void Run() { |
| 598 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | 591 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); |
| 599 { | 592 { |
| 600 Thread* thread = Thread::Current(); | 593 Thread* thread = Thread::Current(); |
| 601 StackZone stack_zone(thread); | 594 StackZone stack_zone(thread); |
| 602 Zone* zone = stack_zone.GetZone(); | 595 Zone* zone = stack_zone.GetZone(); |
| 603 HANDLESCOPE(thread); | 596 HANDLESCOPE(thread); |
| 604 String& old_str = String::Handle(zone, String::New("old", Heap::kOld)); | 597 String& old_str = String::Handle(zone, String::New("old", Heap::kOld)); |
| 605 isolate_->heap()->CollectAllGarbage(); | 598 isolate_->heap()->CollectAllGarbage(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 632 TransitionVMToBlocked transition(thread); | 625 TransitionVMToBlocked transition(thread); |
| 633 MonitorLocker ml(&done_monitor); | 626 MonitorLocker ml(&done_monitor); |
| 634 if (done) { | 627 if (done) { |
| 635 break; | 628 break; |
| 636 } | 629 } |
| 637 } | 630 } |
| 638 } | 631 } |
| 639 } | 632 } |
| 640 | 633 |
| 641 } // namespace dart | 634 } // namespace dart |
| OLD | NEW |