void MemoryMonitor::checkPoolsAndAdviseReclaim()

in cachelib/allocator/MemoryMonitor.cpp [150:222]


void MemoryMonitor::checkPoolsAndAdviseReclaim() {
  auto results = cache_.calcNumSlabsToAdviseReclaim();
  if (results.poolAdviseReclaimMap.empty()) {
    return;
  }
  // all result would either be advise or reclaim. It is not possible for
  // some of them to be advise and some to reclaim

  // Advise slabs, if marked for advise
  if (results.advise) {
    for (auto& result : results.poolAdviseReclaimMap) {
      uint64_t slabsAdvised = 0;
      PoolId poolId = result.first;
      uint64_t slabsToAdvise = result.second;
      while (slabsAdvised < slabsToAdvise) {
        const auto classId = strategy_->pickVictimForResizing(cache_, poolId);
        if (classId == Slab::kInvalidClassId) {
          break;
        }
        try {
          const auto now = util::getCurrentTimeMs();
          auto stats = cache_.getPoolStats(poolId);
          cache_.releaseSlab(poolId, classId, SlabReleaseMode::kAdvise);
          ++slabsAdvised;
          const auto elapsed_time =
              static_cast<uint64_t>(util::getCurrentTimeMs() - now);
          stats.numSlabsForClass(classId);
          stats.evictionAgeForClass(classId);
          // Log the event about the Pool which released the Slab along with
          // the number of slabs.
          stats_.addSlabReleaseEvent(
              classId, Slab::kInvalidClassId, /* No Class info */
              elapsed_time, poolId, stats.numSlabsForClass(classId),
              0 /* receiver slabs */, stats.allocSizeForClass(classId),
              0 /* receiver alloc size */, stats.evictionAgeForClass(classId),
              0 /* receiver eviction age */,
              stats.numFreeAllocsForClass(classId));

        } catch (const exception::SlabReleaseAborted& e) {
          XLOGF(WARN,
                "Aborted trying to advise away a slab from pool {} for"
                " allocation class {}. Error: {}",
                static_cast<int>(poolId), static_cast<int>(classId), e.what());
          return;
        } catch (const std::exception& e) {
          XLOGF(
              CRITICAL,
              "Error trying to advise away a slab from pool {} for allocation "
              "class {}. Error: {}",
              static_cast<int>(poolId), static_cast<int>(classId), e.what());
        }
      }
      slabsAdvised_ += slabsAdvised;
      XLOGF(DBG, "Advised away {} slabs from Pool ID: {}, to free {} bytes",
            slabsAdvised, static_cast<int>(poolId), slabsAdvised * Slab::kSize);
    }
    return;
  } else {
    XDCHECK(!results.advise);
    // Reclaim slabs, if marked for reclaim
    for (auto& result : results.poolAdviseReclaimMap) {
      PoolId poolId = result.first;
      uint64_t slabsToReclaim = result.second;
      auto slabsReclaimed = cache_.reclaimSlabs(poolId, slabsToReclaim);
      XLOGF(
          DBG,
          "Reclaimed {} of {} slabs for Pool ID: {}, to grow cache by {} bytes",
          slabsReclaimed, slabsToReclaim, static_cast<int>(poolId),
          slabsReclaimed * Slab::kSize);
      slabsReclaimed_ += slabsReclaimed;
    }
  }
}