From: Robert Haas Date: Tue, 29 Apr 2014 16:58:18 +0000 (-0400) Subject: Teach sb_free to unlink spans and return their storage to fpm. X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=21cc3d7b3cfb07c3762baf7bfd1ef04b6d3e4109;p=users%2Frhaas%2Fpostgres.git Teach sb_free to unlink spans and return their storage to fpm. The spans themselves don't get reclaimed yet. --- diff --git a/src/backend/utils/mmgr/sb_alloc.c b/src/backend/utils/mmgr/sb_alloc.c index d8923fdca8..70eb9c75a0 100644 --- a/src/backend/utils/mmgr/sb_alloc.c +++ b/src/backend/utils/mmgr/sb_alloc.c @@ -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); +}