Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: runtime/vm/isolate_test.cc

Issue 1812753002: - Move (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 Dart_Handle exception_result = Dart_ErrorGetException(result); 82 Dart_Handle exception_result = Dart_ErrorGetException(result);
83 EXPECT_VALID(exception_result); 83 EXPECT_VALID(exception_result);
84 } 84 }
85 85
86 86
87 class InterruptChecker : public ThreadPool::Task { 87 class InterruptChecker : public ThreadPool::Task {
88 public: 88 public:
89 static const intptr_t kTaskCount; 89 static const intptr_t kTaskCount;
90 static const intptr_t kIterations; 90 static const intptr_t kIterations;
91 91
92 InterruptChecker(Isolate* isolate, 92 InterruptChecker(Thread* thread, ThreadBarrier* barrier)
93 ThreadBarrier* barrier) 93 : thread_(thread),
94 : isolate_(isolate),
95 barrier_(barrier) { 94 barrier_(barrier) {
96 } 95 }
97 96
98 virtual void Run() { 97 virtual void Run() {
99 Thread::EnterIsolateAsHelper(isolate_); 98 Thread::EnterIsolateAsHelper(thread_->isolate());
100 // Tell main thread that we are ready. 99 // Tell main thread that we are ready.
101 barrier_->Sync(); 100 barrier_->Sync();
102 for (intptr_t i = 0; i < kIterations; ++i) { 101 for (intptr_t i = 0; i < kIterations; ++i) {
103 // Busy wait for interrupts. 102 // Busy wait for interrupts.
104 while (!isolate_->HasInterruptsScheduled(Isolate::kVMInterrupt)) { 103 uword limit = 0;
105 // Do nothing. 104 do {
106 } 105 limit = AtomicOperations::LoadRelaxed(
106 reinterpret_cast<uword*>(thread_->stack_limit_address()));
107 } while ((limit == thread_->saved_stack_limit_) ||
108 (((limit & Thread::kInterruptsMask) &
109 Thread::kVMInterrupt) == 0));
107 // Tell main thread that we observed the interrupt. 110 // Tell main thread that we observed the interrupt.
108 barrier_->Sync(); 111 barrier_->Sync();
109 } 112 }
110 Thread::ExitIsolateAsHelper(); 113 Thread::ExitIsolateAsHelper();
111 barrier_->Exit(); 114 barrier_->Exit();
112 } 115 }
113 116
114 private: 117 private:
115 Isolate* isolate_; 118 Thread* thread_;
116 ThreadBarrier* barrier_; 119 ThreadBarrier* barrier_;
117 }; 120 };
118 121
119 122
120 const intptr_t InterruptChecker::kTaskCount = 5; 123 const intptr_t InterruptChecker::kTaskCount = 5;
121 const intptr_t InterruptChecker::kIterations = 10; 124 const intptr_t InterruptChecker::kIterations = 10;
122 125
123 // Test and document usage of Isolate::HasInterruptsScheduled. 126 // Test and document usage of Isolate::HasInterruptsScheduled.
124 // 127 //
125 // Go through a number of rounds of scheduling interrupts and waiting until all 128 // Go through a number of rounds of scheduling interrupts and waiting until all
126 // unsynchronized busy-waiting tasks observe it (in the current implementation, 129 // unsynchronized busy-waiting tasks observe it (in the current implementation,
127 // the exact latency depends on cache coherence). Synchronization is then used 130 // 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, 131 // 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 132 // happens *after* the interrupt is observed. Without this synchronization, the
130 // compiler and/or CPU could reorder operations to make the tasks observe the 133 // compiler and/or CPU could reorder operations to make the tasks observe the
131 // round update *before* the interrupt is set. 134 // round update *before* the interrupt is set.
132 TEST_CASE(StackLimitInterrupts) { 135 TEST_CASE(StackLimitInterrupts) {
133 Isolate* isolate = Thread::Current()->isolate(); 136 Isolate* isolate = thread->isolate();
134 ThreadBarrier barrier(InterruptChecker::kTaskCount + 1, 137 ThreadBarrier barrier(InterruptChecker::kTaskCount + 1,
135 isolate->heap()->barrier(), 138 isolate->heap()->barrier(),
136 isolate->heap()->barrier_done()); 139 isolate->heap()->barrier_done());
137 // Start all tasks. They will busy-wait until interrupted in the first round. 140 // Start all tasks. They will busy-wait until interrupted in the first round.
138 for (intptr_t task = 0; task < InterruptChecker::kTaskCount; task++) { 141 for (intptr_t task = 0; task < InterruptChecker::kTaskCount; task++) {
139 Dart::thread_pool()->Run(new InterruptChecker(isolate, &barrier)); 142 Dart::thread_pool()->Run(new InterruptChecker(thread, &barrier));
140 } 143 }
141 // Wait for all tasks to get ready for the first round. 144 // Wait for all tasks to get ready for the first round.
142 barrier.Sync(); 145 barrier.Sync();
143 for (intptr_t i = 0; i < InterruptChecker::kIterations; ++i) { 146 for (intptr_t i = 0; i < InterruptChecker::kIterations; ++i) {
144 isolate->ScheduleInterrupts(Isolate::kVMInterrupt); 147 thread->ScheduleInterrupts(Thread::kVMInterrupt);
145 // Wait for all tasks to observe the interrupt. 148 // Wait for all tasks to observe the interrupt.
146 barrier.Sync(); 149 barrier.Sync();
147 // Continue with next round. 150 // Continue with next round.
148 uword interrupts = isolate->GetAndClearInterrupts(); 151 uword interrupts = thread->GetAndClearInterrupts();
149 EXPECT((interrupts & Isolate::kVMInterrupt) != 0); 152 EXPECT((interrupts & Thread::kVMInterrupt) != 0);
150 } 153 }
151 barrier.Exit(); 154 barrier.Exit();
152 } 155 }
153 156
154 157
155 class IsolateTestHelper { 158 class IsolateTestHelper {
156 public: 159 public:
157 static uword GetStackLimit(Isolate* isolate) { 160 static uword GetStackLimit(Thread* thread) {
158 return isolate->stack_limit_; 161 return thread->stack_limit_;
159 } 162 }
160 static uword GetSavedStackLimit(Isolate* isolate) { 163 static uword GetSavedStackLimit(Thread* thread) {
161 return isolate->saved_stack_limit_; 164 return thread->saved_stack_limit_;
162 } 165 }
163 static uword GetDeferredInterruptsMask(Isolate* isolate) { 166 static uword GetDeferredInterruptsMask(Thread* thread) {
164 return isolate->deferred_interrupts_mask_; 167 return thread->deferred_interrupts_mask_;
165 } 168 }
166 static uword GetDeferredInterrupts(Isolate* isolate) { 169 static uword GetDeferredInterrupts(Thread* thread) {
167 return isolate->deferred_interrupts_; 170 return thread->deferred_interrupts_;
168 } 171 }
169 }; 172 };
170 173
171 174
172 TEST_CASE(NoOOBMessageScope) { 175 TEST_CASE(NoOOBMessageScope) {
173 // EXPECT_EQ is picky about type agreement for its arguments. 176 // EXPECT_EQ is picky about type agreement for its arguments.
174 const uword kZero = 0; 177 const uword kZero = 0;
175 const uword kMessageInterrupt = Isolate::kMessageInterrupt; 178 const uword kMessageInterrupt = Thread::kMessageInterrupt;
176 const uword kVMInterrupt = Isolate::kVMInterrupt; 179 const uword kVMInterrupt = Thread::kVMInterrupt;
177 uword stack_limit; 180 uword stack_limit;
178 uword interrupt_bits; 181 uword interrupt_bits;
179 182
180 // Initially no interrupts are scheduled or deferred. 183 // Initially no interrupts are scheduled or deferred.
181 Isolate* isolate = Thread::Current()->isolate(); 184 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread),
182 EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), 185 IsolateTestHelper::GetSavedStackLimit(thread));
183 IsolateTestHelper::GetSavedStackLimit(isolate)); 186 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread));
184 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 187 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread));
185 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate));
186 188
187 { 189 {
188 // Defer message interrupts. 190 // Defer message interrupts.
189 NoOOBMessageScope no_msg_scope(Thread::Current()); 191 NoOOBMessageScope no_msg_scope(thread);
190 EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), 192 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread),
191 IsolateTestHelper::GetSavedStackLimit(isolate)); 193 IsolateTestHelper::GetSavedStackLimit(thread));
192 EXPECT_EQ(kMessageInterrupt, 194 EXPECT_EQ(kMessageInterrupt,
193 IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 195 IsolateTestHelper::GetDeferredInterruptsMask(thread));
194 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); 196 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread));
195 197
196 // Schedule a message, it is deferred. 198 // Schedule a message, it is deferred.
197 isolate->ScheduleInterrupts(Isolate::kMessageInterrupt); 199 thread->ScheduleInterrupts(Thread::kMessageInterrupt);
198 EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), 200 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread),
199 IsolateTestHelper::GetSavedStackLimit(isolate)); 201 IsolateTestHelper::GetSavedStackLimit(thread));
200 EXPECT_EQ(kMessageInterrupt, 202 EXPECT_EQ(kMessageInterrupt,
201 IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 203 IsolateTestHelper::GetDeferredInterruptsMask(thread));
202 EXPECT_EQ(kMessageInterrupt, 204 EXPECT_EQ(kMessageInterrupt,
203 IsolateTestHelper::GetDeferredInterrupts(isolate)); 205 IsolateTestHelper::GetDeferredInterrupts(thread));
204 206
205 // Schedule a vm interrupt, it is not deferred. 207 // Schedule a vm interrupt, it is not deferred.
206 isolate->ScheduleInterrupts(Isolate::kVMInterrupt); 208 thread->ScheduleInterrupts(Thread::kVMInterrupt);
207 stack_limit = IsolateTestHelper::GetStackLimit(isolate); 209 stack_limit = IsolateTestHelper::GetStackLimit(thread);
208 EXPECT_NE(stack_limit, IsolateTestHelper::GetSavedStackLimit(isolate)); 210 EXPECT_NE(stack_limit, IsolateTestHelper::GetSavedStackLimit(thread));
209 EXPECT((stack_limit & Isolate::kVMInterrupt) != 0); 211 EXPECT((stack_limit & Thread::kVMInterrupt) != 0);
210 EXPECT_EQ(kMessageInterrupt, 212 EXPECT_EQ(kMessageInterrupt,
211 IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 213 IsolateTestHelper::GetDeferredInterruptsMask(thread));
212 EXPECT_EQ(kMessageInterrupt, 214 EXPECT_EQ(kMessageInterrupt,
213 IsolateTestHelper::GetDeferredInterrupts(isolate)); 215 IsolateTestHelper::GetDeferredInterrupts(thread));
214 216
215 // Clear the vm interrupt. Message is still deferred. 217 // Clear the vm interrupt. Message is still deferred.
216 interrupt_bits = isolate->GetAndClearInterrupts(); 218 interrupt_bits = thread->GetAndClearInterrupts();
217 EXPECT_EQ(kVMInterrupt, interrupt_bits); 219 EXPECT_EQ(kVMInterrupt, interrupt_bits);
218 EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), 220 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread),
219 IsolateTestHelper::GetSavedStackLimit(isolate)); 221 IsolateTestHelper::GetSavedStackLimit(thread));
220 EXPECT_EQ(kMessageInterrupt, 222 EXPECT_EQ(kMessageInterrupt,
221 IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 223 IsolateTestHelper::GetDeferredInterruptsMask(thread));
222 EXPECT_EQ(kMessageInterrupt, 224 EXPECT_EQ(kMessageInterrupt,
223 IsolateTestHelper::GetDeferredInterrupts(isolate)); 225 IsolateTestHelper::GetDeferredInterrupts(thread));
224 } 226 }
225 227
226 // Restore message interrupts. Message is now pending. 228 // Restore message interrupts. Message is now pending.
227 stack_limit = IsolateTestHelper::GetStackLimit(isolate); 229 stack_limit = IsolateTestHelper::GetStackLimit(thread);
228 EXPECT_NE(stack_limit, IsolateTestHelper::GetSavedStackLimit(isolate)); 230 EXPECT_NE(stack_limit, IsolateTestHelper::GetSavedStackLimit(thread));
229 EXPECT((stack_limit & Isolate::kMessageInterrupt) != 0); 231 EXPECT((stack_limit & Thread::kMessageInterrupt) != 0);
230 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 232 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread));
231 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); 233 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread));
232 234
233 { 235 {
234 // Defer message interrupts, again. The pending interrupt is deferred. 236 // Defer message interrupts, again. The pending interrupt is deferred.
235 NoOOBMessageScope no_msg_scope(Thread::Current()); 237 NoOOBMessageScope no_msg_scope(thread);
236 EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), 238 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread),
237 IsolateTestHelper::GetSavedStackLimit(isolate)); 239 IsolateTestHelper::GetSavedStackLimit(thread));
238 EXPECT_EQ(kMessageInterrupt, 240 EXPECT_EQ(kMessageInterrupt,
239 IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 241 IsolateTestHelper::GetDeferredInterruptsMask(thread));
240 EXPECT_EQ(kMessageInterrupt, 242 EXPECT_EQ(kMessageInterrupt,
241 IsolateTestHelper::GetDeferredInterrupts(isolate)); 243 IsolateTestHelper::GetDeferredInterrupts(thread));
242 } 244 }
243 245
244 // Restore, then clear interrupts. The world is as it was. 246 // Restore, then clear interrupts. The world is as it was.
245 interrupt_bits = isolate->GetAndClearInterrupts(); 247 interrupt_bits = thread->GetAndClearInterrupts();
246 EXPECT_EQ(kMessageInterrupt, interrupt_bits); 248 EXPECT_EQ(kMessageInterrupt, interrupt_bits);
247 EXPECT_EQ(IsolateTestHelper::GetStackLimit(isolate), 249 EXPECT_EQ(IsolateTestHelper::GetStackLimit(thread),
248 IsolateTestHelper::GetSavedStackLimit(isolate)); 250 IsolateTestHelper::GetSavedStackLimit(thread));
249 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(isolate)); 251 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterruptsMask(thread));
250 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(isolate)); 252 EXPECT_EQ(kZero, IsolateTestHelper::GetDeferredInterrupts(thread));
251 } 253 }
252 254
253 } // namespace dart 255 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698