MCPcopy Create free account
hub / github.com/bytedance/bolt / makeSpace

Method makeSpace

bolt/common/caching/AsyncDataCache.cpp:706–802  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

704}
705
706bool AsyncDataCache::makeSpace(
707 MachinePageCount numPages,
708 std::function<bool(memory::Allocation& allocation)> allocate) {
709 // Try to allocate and if failed, evict the desired amount and
710 // retry. This is without synchronization, so that other threads may
711 // get what one thread evicted but this will usually work in a
712 // couple of iterations. If this does not settle within 8 tries, we
713 // start counting the contending threads and doing random backoff to
714 // serialize the evicts and allocates. If a new thread enters when
715 // thread counting and backoff are in effect, it gets a rank at the
716 // end of the queue. The larger the rank, the larger the backoff, so
717 // that first comer is likelier to get the memory. We cannot
718 // serialize with a mutex because memory arbitration must not be
719 // called from inside a global mutex.
720
721 constexpr int32_t kMaxAttempts = kNumShards * 4;
722 // Evict at least 1MB even for small allocations to avoid constantly hitting
723 // the mutex protected evict loop.
724 constexpr int32_t kMinEvictPages = 256;
725 // If requesting less than kSmallSizePages try up to 4x more if
726 // first try failed.
727 constexpr int32_t kSmallSizePages = 2048; // 8MB
728 float sizeMultiplier = 1.2;
729 // True if this thread is counted in 'numThreadsInAllocate_'.
730 bool isCounted = false;
731 // If more than half the allowed retries are needed, this is the rank in
732 // arrival order of this.
733 int32_t rank = 0;
734 // Allocation into which evicted pages are moved.
735 memory::Allocation acquired;
736 // 'acquired' is not managed by a pool. Make sure it is freed on throw.
737 // Destruct without pool and non-empty kills the process.
738 auto guard = folly::makeGuard([&]() {
739 try {
740 allocator_->freeNonContiguous(acquired);
741 } catch (std::exception& e) {
742 LOG(ERROR) << "Exception from freeNonContiguous(): " << e.what();
743 }
744 if (isCounted) {
745 --numThreadsInAllocate_;
746 }
747 });
748 BOLT_CHECK(
749 numThreadsInAllocate_ >= 0 && numThreadsInAllocate_ < 10000,
750 "Leak in numThreadsInAllocate_: {}",
751 numThreadsInAllocate_);
752 if (numThreadsInAllocate_) {
753 rank = ++numThreadsInAllocate_;
754 isCounted = true;
755 }
756 for (auto nthAttempt = 0; nthAttempt < kMaxAttempts; ++nthAttempt) {
757 if (canTryAllocate(numPages, acquired)) {
758 if (allocate(acquired)) {
759 return true;
760 }
761 }
762
763 if (nthAttempt > 2 && ssdCache_ && ssdCache_->writeInProgress()) {

Callers

nothing calls this directly

Calls 7

setCacheFailureMessageFunction · 0.85
writeInProgressMethod · 0.80
toStringFunction · 0.50
freeNonContiguousMethod · 0.45
whatMethod · 0.45
numPagesMethod · 0.45
evictMethod · 0.45

Tested by

no test coverage detected