PageSizeT getPageSizeInSMap()

in cachelib/shm/ShmCommon.cpp [112:158]


PageSizeT getPageSizeInSMap(void* addr) {
  std::string smapContent;
  folly::readFile("/proc/self/smaps", smapContent);
  const auto smapLines = getSmapLines(smapContent);

  bool foundMatching = false;
  for (auto line : smapLines) {
    const bool isAddr = isAddressLine(line);
    if (!foundMatching && isAddr &&
        lineAddressMatches(line, reinterpret_cast<uintptr_t>(addr))) {
      foundMatching = true;
      continue;
    }

    if (!foundMatching) {
      continue;
    }

    XDCHECK(foundMatching);
    XDCHECK(!isAddr);

    // Format is the following
    // KernelPageSize:        4 kB
    folly::StringPiece fieldName, value;
    folly::split(":", line, fieldName, value);
    if (fieldName != "MMUPageSize") {
      continue;
    }

    value = folly::skipWhitespace(value);

    folly::StringPiece sizeVal;
    folly::StringPiece unitVal;
    folly::split(" ", value, sizeVal, unitVal);
    XDCHECK_EQ(unitVal, "kB");
    size_t size = folly::to<size_t>(sizeVal) * 1024;
    if (size == getPageSize(PageSizeT::TWO_MB)) {
      return PageSizeT::TWO_MB;
    } else if (size == getPageSize(PageSizeT::ONE_GB)) {
      return PageSizeT::ONE_GB;
    } else {
      XDCHECK_EQ(size, getPageSize());
      return PageSizeT::NORMAL;
    }
  }
  throw std::invalid_argument("address mapping not found in /proc/self/smaps");
}