last bits of sb_alloc_from_heap
authorRobert Haas <rhaas@postgresql.org>
Mon, 24 Mar 2014 23:06:21 +0000 (16:06 -0700)
committerRobert Haas <rhaas@postgresql.org>
Mon, 24 Mar 2014 23:06:21 +0000 (16:06 -0700)
src/backend/utils/mmgr/sb_alloc.c

index 4042c88ba010b85f48f9d81ce221eb58d0f24611..4c707f73e2a67c3712a28657c52e510c20896fa2 100644 (file)
@@ -296,6 +296,8 @@ sb_alloc_from_heap(char *base, sb_heap *heap, Size obsize)
        sb_span *active_sb;
        Size    fclass;
        Size    nmax = (FPM_PAGE_SIZE * SB_PAGES_PER_SUPERBLOCK) / obsize;
+       char   *superblock;
+       char   *result;
 
        /*
         * If fullness class 1 is empty, try to find something to put in it by
@@ -363,16 +365,33 @@ sb_alloc_from_heap(char *base, sb_heap *heap, Size obsize)
                                return NULL;
        }
 
-       /* We have a superblock from which to allocate; do it. */
+       /*
+        * There should be a superblock in fullness class 1 at this point, and
+        * it should never be completely full.  Thus we can either pop the
+        * free list or, failing that, initialize a new object.
+        */
        active_sb = relptr_access(base, heap->spans[1]);
+       superblock = base + active_sb->first_page * FPM_PAGE_SIZE;
        Assert(active_sb != NULL);
-       /* XXX need to actually allocate something here! */
+       Assert(active_sb->nused < nmax);
+       Assert(active_sb->nused < active_sb->ninitialized);
+       if (active_sb->firstfree < nmax)
+       {
+               result = superblock + active_sb->firstfree * obsize;
+               active_sb->firstfree = * (Size *) result;
+       }
+       else
+       {
+               Assert(active_sb->ninitialized < nmax);
+               result = superblock + active_sb->ninitialized * obsize;
+               ++active_sb->ninitialized;
+       }
 
        /* If it's now full, move it to the highest-numbered fullness class. */
        if (active_sb->nused == nmax)
                sb_transfer_first_span(base, heap, 1, SB_FULLNESS_CLASSES - 1);
 
-       return NULL; /* XXX */
+       return result;
 }
 
 /*
@@ -506,7 +525,7 @@ sb_init_span(char *base, sb_span *span, sb_heap *heap, Size first_page,
        span->size_class = size_class;
        span->ninitialized = 0;
        span->nused = 0;
-       span->firstfree = 0;
+       span->firstfree = (uint16) -1;
 }
 
 /*