Fix aregion.c bugs in computing which region freelist to target.
authorRobert Haas <rhaas@postgresql.org>
Mon, 9 Jun 2014 21:00:30 +0000 (21:00 +0000)
committerRobert Haas <rhaas@postgresql.org>
Mon, 9 Jun 2014 21:00:30 +0000 (21:00 +0000)
src/backend/utils/mmgr/aregion.c

index 029ffd023e6db1f7cc7d5bfc3da83d461e34f1ca..9ba2ece4847bc0edd47e118704ae6b634eb26e1a 100644 (file)
@@ -94,6 +94,9 @@ static AllocatorRegionLookupLeaf lookup_root_leaf;
 #define NUM_PRIVATE_FREELISTS  16
 static dlist_head private_freelist[NUM_PRIVATE_FREELISTS];
 
+#define contiguous_pages_to_freelist(n) \
+       Min(fls(n), NUM_PRIVATE_FREELISTS - 1)
+
 /*
  * Constants to set the size of backend-private regions.  Superblocks are
  * 16 pages each (64kB), and we want a number of superblocks to fit inside
@@ -274,7 +277,7 @@ LookupAllocatorRegion(void *ptr)
 AllocatorRegion *
 GetRegionForPrivateAllocation(Size npages)
 {
-       int freelist = Min(fls(npages), NUM_PRIVATE_FREELISTS);
+       int freelist = contiguous_pages_to_freelist(npages);
        Size    new_region_net_pages;
        Size    metadata_bytes;
        char   *region_start;
@@ -320,7 +323,7 @@ GetRegionForPrivateAllocation(Size npages)
                         */
                        if (largest < threshold)
                        {
-                               int     new_freelist = Min(fls(largest), NUM_PRIVATE_FREELISTS);
+                               int     new_freelist = contiguous_pages_to_freelist(largest);
 
                                dlist_delete(iter.cur);
                                dlist_push_head(&private_freelist[new_freelist],
@@ -414,7 +417,7 @@ GetRegionForPrivateAllocation(Size npages)
                                                                metadata_bytes / FPM_PAGE_SIZE,
                                                                new_region_net_pages);
        region->contiguous_pages = new_region_net_pages; /* Now fix the value. */
-       freelist = Min(fls(new_region_net_pages), NUM_PRIVATE_FREELISTS);
+       freelist = contiguous_pages_to_freelist(new_region_net_pages);
        dlist_push_head(&private_freelist[freelist], &region->fl_node);
        AllocatorRegionAdjustLookup(region, true);
 
@@ -473,8 +476,8 @@ ReportRegionContiguousFreespace(AllocatorRegion *region, Size npages)
        }
 
        /* If necessary, move the region to a higher-numbered freelist. */
-       old_freelist = Min(fls(region->contiguous_pages), NUM_PRIVATE_FREELISTS);
-       new_freelist = Min(fls(npages), NUM_PRIVATE_FREELISTS);
+       old_freelist = contiguous_pages_to_freelist(region->contiguous_pages);
+       new_freelist = contiguous_pages_to_freelist(npages);
        if (new_freelist > old_freelist)
        {
                dlist_delete(&region->fl_node);