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 "vm/isolate.h" |
5 #include "include/dart_api.h" | 6 #include "include/dart_api.h" |
6 #include "platform/assert.h" | 7 #include "platform/assert.h" |
7 #include "vm/globals.h" | 8 #include "vm/globals.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" |
11 #include "vm/thread_pool.h" | 11 #include "vm/thread_pool.h" |
12 #include "vm/unit_test.h" | 12 #include "vm/unit_test.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 VM_UNIT_TEST_CASE(IsolateCurrent) { | 16 VM_UNIT_TEST_CASE(IsolateCurrent) { |
17 Dart_Isolate isolate = Dart_CreateIsolate( | 17 Dart_Isolate isolate = Dart_CreateIsolate( |
18 NULL, NULL, bin::core_isolate_snapshot_data, | 18 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 EXPECT_EQ(isolate, Dart_CurrentIsolate()); | 20 EXPECT_EQ(isolate, Dart_CurrentIsolate()); |
21 Dart_ShutdownIsolate(); | 21 Dart_ShutdownIsolate(); |
22 EXPECT_EQ(reinterpret_cast<Dart_Isolate>(NULL), Dart_CurrentIsolate()); | 22 EXPECT_EQ(reinterpret_cast<Dart_Isolate>(NULL), Dart_CurrentIsolate()); |
23 } | 23 } |
24 | 24 |
25 | |
26 // Test to ensure that an exception is thrown if no isolate creation | 25 // Test to ensure that an exception is thrown if no isolate creation |
27 // callback has been set by the embedder when an isolate is spawned. | 26 // callback has been set by the embedder when an isolate is spawned. |
28 TEST_CASE(IsolateSpawn) { | 27 TEST_CASE(IsolateSpawn) { |
29 const char* kScriptChars = | 28 const char* kScriptChars = |
30 "import 'dart:isolate';\n" | 29 "import 'dart:isolate';\n" |
31 // Ignores printed lines. | 30 // Ignores printed lines. |
32 "var _nullPrintClosure = (String line) {};\n" | 31 "var _nullPrintClosure = (String line) {};\n" |
33 "void entry(message) {}\n" | 32 "void entry(message) {}\n" |
34 "int testMain() {\n" | 33 "int testMain() {\n" |
35 " Isolate.spawn(entry, null);\n" | 34 " Isolate.spawn(entry, null);\n" |
(...skipping 28 matching lines...) Expand all Loading... |
64 isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), 0, NULL); | 63 isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), 0, NULL); |
65 Dart_Handle args[1]; | 64 Dart_Handle args[1]; |
66 args[0] = schedule_immediate_closure; | 65 args[0] = schedule_immediate_closure; |
67 url = NewString("dart:async"); | 66 url = NewString("dart:async"); |
68 DART_CHECK_VALID(url); | 67 DART_CHECK_VALID(url); |
69 Dart_Handle async_lib = Dart_LookupLibrary(url); | 68 Dart_Handle async_lib = Dart_LookupLibrary(url); |
70 DART_CHECK_VALID(async_lib); | 69 DART_CHECK_VALID(async_lib); |
71 DART_CHECK_VALID(Dart_Invoke( | 70 DART_CHECK_VALID(Dart_Invoke( |
72 async_lib, NewString("_setScheduleImmediateClosure"), 1, args)); | 71 async_lib, NewString("_setScheduleImmediateClosure"), 1, args)); |
73 | 72 |
74 | |
75 result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL); | 73 result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL); |
76 EXPECT_VALID(result); | 74 EXPECT_VALID(result); |
77 // Run until all ports to isolate are closed. | 75 // Run until all ports to isolate are closed. |
78 result = Dart_RunLoop(); | 76 result = Dart_RunLoop(); |
79 EXPECT_ERROR(result, "Unsupported operation: Isolate.spawn"); | 77 EXPECT_ERROR(result, "Unsupported operation: Isolate.spawn"); |
80 EXPECT(Dart_ErrorHasException(result)); | 78 EXPECT(Dart_ErrorHasException(result)); |
81 Dart_Handle exception_result = Dart_ErrorGetException(result); | 79 Dart_Handle exception_result = Dart_ErrorGetException(result); |
82 EXPECT_VALID(exception_result); | 80 EXPECT_VALID(exception_result); |
83 } | 81 } |
84 | 82 |
85 | |
86 class InterruptChecker : public ThreadPool::Task { | 83 class InterruptChecker : public ThreadPool::Task { |
87 public: | 84 public: |
88 static const intptr_t kTaskCount; | 85 static const intptr_t kTaskCount; |
89 static const intptr_t kIterations; | 86 static const intptr_t kIterations; |
90 | 87 |
91 InterruptChecker(Thread* thread, ThreadBarrier* barrier) | 88 InterruptChecker(Thread* thread, ThreadBarrier* barrier) |
92 : thread_(thread), barrier_(barrier) {} | 89 : thread_(thread), barrier_(barrier) {} |
93 | 90 |
94 virtual void Run() { | 91 virtual void Run() { |
95 Thread::EnterIsolateAsHelper(thread_->isolate(), Thread::kUnknownTask); | 92 Thread::EnterIsolateAsHelper(thread_->isolate(), Thread::kUnknownTask); |
(...skipping 13 matching lines...) Expand all Loading... |
109 } | 106 } |
110 Thread::ExitIsolateAsHelper(); | 107 Thread::ExitIsolateAsHelper(); |
111 barrier_->Exit(); | 108 barrier_->Exit(); |
112 } | 109 } |
113 | 110 |
114 private: | 111 private: |
115 Thread* thread_; | 112 Thread* thread_; |
116 ThreadBarrier* barrier_; | 113 ThreadBarrier* barrier_; |
117 }; | 114 }; |
118 | 115 |
119 | |
120 const intptr_t InterruptChecker::kTaskCount = 5; | 116 const intptr_t InterruptChecker::kTaskCount = 5; |
121 const intptr_t InterruptChecker::kIterations = 10; | 117 const intptr_t InterruptChecker::kIterations = 10; |
122 | 118 |
123 // Test and document usage of Isolate::HasInterruptsScheduled. | 119 // Test and document usage of Isolate::HasInterruptsScheduled. |
124 // | 120 // |
125 // Go through a number of rounds of scheduling interrupts and waiting until all | 121 // Go through a number of rounds of scheduling interrupts and waiting until all |
126 // unsynchronized busy-waiting tasks observe it (in the current implementation, | 122 // unsynchronized busy-waiting tasks observe it (in the current implementation, |
127 // the exact latency depends on cache coherence). Synchronization is then used | 123 // the exact latency depends on cache coherence). Synchronization is then used |
128 // to ensure that the response to the interrupt, i.e., starting a new round, | 124 // to ensure that the response to the interrupt, i.e., starting a new round, |
129 // happens *after* the interrupt is observed. Without this synchronization, the | 125 // happens *after* the interrupt is observed. Without this synchronization, the |
(...skipping 14 matching lines...) Expand all Loading... |
144 thread->ScheduleInterrupts(Thread::kVMInterrupt); | 140 thread->ScheduleInterrupts(Thread::kVMInterrupt); |
145 // Wait for all tasks to observe the interrupt. | 141 // Wait for all tasks to observe the interrupt. |
146 barrier.Sync(); | 142 barrier.Sync(); |
147 // Continue with next round. | 143 // Continue with next round. |
148 uword interrupts = thread->GetAndClearInterrupts(); | 144 uword interrupts = thread->GetAndClearInterrupts(); |
149 EXPECT((interrupts & Thread::kVMInterrupt) != 0); | 145 EXPECT((interrupts & Thread::kVMInterrupt) != 0); |
150 } | 146 } |
151 barrier.Exit(); | 147 barrier.Exit(); |
152 } | 148 } |
153 | 149 |
154 | |
155 class IsolateTestHelper { | 150 class IsolateTestHelper { |
156 public: | 151 public: |
157 static uword GetStackLimit(Thread* thread) { return thread->stack_limit_; } | 152 static uword GetStackLimit(Thread* thread) { return thread->stack_limit_; } |
158 static uword GetSavedStackLimit(Thread* thread) { | 153 static uword GetSavedStackLimit(Thread* thread) { |
159 return thread->saved_stack_limit_; | 154 return thread->saved_stack_limit_; |
160 } | 155 } |
161 static uword GetDeferredInterruptsMask(Thread* thread) { | 156 static uword GetDeferredInterruptsMask(Thread* thread) { |
162 return thread->deferred_interrupts_mask_; | 157 return thread->deferred_interrupts_mask_; |
163 } | 158 } |
164 static uword GetDeferredInterrupts(Thread* thread) { | 159 static uword GetDeferredInterrupts(Thread* thread) { |
165 return thread->deferred_interrupts_; | 160 return thread->deferred_interrupts_; |
166 } | 161 } |
167 }; | 162 }; |
168 | 163 |
169 | |
170 TEST_CASE(NoOOBMessageScope) { | 164 TEST_CASE(NoOOBMessageScope) { |
171 // EXPECT_EQ is picky about type agreement for its arguments. | 165 // EXPECT_EQ is picky about type agreement for its arguments. |
172 const uword kZero = 0; | 166 const uword kZero = 0; |
173 const uword kMessageInterrupt = Thread::kMessageInterrupt; | 167 const uword kMessageInterrupt = Thread::kMessageInterrupt; |
174 const uword kVMInterrupt = Thread::kVMInterrupt; | 168 const uword kVMInterrupt = Thread::kVMInterrupt; |
175 uword stack_limit; | 169 uword stack_limit; |
176 uword interrupt_bits; | 170 uword interrupt_bits; |
177 | 171 |
178 // Initially no interrupts are scheduled or deferred. | 172 // Initially no interrupts are scheduled or deferred. |
179 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread), | 173 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread), |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 // Restore, then clear interrupts. The world is as it was. | 235 // Restore, then clear interrupts. The world is as it was. |
242 interrupt_bits = thread->GetAndClearInterrupts(); | 236 interrupt_bits = thread->GetAndClearInterrupts(); |
243 EXPECT_EQ(kMessageInterrupt, interrupt_bits); | 237 EXPECT_EQ(kMessageInterrupt, interrupt_bits); |
244 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread), | 238 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread), |
245 IsolateTestHelper::GetSavedStackLimit(thread)); | 239 IsolateTestHelper::GetSavedStackLimit(thread)); |
246 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread)); | 240 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread)); |
247 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread)); | 241 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread)); |
248 } | 242 } |
249 | 243 |
250 } // namespace dart | 244 } // namespace dart |
OLD | NEW |