FOLLY_NORETURN
[folly.git] / folly / experimental / io / HugePages.cpp
index e2deabf52770a042f5e2dc85f6e6dd53a976c4fe..a16b3f6057dbc8415374292a225236282a902e30 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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 {
 
@@ -48,15 +51,23 @@ namespace {
 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)
@@ -124,47 +135,48 @@ HugePageSizeVec getHugePageSizes() {
   // 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;
 }