Implement os::memory() for FreeBSD.

Review: https://reviews.apache.org/r/41726/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/451bdcb7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/451bdcb7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/451bdcb7

Branch: refs/heads/master
Commit: 451bdcb714aebe8bc680bc7068aeee580ee61a04
Parents: d89da4f
Author: David Forsythe <[email protected]>
Authored: Wed Jan 20 14:49:42 2016 -0800
Committer: Ian Downes <[email protected]>
Committed: Wed Jan 20 14:52:46 2016 -0800

----------------------------------------------------------------------
 .../3rdparty/stout/include/stout/posix/os.hpp   | 57 +++++++++++++++++++-
 1 file changed, 55 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/451bdcb7/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp 
b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
index c2b9e3d..74af007 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
@@ -80,9 +80,9 @@
 #ifdef __sun
 #include <stout/os/sunos.hpp>
 #endif // __sun
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__FreeBSD__)
 #include <stout/os/sysctl.hpp>
-#endif // __APPLE__
+#endif // __APPLE__ || __FreeBSD__
 
 #include <stout/os/raw/environment.hpp>
 
@@ -503,6 +503,8 @@ inline Try<Memory> memory()
 {
   Memory memory;
 
+// TODO(dforsyth): Refactor these implementations into seperate, platform
+// specific files.
 #ifdef __linux__
   struct sysinfo info;
   if (sysinfo(&info) != 0) {
@@ -566,6 +568,57 @@ inline Try<Memory> memory()
 
   return memory;
 
+#elif defined __FreeBSD__
+  const Try<int64_t> physicalMemory = os::sysctl(CTL_HW, HW_PHYSMEM).integer();
+  if (physicalMemory.isError()) {
+    return Error(physicalMemory.error());
+  }
+  memory.total = Bytes(physicalMemory.get());
+
+  const int pageSize = getpagesize();
+
+  unsigned int freeCount;
+  size_t length = sizeof(freeCount);
+
+  if (sysctlbyname(
+      "vm.stats.v_free_count",
+      &freeCount,
+      &length,
+      NULL,
+      0) != 0) {
+    return ErrnoError();
+  }
+  memory.free = Bytes(freeCount * pageSize);
+
+  int totalBlocks = 0;
+  int usedBlocks = 0;
+
+  int mib[3];
+  size_t mibSize = 2;
+  if (::sysctlnametomib("vm.swap_info", mib, &mibSize) != 0) {
+      return ErrnoError();
+  }
+
+  // FreeBSD supports multiple swap devices. Here we sum across all of them.
+  struct xswdev xswd;
+  size_t xswdSize = sizeof(xswd);
+  int* mibDevice = &(mib[mibSize + 1]);
+  for (*mibDevice = 0; ; (*mibDevice)++) {
+      if (::sysctl(mib, 3, &xswd, &xswdSize, NULL, 0) != 0) {
+          if (errno == ENOENT) {
+              break;
+          }
+          return ErrnoError();
+      }
+
+      totalBlocks += xswd.xsw_nblks;
+      usedBlocks += xswd.xsw_used;
+  }
+
+  memory.totalSwap = Bytes(totalBlocks * pageSize);
+  memory.freeSwap = Bytes((totalBlocks - usedBlocks) * pageSize);
+
+  return memory;
 #else
   return Error("Cannot determine the size of total and free memory");
 #endif

Reply via email to