| 524 | } |
| 525 | |
| 526 | void AsyncDataCacheTest::loadLoop( |
| 527 | int64_t startOffset, |
| 528 | int64_t loadBytes, |
| 529 | int32_t errorEveryNBatches, |
| 530 | int32_t largeEveryNBatches, |
| 531 | int32_t largeAllocSize) { |
| 532 | const int64_t maxOffset = |
| 533 | std::max<int64_t>(100'000, (startOffset + loadBytes) / filenames_.size()); |
| 534 | int64_t skippedBytes = 0; |
| 535 | int32_t errorCounter = 0; |
| 536 | int32_t largeCounter = 0; |
| 537 | std::vector<Request> batch; |
| 538 | for (auto i = 0; i < filenames_.size(); ++i) { |
| 539 | const auto fileNum = filenames_[i].id(); |
| 540 | for (uint64_t offset = 100; offset < maxOffset; |
| 541 | offset += sizeAtOffset(offset)) { |
| 542 | const auto size = sizeAtOffset(offset); |
| 543 | if (skippedBytes < startOffset) { |
| 544 | skippedBytes += size; |
| 545 | continue; |
| 546 | } |
| 547 | |
| 548 | batch.emplace_back(offset, size); |
| 549 | if (batch.size() >= 8) { |
| 550 | for (;;) { |
| 551 | if (largeEveryNBatches > 0 && |
| 552 | largeCounter++ % largeEveryNBatches == 0) { |
| 553 | // Many threads will allocate a single large chunk at the |
| 554 | // same time. Some are expected to fail. All will |
| 555 | // eventually succeed because whoever gets the allocation |
| 556 | // frees it soon and without deadlocking with others.. |
| 557 | memory::ContiguousAllocation large; |
| 558 | // Explicitly free 'large' on exit. Do not use MemoryPool for that |
| 559 | // because we test the allocator's limits, not the pool/memory |
| 560 | // manager limits. |
| 561 | auto guard = |
| 562 | folly::makeGuard([&]() { allocator_->freeContiguous(large); }); |
| 563 | while (!allocator_->allocateContiguous( |
| 564 | memory::AllocationTraits::numPages(largeAllocSize), |
| 565 | nullptr, |
| 566 | large)) { |
| 567 | ++numLargeRetries_; |
| 568 | } |
| 569 | std::this_thread::sleep_for( |
| 570 | std::chrono::microseconds(2000)); // NOLINT |
| 571 | } |
| 572 | const bool injectError = (errorEveryNBatches > 0) && |
| 573 | (++errorCounter % errorEveryNBatches == 0); |
| 574 | loadBatch(fileNum, batch, injectError); |
| 575 | try { |
| 576 | checkBatch(fileNum, batch, injectError); |
| 577 | } catch (std::exception& e) { |
| 578 | continue; |
| 579 | } |
| 580 | batch.clear(); |
| 581 | break; |
| 582 | } |
| 583 | } |
nothing calls this directly
no test coverage detected