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.
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 */