Chromium Code Reviews| 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" |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 } | 198 } |
| 199 EXPECT(done[i]); | 199 EXPECT(done[i]); |
| 200 if (i % 10 == 0) { | 200 if (i % 10 == 0) { |
| 201 Thread::EnterIsolate(isolate); | 201 Thread::EnterIsolate(isolate); |
| 202 } | 202 } |
| 203 EXPECT(bar.Equals("bar")); | 203 EXPECT(bar.Equals("bar")); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 | 206 |
| 207 | 207 |
| 208 #ifndef RELEASE | |
| 209 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { | |
| 210 public: | |
| 211 SimpleTaskWithZoneAllocation(Isolate* isolate, | |
| 212 Thread** thread_ptr, | |
| 213 Monitor* sync, | |
| 214 Monitor* monitor, | |
| 215 bool* done, | |
| 216 bool* wait) | |
| 217 : isolate_(isolate), | |
| 218 thread_ptr_(thread_ptr), | |
| 219 sync_(sync), | |
| 220 monitor_(monitor), | |
| 221 done_(done), | |
| 222 wait_(wait) {} | |
| 223 | |
| 224 virtual void Run() { | |
| 225 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | |
| 226 { | |
| 227 Thread* thread = Thread::Current(); | |
| 228 *thread_ptr_ = thread; | |
| 229 | |
| 230 // Create a zone (which is also a stack resource) and exercise it a bit. | |
| 231 StackZone stack_zone(thread); | |
| 232 HANDLESCOPE(thread); | |
| 233 Zone* zone = thread->zone(); | |
| 234 EXPECT_EQ(zone, stack_zone.GetZone()); | |
| 235 ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1); | |
| 236 GrowableArray<bool> a1(zone, 1); | |
| 237 for (intptr_t i = 0; i < 100000; ++i) { | |
| 238 a0->Add(true); | |
| 239 a1.Add(true); | |
| 240 } | |
| 241 // Let the main thread know we're done with memory ops on this thread. | |
| 242 { | |
| 243 MonitorLocker ml(monitor_); | |
| 244 *done_ = true; | |
| 245 ml.Notify(); | |
| 246 } | |
| 247 // Wait for the go-ahead from the main thread to exit. | |
| 248 { | |
| 249 MonitorLocker sync_ml(sync_); | |
| 250 while (*wait_) { | |
| 251 sync_ml.Wait(); | |
| 252 } | |
| 253 } | |
| 254 } | |
| 255 Thread::ExitIsolateAsHelper(); | |
| 256 // Notify the main thread that this thread has exited. | |
| 257 { | |
| 258 MonitorLocker ml(monitor_); | |
| 259 *done_ = true; | |
| 260 ml.Notify(); | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 private: | |
| 265 Isolate* isolate_; | |
| 266 Thread** thread_ptr_; | |
| 267 Monitor* sync_; | |
| 268 Monitor* monitor_; | |
| 269 Monitor* done_monitor_; | |
| 270 bool* done_; | |
| 271 bool* wait_; | |
| 272 }; | |
| 273 | |
| 274 | |
| 275 VM_TEST_CASE(ManySimpleTasksWithZones) { | |
| 276 const int kTaskCount = 10; | |
| 277 Monitor monitor[kTaskCount]; | |
| 278 Monitor sync; | |
| 279 Thread* threads[kTaskCount + 1]; | |
| 280 Isolate* isolate = Thread::Current()->isolate(); | |
| 281 bool done[kTaskCount]; | |
| 282 bool wait = true; | |
| 283 threads[kTaskCount] = Thread::Current(); | |
| 284 | |
| 285 EXPECT(isolate->heap()->GrowthControlState()); | |
| 286 isolate->heap()->DisableGrowthControl(); | |
| 287 for (int i = 0; i < kTaskCount; i++) { | |
| 288 done[i] = false; | |
| 289 Dart::thread_pool()->Run(new SimpleTaskWithZoneAllocation( | |
| 290 isolate, &threads[i], &sync, &monitor[i], &done[i], &wait)); | |
| 291 } | |
| 292 // Wait until all spawned tasks finish their memory operations. | |
| 293 for (int i = 0; i < kTaskCount; i++) { | |
| 294 MonitorLocker ml(&monitor[i]); | |
| 295 while (!done[i]) { | |
| 296 ml.Wait(); | |
| 297 } | |
| 298 // Reset flag to be reused later. | |
| 299 done[i] = false; | |
| 300 } | |
|
siva
2016/12/07 22:12:53
Why does this have to use so many monitors one for
| |
| 301 | |
| 302 JSONStream stream; | |
| 303 Isolate::PrintAllIsolatesMemoryInfoToJSONLocked(&stream); | |
| 304 const char* json = stream.ToCString(); | |
| 305 | |
| 306 // Confirm all expected entries are in the JSON output. | |
| 307 for (int i = 0; i < kTaskCount + 1; i++) { | |
| 308 Thread* thread = threads[i]; | |
| 309 Isolate* thread_isolate = thread->isolate(); | |
| 310 // Buffer can handle any possible input length given types. | |
| 311 char thread_address_buf[96]; | |
| 312 char isolate_address_buf[64]; | |
| 313 intptr_t thread_zone_size_total = 0; | |
| 314 Zone* top_zone = thread->zone(); | |
| 315 | |
| 316 // Check that all zones are present with correct sizes. | |
| 317 while (top_zone != NULL) { | |
| 318 char zone_info_buf[64]; | |
| 319 snprintf(zone_info_buf, sizeof(zone_info_buf), | |
| 320 "\"address\":\"0x%" Px "\",\"size\":%ld", | |
| 321 reinterpret_cast<uword>(top_zone), top_zone->SizeInBytes()); | |
| 322 | |
| 323 EXPECT_SUBSTRING(zone_info_buf, json); | |
| 324 thread_zone_size_total += top_zone->SizeInBytes(); | |
| 325 top_zone = top_zone->previous(); | |
| 326 } | |
| 327 | |
| 328 // Check the thread exists and is the correct size. | |
| 329 snprintf(thread_address_buf, sizeof(thread_address_buf), | |
| 330 "\"thread_address\":\"0x%" Px | |
| 331 "\",\"thread_zone_size_total\":\"%ld\"", | |
| 332 reinterpret_cast<uword>(thread), thread_zone_size_total); | |
| 333 | |
| 334 // Ensure the isolate for each thread is valid. | |
| 335 snprintf(isolate_address_buf, sizeof(isolate_address_buf), | |
| 336 "\"isolate_address\":\"0x%" Px "\"", | |
| 337 reinterpret_cast<uword>(thread_isolate)); | |
| 338 | |
| 339 EXPECT_SUBSTRING(thread_address_buf, json); | |
| 340 EXPECT_SUBSTRING(isolate_address_buf, json); | |
| 341 } | |
| 342 | |
| 343 // Unblock the tasks so they can finish. | |
| 344 { | |
| 345 MonitorLocker sync_ml(&sync); | |
| 346 wait = false; | |
| 347 sync_ml.NotifyAll(); | |
| 348 } | |
| 349 // Now wait for them all to exit before destroying the isolate. | |
| 350 for (int i = 0; i < kTaskCount; i++) { | |
| 351 MonitorLocker ml(&monitor[i]); | |
| 352 while (!done[i]) { | |
| 353 ml.Wait(); | |
| 354 } | |
| 355 } | |
|
siva
2016/12/07 22:12:53
Ditto comment about waiting for tasks to exit, cou
| |
| 356 } | |
| 357 #endif | |
| 358 | |
| 359 | |
| 208 TEST_CASE(ThreadRegistry) { | 360 TEST_CASE(ThreadRegistry) { |
| 209 Isolate* orig = Thread::Current()->isolate(); | 361 Isolate* orig = Thread::Current()->isolate(); |
| 210 Zone* orig_zone = Thread::Current()->zone(); | 362 Zone* orig_zone = Thread::Current()->zone(); |
| 211 char* orig_str = orig_zone->PrintToString("foo"); | 363 char* orig_str = orig_zone->PrintToString("foo"); |
| 212 Dart_ExitIsolate(); | 364 Dart_ExitIsolate(); |
| 213 // Create and enter a new isolate. | 365 // Create and enter a new isolate. |
| 214 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, | 366 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
| 215 NULL); | 367 NULL); |
| 216 Zone* zone0 = Thread::Current()->zone(); | 368 Zone* zone0 = Thread::Current()->zone(); |
| 217 EXPECT(zone0 != orig_zone); | 369 EXPECT(zone0 != orig_zone); |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 TransitionVMToBlocked transition(thread); | 777 TransitionVMToBlocked transition(thread); |
| 626 MonitorLocker ml(&done_monitor); | 778 MonitorLocker ml(&done_monitor); |
| 627 if (done) { | 779 if (done) { |
| 628 break; | 780 break; |
| 629 } | 781 } |
| 630 } | 782 } |
| 631 } | 783 } |
| 632 } | 784 } |
| 633 | 785 |
| 634 } // namespace dart | 786 } // namespace dart |
| OLD | NEW |