in cachelib/allocator/CacheAllocator-inl.h [2581:2659]
void CacheAllocator<CacheTrait>::evictForSlabRelease(
const SlabReleaseContext& ctx, Item& item, util::Throttler& throttler) {
XDCHECK(!config_.isEvictionDisabled());
auto startTime = util::getCurrentTimeSec();
while (true) {
stats_.numEvictionAttempts.inc();
// if the item is already in a state where only the moving bit is set,
// nothing needs to be done. We simply need to unmark moving bit and free
// the item.
if (item.isOnlyMoving()) {
item.unmarkMoving();
const auto res =
releaseBackToAllocator(item, RemoveContext::kNormal, false);
XDCHECK(ReleaseRes::kReleased == res);
return;
}
// Since we couldn't move, we now evict this item. Owning handle will be
// the item's handle for regular/normal items and will be the parent
// handle for chained items.
auto owningHandle =
item.isChainedItem()
? evictChainedItemForSlabRelease(item.asChainedItem())
: evictNormalItemForSlabRelease(item);
// we managed to evict the corresponding owner of the item and have the
// last handle for the owner.
if (owningHandle) {
const auto allocInfo =
allocator_->getAllocInfo(static_cast<const void*>(&item));
if (owningHandle->hasChainedItem()) {
(*stats_.chainedItemEvictions)[allocInfo.poolId][allocInfo.classId]
.inc();
} else {
(*stats_.regularItemEvictions)[allocInfo.poolId][allocInfo.classId]
.inc();
}
stats_.numEvictionSuccesses.inc();
// we have the last handle. no longer need to hold on to the moving bit
item.unmarkMoving();
XDCHECK(owningHandle->isExclusive());
// manually decrement the refcount to call releaseBackToAllocator
const auto ref = decRef(*owningHandle);
XDCHECK(ref == 0);
const auto res = releaseBackToAllocator(*owningHandle.release(),
RemoveContext::kEviction, false);
XDCHECK(res == ReleaseRes::kReleased);
return;
}
if (shutDownInProgress_) {
item.unmarkMoving();
allocator_->abortSlabRelease(ctx);
throw exception::SlabReleaseAborted(
folly::sformat("Slab Release aborted while trying to evict"
" Item: {} Pool: {}, Class: {}.",
item.toString(), ctx.getPoolId(), ctx.getClassId()));
}
throttleWith(throttler, [&] {
XLOGF(WARN,
"Spent {} seconds, slab release still trying to evict Item: {}. "
"Pool: {}, Class: {}.",
util::getCurrentTimeSec() - startTime, item.toString(),
ctx.getPoolId(), ctx.getClassId())
<< (item.isChainedItem()
? folly::sformat(" Parent: {}",
item.asChainedItem()
.getParentItem(compressor_)
.toString())
: "");
});
}
}