Teach sb_free to unlink spans and return their storage to fpm.
authorRobert Haas <rhaas@postgresql.org>
Tue, 29 Apr 2014 16:58:18 +0000 (12:58 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 29 Apr 2014 16:58:18 +0000 (12:58 -0400)
The spans themselves don't get reclaimed yet.

src/backend/utils/mmgr/sb_alloc.c

index d8923fdca8b955e58153ac4f563de5f3896701f0..70eb9c75a064a680b3d2341117e6786e67b9ff0d 100644 (file)
@@ -43,7 +43,7 @@ struct sb_span
        relptr(sb_heap) parent;         /* Containing heap. */
        relptr(sb_span) prevspan;       /* Previous span. */
        relptr(sb_span) nextspan;       /* Next span. */
-       relptr(char)    start;          /* Starting page number. */
+       relptr(char)    start;          /* Starting address. */
        Size            npages;                 /* Length of span in pages. */
        uint16          size_class;             /* Size class. */
        uint16          ninitialized;   /* Maximum number of objects ever allocated. */
@@ -125,6 +125,7 @@ static void sb_init_span(char *base, sb_span *span, sb_heap *heap,
 static void sb_out_of_memory_error(sb_allocator *a);
 static bool sb_transfer_first_span(char *base, sb_heap *heap,
                                           int fromclass, int toclass);
+static void sb_unlink_span(char *base, sb_heap *heap, sb_span *span);
 
 /*
  * Create a backend-private allocator.
@@ -322,20 +323,10 @@ sb_free(void *ptr)
        if (span->nallocatable == 1 && span->fclass == SB_FULLNESS_CLASSES - 1)
        {
                sb_heap *heap = relptr_access(base, span->parent);
-               sb_span *nextspan = relptr_access(base, span->nextspan);
-               sb_span *prevspan = relptr_access(base, span->prevspan);
                sb_span *new_nextspan;
 
-               /* Remove from current list. */
-               relptr_store(base, span->prevspan, (sb_span *) NULL);
-               if (nextspan != NULL)
-                       relptr_copy(nextspan->prevspan, span->prevspan);
-               if (prevspan != NULL)
-                       relptr_copy(prevspan->nextspan, span->nextspan);
-               else
-                       relptr_copy(heap->spans[span->fclass], span->nextspan);
-
-               /* Add to correct list. */
+               /* Move to next lower-numbered list. */
+               sb_unlink_span(base, heap, span);
                span->fclass = SB_FULLNESS_CLASSES - 2;
                relptr_copy(span->nextspan, heap->spans[SB_FULLNESS_CLASSES - 2]);
                relptr_store(base, span->prevspan, (sb_span *) NULL);
@@ -347,9 +338,17 @@ sb_free(void *ptr)
        }
        else if (span->nallocatable == span->nmax)
        {
+               sb_heap *heap = relptr_access(base, span->parent);
+               Size    first_page;
+
+               sb_unlink_span(base, heap, span);
+               first_page = fpm_pointer_to_page(fpm_base,
+                                                                                relptr_access(base, span->start));
+               FreePageManagerPut(region->fpm, first_page, span->npages);
+
                /*
-                * XXX. Deallocate the span; and if that causes the span of spans
-                * to need deallocation, do that, too.
+                * XXX. Free the span, and possibly the span-of-spans which contains
+                * it.
                 */
        }
 
@@ -721,3 +720,21 @@ sb_transfer_first_span(char *base, sb_heap *heap, int fromclass, int toclass)
 
        return true;
 }
+
+/*
+ * Remove span from current list.
+ */
+static void
+sb_unlink_span(char *base, sb_heap *heap, sb_span *span)
+{
+       sb_span *nextspan = relptr_access(base, span->nextspan);
+       sb_span *prevspan = relptr_access(base, span->prevspan);
+
+       relptr_store(base, span->prevspan, (sb_span *) NULL);
+       if (nextspan != NULL)
+               relptr_copy(nextspan->prevspan, span->prevspan);
+       if (prevspan != NULL)
+               relptr_copy(prevspan->nextspan, span->nextspan);
+       else
+               relptr_copy(heap->spans[span->fclass], span->nextspan);
+}