top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-OBJS = aset.o freepage.o mcxt.o portalmem.o sb_map.o
+OBJS = aset.o freepage.o mcxt.o portalmem.o sb_alloc.o sb_map.o sb_region.o
include $(top_srcdir)/src/backend/common.mk
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * sb_alloc.c
+ * Superblock-based memory allocator.
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/backend/utils/mmgr/sb_alloc.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "utils/sb_alloc.h"
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * sb_region.c
+ * Superblock allocator memory region manager.
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/backend/utils/mmgr/sb_region.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "utils/sb_region.h"
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * sb_alloc.h
+ * Superblock-based memory allocator.
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/sb_alloc.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef SB_ALLOC_H
+#define SB_ALLOC_H
+
+#include "storage/lwlock.h"
+#include "utils/relptr.h"
+
+typedef struct sb_span sb_span;
+
+/*
+ * Superblocks are binned by how full they are. Generally, each fullness
+ * class corresponds to one quartile, but the superblock being used for
+ * allocations is always at the head of the list for fullness class 1,
+ * regardless of how full it really is.
+ *
+ * For large objects, we just stick all of the allocations in fullness class
+ * 0. Since we can just return the space directly to the free page manager,
+ * we don't really need them on a list at all, except that if someone wants
+ * to bulk release everything allocated using this sb_allocator, we have no
+ * other way of finding them.
+ */
+#define SB_FULLNESS_CLASSES 4
+
+/*
+ * An sb_heap represents a set of allocations of a given size class.
+ * There can be multiple heaps for the same size class for contention
+ * avoidance.
+ */
+typedef struct sb_heap
+{
+ relptr(LWLock) lock;
+ relptr(sb_span) spans[SB_FULLNESS_CLASSES];
+} sb_heap;
+
+/*
+ * An sb_allocator is basically just a group of heaps, N per size class, where
+ * N can be chosen by the user. If locking is required, then we've also got
+ * an array of LWLocks, one per heap.
+ */
+typedef struct sb_allocator
+{
+ uint16 heaps_per_size_class;
+ uint16 num_size_classes;
+ relptr(LWLock) locks;
+ sb_heap heaps[FLEXIBLE_ARRAY_MEMBER];
+} sb_allocator;
+
+/* Allocation options. */
+#define SB_ALLOC_HUGE 0x0001 /* allow >=1GB */
+#define SB_ALLOC_SOFT_FAIL 0x0002 /* return NULL if no mem */
+
+/* Exported functions. */
+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_destroy_private_allocator(sb_allocator *);
+
+#endif /* SB_ALLOC_H */
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * sb_region.h
+ * Superblock allocator memory region manager.
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/sb_region.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef SB_REGION_H
+#define SB_REGION_H
+
+#include "storage/dsm.h"
+#include "storage/shm_toc.h"
+#include "utils/freepage.h"
+#include "utils/sb_alloc.h"
+#include "utils/sb_map.h"
+
+/*
+ * An sb_region is a backend-private object used to track allocatable regions
+ * of memory, either backend-private or shared.
+ */
+typedef struct sb_region
+{
+ char *region_start;
+ Size region_size;
+ dsm_segment *seg;
+ FreePageManager *fpm;
+ sb_map *pagemap;
+ sb_allocator *allocator;
+} sb_region;
+
+/*
+ * An sb_shared_region is a shared-memory object containing the information
+ * necessary to set up an sb_region object for an individual backend.
+ */
+typedef struct sb_shared_region
+{
+ relptr(FreePageManager) fpm;
+ relptr(sb_map) pagemap;
+ relptr(sb_allocator) allocator;
+ int lwlock_tranche_id;
+ char lwlock_tranche_name[FLEXIBLE_ARRAY_MEMBER];
+} sb_shared_region;
+
+/* Public API. */
+extern sb_shared_region *sb_create_shared_region(dsm_segment *seg,
+ shm_toc *toc, Size size,
+ int lwlock_tranche_id,
+ char *lwlock_tranche_name);
+extern sb_allocator *sb_attach_shared_region(dsm_segment *,
+ sb_shared_region *);
+
+/* For use by sb_alloc/sb_free. */
+extern sb_region *sb_private_region_for_allocator(Size npages);
+extern sb_region *sb_lookup_region(void *);
+
+#endif /* SB_REGION_H */