| 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 "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
| 7 #include "vm/globals.h" | 7 #include "vm/globals.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/lockers.h" | 9 #include "vm/lockers.h" |
| 10 #include "vm/thread_barrier.h" | 10 #include "vm/thread_barrier.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 Dart_Handle test_lib = TestCase::LoadTestScript(kScriptChars, NULL); | 42 Dart_Handle test_lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 43 | 43 |
| 44 // Setup the internal library's 'internalPrint' function. | 44 // Setup the internal library's 'internalPrint' function. |
| 45 // Necessary because asynchronous errors use "print" to print their | 45 // Necessary because asynchronous errors use "print" to print their |
| 46 // stack trace. | 46 // stack trace. |
| 47 Dart_Handle url = NewString("dart:_internal"); | 47 Dart_Handle url = NewString("dart:_internal"); |
| 48 DART_CHECK_VALID(url); | 48 DART_CHECK_VALID(url); |
| 49 Dart_Handle internal_lib = Dart_LookupLibrary(url); | 49 Dart_Handle internal_lib = Dart_LookupLibrary(url); |
| 50 DART_CHECK_VALID(internal_lib); | 50 DART_CHECK_VALID(internal_lib); |
| 51 Dart_Handle print = Dart_GetField(test_lib, NewString("_nullPrintClosure")); | 51 Dart_Handle print = Dart_GetField(test_lib, NewString("_nullPrintClosure")); |
| 52 Dart_Handle result = Dart_SetField(internal_lib, | 52 Dart_Handle result = |
| 53 NewString("_printClosure"), | 53 Dart_SetField(internal_lib, NewString("_printClosure"), print); |
| 54 print); | |
| 55 | 54 |
| 56 DART_CHECK_VALID(result); | 55 DART_CHECK_VALID(result); |
| 57 | 56 |
| 58 // Setup the 'scheduleImmediate' closure. | 57 // Setup the 'scheduleImmediate' closure. |
| 59 url = NewString("dart:isolate"); | 58 url = NewString("dart:isolate"); |
| 60 DART_CHECK_VALID(url); | 59 DART_CHECK_VALID(url); |
| 61 Dart_Handle isolate_lib = Dart_LookupLibrary(url); | 60 Dart_Handle isolate_lib = Dart_LookupLibrary(url); |
| 62 DART_CHECK_VALID(isolate_lib); | 61 DART_CHECK_VALID(isolate_lib); |
| 63 Dart_Handle schedule_immediate_closure = | 62 Dart_Handle schedule_immediate_closure = Dart_Invoke( |
| 64 Dart_Invoke(isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), | 63 isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), 0, NULL); |
| 65 0, NULL); | |
| 66 Dart_Handle args[1]; | 64 Dart_Handle args[1]; |
| 67 args[0] = schedule_immediate_closure; | 65 args[0] = schedule_immediate_closure; |
| 68 url = NewString("dart:async"); | 66 url = NewString("dart:async"); |
| 69 DART_CHECK_VALID(url); | 67 DART_CHECK_VALID(url); |
| 70 Dart_Handle async_lib = Dart_LookupLibrary(url); | 68 Dart_Handle async_lib = Dart_LookupLibrary(url); |
| 71 DART_CHECK_VALID(async_lib); | 69 DART_CHECK_VALID(async_lib); |
| 72 DART_CHECK_VALID(Dart_Invoke( | 70 DART_CHECK_VALID(Dart_Invoke( |
| 73 async_lib, NewString("_setScheduleImmediateClosure"), 1, args)); | 71 async_lib, NewString("_setScheduleImmediateClosure"), 1, args)); |
| 74 | 72 |
| 75 | 73 |
| 76 result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL); | 74 result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL); |
| 77 EXPECT_VALID(result); | 75 EXPECT_VALID(result); |
| 78 // Run until all ports to isolate are closed. | 76 // Run until all ports to isolate are closed. |
| 79 result = Dart_RunLoop(); | 77 result = Dart_RunLoop(); |
| 80 EXPECT_ERROR(result, "Unsupported operation: Isolate.spawn"); | 78 EXPECT_ERROR(result, "Unsupported operation: Isolate.spawn"); |
| 81 EXPECT(Dart_ErrorHasException(result)); | 79 EXPECT(Dart_ErrorHasException(result)); |
| 82 Dart_Handle exception_result = Dart_ErrorGetException(result); | 80 Dart_Handle exception_result = Dart_ErrorGetException(result); |
| 83 EXPECT_VALID(exception_result); | 81 EXPECT_VALID(exception_result); |
| 84 } | 82 } |
| 85 | 83 |
| 86 | 84 |
| 87 class InterruptChecker : public ThreadPool::Task { | 85 class InterruptChecker : public ThreadPool::Task { |
| 88 public: | 86 public: |
| 89 static const intptr_t kTaskCount; | 87 static const intptr_t kTaskCount; |
| 90 static const intptr_t kIterations; | 88 static const intptr_t kIterations; |
| 91 | 89 |
| 92 InterruptChecker(Thread* thread, ThreadBarrier* barrier) | 90 InterruptChecker(Thread* thread, ThreadBarrier* barrier) |
| 93 : thread_(thread), | 91 : thread_(thread), barrier_(barrier) {} |
| 94 barrier_(barrier) { | |
| 95 } | |
| 96 | 92 |
| 97 virtual void Run() { | 93 virtual void Run() { |
| 98 Thread::EnterIsolateAsHelper(thread_->isolate(), Thread::kUnknownTask); | 94 Thread::EnterIsolateAsHelper(thread_->isolate(), Thread::kUnknownTask); |
| 99 // Tell main thread that we are ready. | 95 // Tell main thread that we are ready. |
| 100 barrier_->Sync(); | 96 barrier_->Sync(); |
| 101 for (intptr_t i = 0; i < kIterations; ++i) { | 97 for (intptr_t i = 0; i < kIterations; ++i) { |
| 102 // Busy wait for interrupts. | 98 // Busy wait for interrupts. |
| 103 uword limit = 0; | 99 uword limit = 0; |
| 104 do { | 100 do { |
| 105 limit = AtomicOperations::LoadRelaxed( | 101 limit = AtomicOperations::LoadRelaxed( |
| 106 reinterpret_cast<uword*>(thread_->stack_limit_address())); | 102 reinterpret_cast<uword*>(thread_->stack_limit_address())); |
| 107 } while ((limit == thread_->saved_stack_limit_) || | 103 } while ( |
| 108 (((limit & Thread::kInterruptsMask) & | 104 (limit == thread_->saved_stack_limit_) || |
| 109 Thread::kVMInterrupt) == 0)); | 105 (((limit & Thread::kInterruptsMask) & Thread::kVMInterrupt) == 0)); |
| 110 // Tell main thread that we observed the interrupt. | 106 // Tell main thread that we observed the interrupt. |
| 111 barrier_->Sync(); | 107 barrier_->Sync(); |
| 112 } | 108 } |
| 113 Thread::ExitIsolateAsHelper(); | 109 Thread::ExitIsolateAsHelper(); |
| 114 barrier_->Exit(); | 110 barrier_->Exit(); |
| 115 } | 111 } |
| 116 | 112 |
| 117 private: | 113 private: |
| 118 Thread* thread_; | 114 Thread* thread_; |
| 119 ThreadBarrier* barrier_; | 115 ThreadBarrier* barrier_; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 150 // Continue with next round. | 146 // Continue with next round. |
| 151 uword interrupts = thread->GetAndClearInterrupts(); | 147 uword interrupts = thread->GetAndClearInterrupts(); |
| 152 EXPECT((interrupts & Thread::kVMInterrupt) != 0); | 148 EXPECT((interrupts & Thread::kVMInterrupt) != 0); |
| 153 } | 149 } |
| 154 barrier.Exit(); | 150 barrier.Exit(); |
| 155 } | 151 } |
| 156 | 152 |
| 157 | 153 |
| 158 class IsolateTestHelper { | 154 class IsolateTestHelper { |
| 159 public: | 155 public: |
| 160 static uword GetStackLimit(Thread* thread) { | 156 static uword GetStackLimit(Thread* thread) { return thread->stack_limit_; } |
| 161 return thread->stack_limit_; | |
| 162 } | |
| 163 static uword GetSavedStackLimit(Thread* thread) { | 157 static uword GetSavedStackLimit(Thread* thread) { |
| 164 return thread->saved_stack_limit_; | 158 return thread->saved_stack_limit_; |
| 165 } | 159 } |
| 166 static uword GetDeferredInterruptsMask(Thread* thread) { | 160 static uword GetDeferredInterruptsMask(Thread* thread) { |
| 167 return thread->deferred_interrupts_mask_; | 161 return thread->deferred_interrupts_mask_; |
| 168 } | 162 } |
| 169 static uword GetDeferredInterrupts(Thread* thread) { | 163 static uword GetDeferredInterrupts(Thread* thread) { |
| 170 return thread->deferred_interrupts_; | 164 return thread->deferred_interrupts_; |
| 171 } | 165 } |
| 172 }; | 166 }; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 // Restore, then clear interrupts. The world is as it was. | 240 // Restore, then clear interrupts. The world is as it was. |
| 247 interrupt_bits = thread->GetAndClearInterrupts(); | 241 interrupt_bits = thread->GetAndClearInterrupts(); |
| 248 EXPECT_EQ(kMessageInterrupt, interrupt_bits); | 242 EXPECT_EQ(kMessageInterrupt, interrupt_bits); |
| 249 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread), | 243 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread), |
| 250 IsolateTestHelper::GetSavedStackLimit(thread)); | 244 IsolateTestHelper::GetSavedStackLimit(thread)); |
| 251 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread)); | 245 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread)); |
| 252 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread)); | 246 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread)); |
| 253 } | 247 } |
| 254 | 248 |
| 255 } // namespace dart | 249 } // namespace dart |
| OLD | NEW |