From 72f8b8d694362890a424f5fa21fef37cee921ecf Mon Sep 17 00:00:00 2001
From: Ben Gamari <bgamari.foss@gmail.com>
Date: Thu, 12 Sep 2013 23:04:10 -0400
Subject: [PATCH] rts: Add getPhysicalMemorySize

---
 rts/posix/OSMem.c | 20 ++++++++++++++++++++
 rts/sm/OSMem.h    |  1 +
 rts/win32/OSMem.c | 18 ++++++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c
index 4328d9d2622e..21d4e5443ca6 100644
--- a/rts/posix/OSMem.c
+++ b/rts/posix/OSMem.c
@@ -263,6 +263,26 @@ W_ getPageSize (void)
     }
 }
 
+/* Returns 0 if physical memory size cannot be identified */
+StgWord64 getPhysicalMemorySize (void)
+{
+    static StgWord64 physMemSize = 0;
+    if (!physMemSize) {
+        long ret;
+        W_ pageSize = getPageSize();
+
+        ret = sysconf(_SC_PHYS_PAGES);
+        if (ret == -1) {
+#if defined(DEBUG)
+            errorBelch("warning: getPhysicsMemorySize: cannot get physical memory size");
+#endif
+            return 0;
+        }
+        physMemSize = ret * pageSize;
+    }
+    return physMemSize;
+}
+
 void setExecutable (void *p, W_ len, rtsBool exec)
 {
     StgWord pageSize = getPageSize();
diff --git a/rts/sm/OSMem.h b/rts/sm/OSMem.h
index a0d615b4249d..db704fc78bb3 100644
--- a/rts/sm/OSMem.h
+++ b/rts/sm/OSMem.h
@@ -17,6 +17,7 @@ void osFreeMBlocks(char *addr, nat n);
 void osReleaseFreeMemory(void);
 void osFreeAllMBlocks(void);
 W_ getPageSize (void);
+StgWord64 getPhysicalMemorySize (void);
 void setExecutable (void *p, W_ len, rtsBool exec);
 
 #include "EndPrivate.h"
diff --git a/rts/win32/OSMem.c b/rts/win32/OSMem.c
index 218b25df1301..f350076c9404 100644
--- a/rts/win32/OSMem.c
+++ b/rts/win32/OSMem.c
@@ -378,6 +378,24 @@ W_ getPageSize (void)
     }
 }
 
+/* Returns 0 if physical memory size cannot be identified */
+StgWord64 getPhysicalMemorySize (void)
+{
+    static StgWord64 physMemSize = 0;
+    if (!physMemSize) {
+        MEMORYSTATUSEX status;
+        status.dwLength = sizeof(status);
+        if (!GlobalMemoryStatusEx(&status)) {
+#if defined(DEBUG)
+            errorBelch("warning: getPhysicalMemorySize: cannot get physical memory size");
+#endif
+            return 0;
+        }
+        physMemSize = status.ullTotalPhys;
+    }
+    return physMemSize;
+}
+
 void setExecutable (void *p, W_ len, rtsBool exec)
 {
     DWORD dwOldProtect = 0;
-- 
GitLab