/*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "folly/Range.h"
#include "folly/ScopeGuard.h"
#include "folly/String.h"
-#include "folly/experimental/io/Stream.h"
+
+#include "folly/experimental/Gen.h"
+#include "folly/experimental/FileGen.h"
+#include "folly/experimental/StringGen.h"
namespace folly {
size_t getDefaultHugePageSize() {
// We need to parse /proc/meminfo
static const boost::regex regex(R"!(Hugepagesize:\s*(\d+)\s*kB)!");
+ size_t pageSize = 0;
boost::cmatch match;
- for (auto& byteLine : byLine("/proc/meminfo")) {
- StringPiece line(byteLine);
- if (boost::regex_match(line.begin(), line.end(), match, regex)) {
- StringPiece numStr(line.begin() + match.position(1), match.length(1));
- return to<size_t>(numStr) * 1024; // in KiB
- }
+
+ bool error = gen::byLine("/proc/meminfo") |
+ [&] (StringPiece line) -> bool {
+ if (boost::regex_match(line.begin(), line.end(), match, regex)) {
+ StringPiece numStr(line.begin() + match.position(1), match.length(1));
+ pageSize = to<size_t>(numStr) * 1024; // in KiB
+ return false; // stop
+ }
+ return true;
+ };
+
+ if (error) {
+ throw std::runtime_error("Can't find default huge page size");
}
- throw std::runtime_error("Can't find default huge page size");
+ return pageSize;
}
// Get raw huge page sizes (without mount points, they'll be filled later)
// Read and parse /proc/mounts
std::vector<StringPiece> parts;
std::vector<StringPiece> options;
- for (auto& byteLine : byLine("/proc/mounts")) {
- StringPiece line(byteLine);
- parts.clear();
- split(" ", line, parts);
- // device path fstype options uid gid
- if (parts.size() != 6) {
- throw std::runtime_error("Invalid /proc/mounts line");
- }
- if (parts[2] != "hugetlbfs") {
- continue; // we only care about hugetlbfs
- }
- options.clear();
- split(",", parts[3], options);
- size_t pageSize = defaultHugePageSize;
- // Search for the "pagesize" option, which must have a value
- for (auto& option : options) {
- // key=value
- const char* p = static_cast<const char*>(
- memchr(option.data(), '=', option.size()));
- if (!p) {
- continue;
+ gen::byLine("/proc/mounts") | gen::eachAs<StringPiece>() |
+ [&](StringPiece line) {
+ parts.clear();
+ split(" ", line, parts);
+ // device path fstype options uid gid
+ if (parts.size() != 6) {
+ throw std::runtime_error("Invalid /proc/mounts line");
}
- if (StringPiece(option.data(), p) != "pagesize") {
- continue;
+ if (parts[2] != "hugetlbfs") {
+ return; // we only care about hugetlbfs
}
- pageSize = parsePageSizeValue(StringPiece(p + 1, option.end()));
- break;
- }
- auto pos = std::lower_bound(sizeVec.begin(), sizeVec.end(), pageSize,
- PageSizeLess());
- if (pos == sizeVec.end() || pos->size != pageSize) {
- throw std::runtime_error("Mount page size not found");
- }
- if (pos->mountPoint.empty()) {
- // Store mount point
- pos->mountPoint = fs::canonical(fs::path(parts[1].begin(),
- parts[1].end()));
- }
- }
+ options.clear();
+ split(",", parts[3], options);
+ size_t pageSize = defaultHugePageSize;
+ // Search for the "pagesize" option, which must have a value
+ for (auto& option : options) {
+ // key=value
+ const char* p = static_cast<const char*>(
+ memchr(option.data(), '=', option.size()));
+ if (!p) {
+ continue;
+ }
+ if (StringPiece(option.data(), p) != "pagesize") {
+ continue;
+ }
+ pageSize = parsePageSizeValue(StringPiece(p + 1, option.end()));
+ break;
+ }
+
+ auto pos = std::lower_bound(sizeVec.begin(), sizeVec.end(), pageSize,
+ PageSizeLess());
+ if (pos == sizeVec.end() || pos->size != pageSize) {
+ throw std::runtime_error("Mount page size not found");
+ }
+ if (pos->mountPoint.empty()) {
+ // Store mount point
+ pos->mountPoint = fs::canonical(fs::path(parts[1].begin(),
+ parts[1].end()));
+ }
+ };
return sizeVec;
}