[MLton-commit] r5810

Matthew Fluet fluet at mlton.org
Thu Aug 2 11:55:30 PDT 2007


Handle ambiguity in the sizes of sysctl lookups.

For NetBSD, we need HW_PHYSMEM64 on 64-bit machines with more than
4GB physical memory, so that the runtime/GC will see the available memory.
(NetBSD specifies that HW_PHYSMEM is a 32-bit quantity.)

But, when using HW_PYSMEM64 for a 32-bit machine with more than 4GB
physical memory, we can't just cast the result to size_t ('cause we'll
just get physmem `mod` 4GB); instead, take the minimum of result and
SIZE_MAX.


Given the ambiguity in sysctl, one could imagine that HW_PHYSMEM on
other 32-bit platforms is a 64-bit value (thereby exposing the >4GB
physical memory available with PAE); so, in any case, we can't return
more than the virtual address space allows.

Switch *-darwin over to using syctl.c for GC_pageSize and GC_totalRam.


----------------------------------------------------------------------

U   mlton/trunk/runtime/platform/darwin.c
U   mlton/trunk/runtime/platform/sysctl.c

----------------------------------------------------------------------

Modified: mlton/trunk/runtime/platform/darwin.c
===================================================================
--- mlton/trunk/runtime/platform/darwin.c	2007-07-30 09:10:33 UTC (rev 5809)
+++ mlton/trunk/runtime/platform/darwin.c	2007-08-02 18:55:29 UTC (rev 5810)
@@ -8,6 +8,7 @@
 #include "mkdir2.c"
 #include "mmap-protect.c"
 #include "nonwin.c"
+#include "sysctl.c"
 #include "use-mmap.c"
 
 code_pointer GC_getTextEnd (void) {
@@ -44,18 +45,3 @@
         sa->sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
         sa->sa_sigaction = (void (*)(int, siginfo_t*, void*))catcher;
 }
-
-size_t GC_pageSize (void) {
-        long int pageSize = sysconf(_SC_PAGESIZE);
-        return (size_t)pageSize;
-}
-
-size_t GC_totalRam (void) {
-        int mem;
-        size_t len;
-
-        len = sizeof (int);
-        if (-1 == sysctlbyname ("hw.physmem", &mem, &len, NULL, 0))
-                diee ("sysctl failed");
-        return mem;
-}

Modified: mlton/trunk/runtime/platform/sysctl.c
===================================================================
--- mlton/trunk/runtime/platform/sysctl.c	2007-07-30 09:10:33 UTC (rev 5809)
+++ mlton/trunk/runtime/platform/sysctl.c	2007-08-02 18:55:29 UTC (rev 5810)
@@ -1,25 +1,91 @@
 size_t GC_pageSize (void) {
-  int pageSize;
   size_t len;
   int mib[2];
 
+  len = 0;
   mib[0] = CTL_HW;
   mib[1] = HW_PAGESIZE;
-  len = sizeof(pageSize);
-  if (-1 == sysctl (mib, 2, &pageSize, &len, NULL, 0))
+  if (-1 == sysctl (mib, 2, NULL, &len, NULL, 0))
     diee ("sysctl failed");
-  return (size_t)pageSize;
+  if (len == sizeof(unsigned long long int)) {
+    unsigned long long int pageSize;
+    if (-1 == sysctl (mib, 2, &pageSize, &len, NULL, 0))
+      diee ("sysctl failed");
+    if (sizeof(size_t) >= sizeof(unsigned long long int)
+        || pageSize <= (unsigned long long int)SIZE_MAX) {
+      return (size_t)pageSize;
+    } else {
+      return (size_t)SIZE_MAX;
+    }
+  } else if (len == sizeof(unsigned long int)) {
+    unsigned long int pageSize;
+    if (-1 == sysctl (mib, 2, &pageSize, &len, NULL, 0))
+      diee ("sysctl failed");
+    if (sizeof(size_t) >= sizeof(unsigned long int)
+        || pageSize <= (unsigned long int)SIZE_MAX) {
+      return (size_t)pageSize;
+    } else {
+      return (size_t)SIZE_MAX;
+    }
+  } else if (len == sizeof(unsigned int)) {
+    unsigned int pageSize;
+    if (-1 == sysctl (mib, 2, &pageSize, &len, NULL, 0))
+      diee ("sysctl failed");
+    if (sizeof(size_t) >= sizeof(unsigned int)
+        || pageSize <= (unsigned int)SIZE_MAX) {
+      return (size_t)pageSize;
+    } else {
+      return (size_t)SIZE_MAX;
+    }
+  } else {
+    die ("GC_pageSize");
+  }
 }
 
 size_t GC_totalRam (void) {
-  size_t physMem;
   size_t len;
   int mib[2];
 
+  len = 0;
   mib[0] = CTL_HW;
+#ifdef HW_PHYSMEM64
+  mib[1] = HW_PHYSMEM64;
+#else
   mib[1] = HW_PHYSMEM;
-  len = sizeof(physMem);
-  if (-1 == sysctl (mib, 2, &physMem, &len, NULL, 0))
+#endif
+  if (-1 == sysctl (mib, 2, NULL, &len, NULL, 0))
     diee ("sysctl failed");
-  return (size_t)physMem;
+  if (len == sizeof(unsigned long long int)) {
+    unsigned long long int physMem;
+    if (-1 == sysctl (mib, 2, &physMem, &len, NULL, 0))
+      diee ("sysctl failed");
+    if (sizeof(size_t) >= sizeof(unsigned long long int)
+        || physMem <= (unsigned long long int)SIZE_MAX) {
+      return (size_t)physMem;
+    } else {
+      return (size_t)SIZE_MAX;
+    }
+  } else if (len == sizeof(unsigned long int)) {
+    unsigned long int physMem;
+    if (-1 == sysctl (mib, 2, &physMem, &len, NULL, 0))
+      diee ("sysctl failed");
+    if (sizeof(size_t) >= sizeof(unsigned long int)
+        || physMem <= (unsigned long int)SIZE_MAX) {
+      return (size_t)physMem;
+    } else {
+      return (size_t)SIZE_MAX;
+    }
+  } else if (len == sizeof(unsigned int)) {
+    unsigned int physMem;
+    if (-1 == sysctl (mib, 2, &physMem, &len, NULL, 0))
+      diee ("sysctl failed");
+    if (sizeof(size_t) >= sizeof(unsigned int)
+        || physMem <= (unsigned int)SIZE_MAX) {
+      return (size_t)physMem;
+    } else {
+      return (size_t)SIZE_MAX;
+    }
+  } else {
+    die ("GC_totalRam");
+  }
 }




More information about the MLton-commit mailing list