From: Robert Haas Date: Wed, 26 Mar 2014 23:53:44 +0000 (-0700) Subject: sb_reset_allocator X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=25a89bd4bd249d9475c042d2efb83ffdf8401893;p=users%2Frhaas%2Fpostgres.git sb_reset_allocator --- diff --git a/src/backend/utils/mmgr/sb_alloc.c b/src/backend/utils/mmgr/sb_alloc.c index 30dd5c5c5c..dacb90ecae 100644 --- a/src/backend/utils/mmgr/sb_alloc.c +++ b/src/backend/utils/mmgr/sb_alloc.c @@ -273,6 +273,67 @@ sb_alloc(sb_allocator *a, Size size, int flags) return result; } +/* + * Free all memory used by an allocator. + * + * NB: It's not safe to do this while the allocator is in use! + */ +void +sb_reset_allocator(sb_allocator *a) +{ + char *base = NULL; + int num_heaps; + int heapno; + + /* + * For shared memory allocation, pointers are relative to the start of the + * region. + */ + if (!a->private) + { + sb_region *region = sb_lookup_region(a); + if (region == NULL) + elog(ERROR, "sb_region not found"); + base = region->region_start; + } + + /* + * Iterate through heaps back to front. We do it this way so that + * spans-of-spans are freed last. + */ + num_heaps = a->heaps_per_size_class * (int) a->num_size_classes; + for (heapno = num_heaps; heapno >= 0; --heapno) + { + sb_heap *heap = &a->heaps[heapno]; + Size fclass; + + for (fclass = 0; fclass < SB_FULLNESS_CLASSES; ++fclass) + { + sb_region *region; + char *superblock; + sb_span *span; + char *fpm_base; + Size first_page; + + span = relptr_access(base, heap->spans[fclass]); + superblock = base + span->first_page * FPM_PAGE_SIZE; + region = sb_lookup_region(superblock); + Assert(region != NULL); + fpm_base = fpm_segment_base(region->fpm); + /* + * XXX. Here's where the wheels are going to come + * off if it turns out that malloc returns somethign that isn't + * page-aligned.... what do we do about this? Maybe we should + * rejigger things so that the fpm base is NULL for all private + * stuff. + */ + first_page = (superblock - fpm_base) / FPM_PAGE_SIZE; + FreePageManagerPut(region->fpm, first_page, span->npages); + + } + } +} + /* * Allocate an object from the provided heap. Caller is responsible for * any required locking. diff --git a/src/include/utils/sb_alloc.h b/src/include/utils/sb_alloc.h index 5794bee4d1..0ed528b6d1 100644 --- a/src/include/utils/sb_alloc.h +++ b/src/include/utils/sb_alloc.h @@ -69,6 +69,7 @@ typedef struct sb_allocator extern sb_allocator *sb_create_private_allocator(void); extern void *sb_alloc(sb_allocator *, Size, int flags); extern void sb_free(void *ptr); +extern void sb_reset_allocator(sb_allocator *a); extern void sb_destroy_private_allocator(sb_allocator *); #endif /* SB_ALLOC_H */