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 #if defined(DEBUG) | |
|
zra
2016/12/08 18:54:13
ditto
bkonyi
2016/12/08 20:58:32
Done.
| |
| 209 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { | |
| 210 public: | |
| 211 SimpleTaskWithZoneAllocation(intptr_t id, | |
| 212 Isolate* isolate, | |
| 213 Thread** thread_ptr, | |
| 214 Monitor* sync, | |
| 215 Monitor* monitor, | |
| 216 intptr_t* done_count, | |
| 217 bool* wait) | |
| 218 : id_(id), | |
| 219 isolate_(isolate), | |
| 220 thread_ptr_(thread_ptr), | |
| 221 sync_(sync), | |
| 222 monitor_(monitor), | |
| 223 done_count_(done_count), | |
| 224 wait_(wait) {} | |
| 225 | |
| 226 virtual void Run() { | |
| 227 Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask); | |
| 228 { | |
| 229 Thread* thread = Thread::Current(); | |
| 230 *thread_ptr_ = thread; | |
| 231 CreateStackZones(id_); | |
| 232 } | |
| 233 Thread::ExitIsolateAsHelper(); | |
| 234 // Notify the main thread that this thread has exited. | |
| 235 { | |
| 236 MonitorLocker ml(monitor_); | |
| 237 *done_count_ += 1; | |
| 238 ml.Notify(); | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 private: | |
| 243 void CreateStackZones(intptr_t num) { | |
| 244 Thread* thread = Thread::Current(); | |
| 245 *thread_ptr_ = thread; | |
| 246 | |
| 247 StackZone stack_zone(thread); | |
| 248 HANDLESCOPE(thread); | |
| 249 Zone* zone = thread->zone(); | |
| 250 EXPECT_EQ(zone, stack_zone.GetZone()); | |
| 251 | |
| 252 // Create a zone (which is also a stack resource) and exercise it a bit. | |
| 253 ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1); | |
| 254 GrowableArray<bool> a1(zone, 1); | |
| 255 for (intptr_t i = 0; i < 1000 * num + id_; ++i) { | |
| 256 a0->Add(true); | |
| 257 a1.Add(true); | |
| 258 } | |
| 259 | |
| 260 num -= 1; | |
| 261 if (num != 0) { | |
| 262 CreateStackZones(num); | |
| 263 return; | |
| 264 } | |
| 265 { | |
| 266 // Let the main thread know we're done with memory ops on this thread. | |
| 267 MonitorLocker ml(monitor_); | |
| 268 *done_count_ += 1; | |
| 269 ml.Notify(); | |
| 270 } | |
| 271 // Wait for the go-ahead from the main thread to exit. | |
| 272 { | |
| 273 MonitorLocker sync_ml(sync_); | |
| 274 while (*wait_) { | |
| 275 sync_ml.Wait(); | |
| 276 } | |
| 277 } | |
| 278 } | |
|
zra
2016/12/08 18:54:13
missing newline.
bkonyi
2016/12/08 20:58:32
Done.
| |
| 279 intptr_t id_; | |
| 280 Isolate* isolate_; | |
| 281 Thread** thread_ptr_; | |
| 282 Monitor* sync_; | |
| 283 Monitor* monitor_; | |
| 284 intptr_t* done_count_; | |
| 285 bool* wait_; | |
| 286 }; | |
| 287 | |
| 288 | |
| 289 TEST_CASE(ManySimpleTasksWithZones) { | |
| 290 const int kTaskCount = 10; | |
| 291 Monitor monitor; | |
| 292 Monitor sync; | |
| 293 Thread* threads[kTaskCount + 1]; | |
| 294 Isolate* isolate = Thread::Current()->isolate(); | |
| 295 intptr_t done_count = 0; | |
| 296 bool wait = true; | |
| 297 threads[kTaskCount] = Thread::Current(); | |
| 298 | |
| 299 EXPECT(isolate->heap()->GrowthControlState()); | |
| 300 isolate->heap()->DisableGrowthControl(); | |
| 301 for (int i = 0; i < kTaskCount; i++) { | |
|
zra
2016/12/08 18:54:13
intptr_t i
bkonyi
2016/12/08 20:58:32
Done.
| |
| 302 Dart::thread_pool()->Run(new SimpleTaskWithZoneAllocation( | |
| 303 (i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait)); | |
| 304 } | |
| 305 // Wait until all spawned tasks finish their memory operations. | |
| 306 { | |
| 307 MonitorLocker ml(&monitor); | |
| 308 while (done_count < kTaskCount) { | |
| 309 ml.Wait(); | |
| 310 } | |
| 311 // Reset the done counter for use later. | |
| 312 done_count = 0; | |
| 313 } | |
| 314 | |
| 315 JSONStream stream; | |
| 316 Service::PrintJSONForVM(&stream, false); | |
| 317 const char* json = stream.ToCString(); | |
| 318 | |
| 319 // Confirm all expected entries are in the JSON output. | |
| 320 for (int i = 0; i < kTaskCount + 1; i++) { | |
|
zra
2016/12/08 18:54:13
intptr_t i
bkonyi
2016/12/08 20:58:32
Done.
| |
| 321 Thread* thread = threads[i]; | |
| 322 Isolate* thread_isolate = thread->isolate(); | |
| 323 // Buffer can handle any possible input length given types. | |
| 324 char thread_address_buf[96]; | |
| 325 char isolate_address_buf[64]; | |
| 326 Zone* top_zone = thread->zone(); | |
| 327 | |
| 328 // Check that all zones are present with correct sizes. | |
| 329 while (top_zone != NULL) { | |
| 330 char zone_info_buf[96]; | |
| 331 OS::SNPrint(zone_info_buf, sizeof(zone_info_buf), | |
| 332 "\"type\":\"_Zone\"," | |
| 333 "\"capacity\":%ld," | |
| 334 "\"used\":%ld", | |
| 335 top_zone->SizeInBytes(), top_zone->UsedSizeInBytes()); | |
| 336 | |
| 337 EXPECT_SUBSTRING(zone_info_buf, json); | |
| 338 top_zone = top_zone->previous(); | |
| 339 } | |
| 340 | |
| 341 // Check the thread exists and is the correct size. | |
| 342 OS::SNPrint(thread_address_buf, sizeof(thread_address_buf), | |
| 343 "\"type\":\"_Thread\"," | |
| 344 "\"id\":\"threads\\/%" Pd64 "", | |
| 345 thread->os_thread()->trace_id()); | |
| 346 | |
| 347 // Ensure the isolate for each thread is valid. | |
| 348 OS::SNPrint(isolate_address_buf, sizeof(isolate_address_buf), | |
| 349 "\"type\":\"Isolate\"," | |
| 350 "\"fixedId\":true," | |
| 351 "\"id\":\"isolates\\/%" Pd64 "", | |
| 352 static_cast<int64_t>(thread_isolate->main_port())); | |
| 353 | |
| 354 EXPECT_SUBSTRING(thread_address_buf, json); | |
| 355 EXPECT_SUBSTRING(isolate_address_buf, json); | |
| 356 } | |
| 357 | |
| 358 // Unblock the tasks so they can finish. | |
| 359 { | |
| 360 MonitorLocker sync_ml(&sync); | |
| 361 wait = false; | |
| 362 sync_ml.NotifyAll(); | |
| 363 } | |
| 364 // Now wait for them all to exit before destroying the isolate. | |
| 365 { | |
| 366 MonitorLocker ml(&monitor); | |
| 367 while (done_count < kTaskCount) { | |
| 368 ml.Wait(); | |
| 369 } | |
| 370 } | |
| 371 } | |
| 372 #endif | |
| 373 | |
| 374 | |
| 208 TEST_CASE(ThreadRegistry) { | 375 TEST_CASE(ThreadRegistry) { |
| 209 Isolate* orig = Thread::Current()->isolate(); | 376 Isolate* orig = Thread::Current()->isolate(); |
| 210 Zone* orig_zone = Thread::Current()->zone(); | 377 Zone* orig_zone = Thread::Current()->zone(); |
| 211 char* orig_str = orig_zone->PrintToString("foo"); | 378 char* orig_str = orig_zone->PrintToString("foo"); |
| 212 Dart_ExitIsolate(); | 379 Dart_ExitIsolate(); |
| 213 // Create and enter a new isolate. | 380 // Create and enter a new isolate. |
| 214 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, | 381 Dart_CreateIsolate(NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, |
| 215 NULL); | 382 NULL); |
| 216 Zone* zone0 = Thread::Current()->zone(); | 383 Zone* zone0 = Thread::Current()->zone(); |
| 217 EXPECT(zone0 != orig_zone); | 384 EXPECT(zone0 != orig_zone); |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 TransitionVMToBlocked transition(thread); | 792 TransitionVMToBlocked transition(thread); |
| 626 MonitorLocker ml(&done_monitor); | 793 MonitorLocker ml(&done_monitor); |
| 627 if (done) { | 794 if (done) { |
| 628 break; | 795 break; |
| 629 } | 796 } |
| 630 } | 797 } |
| 631 } | 798 } |
| 632 } | 799 } |
| 633 | 800 |
| 634 } // namespace dart | 801 } // namespace dart |
| OLD | NEW |