From 619fd18de0700edb531db5f3836b034489460b88 Mon Sep 17 00:00:00 2001
From: Austin Seipp <austin@well-typed.com>
Date: Sat, 26 Oct 2013 12:50:16 -0500
Subject: [PATCH] Fix getPhysicalMemorySize on OS X (#8481)

Darwin doesn't support _SC_PHYS_PAGES, but we can get the exact number
of bytes of physical memory via 'hw.memsize', so we use that instead.

Signed-off-by: Austin Seipp <austin@well-typed.com>
---
 rts/posix/OSMem.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c
index 21d4e5443ca6..acdb00e3c99d 100644
--- a/rts/posix/OSMem.c
+++ b/rts/posix/OSMem.c
@@ -35,6 +35,7 @@
 #if darwin_HOST_OS
 #include <mach/mach.h>
 #include <mach/vm_map.h>
+#include <sys/sysctl.h>
 #endif
 
 static caddr_t next_request = 0;
@@ -268,10 +269,24 @@ StgWord64 getPhysicalMemorySize (void)
 {
     static StgWord64 physMemSize = 0;
     if (!physMemSize) {
-        long ret;
+#ifdef darwin_HOST_OS
+        /* So, darwin doesn't support _SC_PHYS_PAGES, but it does
+           support getting the raw memory size in bytes through
+           sysctlbyname(hw.memsize); */
+        size_t len = sizeof(physMemSize);
+        int ret = -1;
+
+        /* Note hw.memsize is in bytes, so no need to multiply by page size. */
+        ret = sysctlbyname("hw.memsize", &physMemSize, &len, NULL, 0);
+        if (ret == -1) {
+            physMemSize = 0;
+            return 0;
+        }
+#else
+        /* We'll politely assume we have a system supporting _SC_PHYS_PAGES
+         * otherwise.  */
         W_ pageSize = getPageSize();
-
-        ret = sysconf(_SC_PHYS_PAGES);
+        long ret = sysconf(_SC_PHYS_PAGES);
         if (ret == -1) {
 #if defined(DEBUG)
             errorBelch("warning: getPhysicsMemorySize: cannot get physical memory size");
@@ -279,6 +294,7 @@ StgWord64 getPhysicalMemorySize (void)
             return 0;
         }
         physMemSize = ret * pageSize;
+#endif /* darwin_HOST_OS */
     }
     return physMemSize;
 }
-- 
GitLab