[MLton-commit] r7439

Matthew Fluet fluet at mlton.org
Wed Mar 17 12:57:23 PST 2010


Simplify backoff scheme with a biased binary search.
----------------------------------------------------------------------

U   mlton/trunk/runtime/gc/heap.c

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

Modified: mlton/trunk/runtime/gc/heap.c
===================================================================
--- mlton/trunk/runtime/gc/heap.c	2010-03-16 02:39:17 UTC (rev 7438)
+++ mlton/trunk/runtime/gc/heap.c	2010-03-17 20:57:22 UTC (rev 7439)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Matthew Fluet.
+/* Copyright (C) 2009-2010 Matthew Fluet.
  * Copyright (C) 2005-2008 Henry Cejtin, Matthew Fluet, Suresh
  *    Jagannathan, and Stephen Weeks.
  *
@@ -203,19 +203,28 @@
     fprintf (stderr, "createHeap  desired size = %s  min size = %s\n",
              uintmaxToCommaString(desiredSize),
              uintmaxToCommaString(minSize));
-  assert (isHeapInit (h));
   if (desiredSize < minSize)
     desiredSize = minSize;
   minSize = align (minSize, s->sysvals.pageSize);
   desiredSize = align (desiredSize, s->sysvals.pageSize);
-  assert (0 == h->size and NULL == h->start);
-  /* mmap toggling back and forth between high and low addresses to
-   * decrease the chance of virtual memory fragmentation causing an mmap
-   * to fail.  This is important for large heaps.
-   * Note that the loop always trys a NULL address last.
+  assert (isHeapInit (h) and NULL == h->start);
+  /* Biased binary search (between minSize and desiredSize) for a
+   * successful mmap.
+   * Toggle back and forth between high and low addresses to decrease
+   * the chance of virtual memory fragmentation; important for large
+   * heaps.
+   * Always try a NULL address last.
    */
-  newSize = desiredSize;
-  do {
+  size_t lowSize = minSize;
+  size_t highSize = desiredSize;
+  newSize = highSize;
+  while (lowSize <= highSize) {
+    pointer newStart;
+
+    newWithMapsSize = newSize + sizeofCardMapAndCrossMap (s, newSize);
+
+    assert (isAligned (newWithMapsSize, s->sysvals.pageSize));
+
     const unsigned int countLog2 = 5;
     const unsigned int count = 0x1 << countLog2;
     const size_t step = (size_t)0x1 << (ADDRESS_BITS - countLog2);
@@ -224,19 +233,9 @@
 #else
     const size_t address_end = (size_t)0x1 << ADDRESS_BITS;
 #endif
-
     static bool direction = TRUE;
-    unsigned int i;
-
-    newWithMapsSize = newSize + sizeofCardMapAndCrossMap (s, newSize);
-
-    assert (isAligned (newWithMapsSize, s->sysvals.pageSize));
-
-    for (i = 1; i <= count; i++) {
-      size_t address;
-      pointer newStart;
-
-      address = (size_t)i * step;
+    for (unsigned int i = 1; i <= count; i++) {
+      size_t address = (size_t)i * step;
       if (direction)
         address = address_end - address;
       /* Always use 0 in the last step. */
@@ -261,11 +260,10 @@
         return TRUE;
       }
     }
-    size_t backoff;
-    backoff = (newSize - minSize) / 16;
-    if (0 == backoff)
-      backoff = 1;
-    backoff = align (backoff, s->sysvals.pageSize);
+    size_t prevSize = newSize;
+    highSize = newSize - s->sysvals.pageSize;
+    const size_t factor = 16;
+    newSize = align((factor-1) * (highSize / factor) + (lowSize / factor), s->sysvals.pageSize);
     if (s->controls.messages) {
       fprintf (stderr,
                "[GC: Creating heap of size %s bytes (+ %s bytes card/cross map) cannot be satisfied,]\n",
@@ -273,16 +271,10 @@
                uintmaxToCommaString (newWithMapsSize - newSize));
       fprintf (stderr,
                "[GC:\tbacking off by %s bytes with minimum size of %s bytes.]\n",
-               uintmaxToCommaString (backoff),
+               uintmaxToCommaString (newSize - prevSize),
                uintmaxToCommaString (minSize));
     }
-    size_t nextSize = newSize - backoff;
-    if (nextSize < minSize and minSize < newSize) {
-      newSize = minSize;
-    } else {
-      newSize = nextSize;
-    }
-  } while (newSize >= minSize);
+  }
   return FALSE;
 }
 
@@ -311,8 +303,6 @@
                 size_t minSize) {
   size_t newSize;
   size_t newWithMapsSize;
-  size_t origSize;
-  size_t origWithMapsSize;
 
 #if not HAS_REMAP
   return FALSE;
@@ -325,17 +315,21 @@
   assert (desiredSize >= h->size);
   minSize = align (minSize, s->sysvals.pageSize);
   desiredSize = align (desiredSize, s->sysvals.pageSize);
-  origSize = h->size;
-  origWithMapsSize = origSize + sizeofCardMapAndCrossMap (s, origSize);
-  newSize = desiredSize;
-  do {
+
+  /* Biased binary search (between minSize and desiredSize) for a
+   * successful mremap.
+   */
+  size_t lowSize = minSize;
+  size_t highSize = desiredSize;
+  newSize = highSize;
+  while (lowSize <= highSize) {
     pointer newStart;
 
     newWithMapsSize = newSize + sizeofCardMapAndCrossMap (s, newSize);
 
     assert (isAligned (newWithMapsSize, s->sysvals.pageSize));
 
-    newStart = GC_mremap (h->start, origWithMapsSize, newWithMapsSize);
+    newStart = GC_mremap (h->start, h->withMapsSize, newWithMapsSize);
     unless ((void*)-1 == newStart) {
       h->start = newStart;
       h->size = newSize;
@@ -351,11 +345,10 @@
                  uintmaxToCommaString(h->withMapsSize - h->size));
       return TRUE;
     }
-    size_t backoff;
-    backoff = (newSize - minSize) / 16;
-    if (0 == backoff)
-      backoff = 1;
-    backoff = align (backoff, s->sysvals.pageSize);
+    size_t prevSize = newSize;
+    highSize = newSize - s->sysvals.pageSize;
+    const size_t factor = 16;
+    newSize = align((factor-1) * (highSize / factor) + (lowSize / factor), s->sysvals.pageSize);
     if (s->controls.messages) {
       fprintf (stderr,
                "[GC: Remapping heap to size %s bytes (+ %s bytes card/cross map) cannot be satisfied,]\n",
@@ -363,16 +356,10 @@
                uintmaxToCommaString (newWithMapsSize - newSize));
       fprintf (stderr,
                "[GC:\tbacking off by %s bytes with minimum size of %s bytes.]\n",
-               uintmaxToCommaString (backoff),
+               uintmaxToCommaString (newSize - prevSize),
                uintmaxToCommaString (minSize));
     }
-    size_t nextSize = newSize - backoff;
-    if (nextSize < minSize and minSize < newSize) {
-      newSize = minSize;
-    } else {
-      newSize = nextSize;
-    }
-  } while (newSize >= minSize);
+  }
   return FALSE;
 }
 




More information about the MLton-commit mailing list