*/
metadata_bytes = MAXALIGN(sizeof(AllocatorRegion));
metadata_bytes += MAXALIGN(sizeof(FreePageManager));
- metadata_bytes +=
- MAXALIGN(BlockAllocatorMapSize(NULL, new_region_net_pages));
+ metadata_bytes += MAXALIGN(new_region_net_pages * sizeof(Size));
if (metadata_bytes % FPM_PAGE_SIZE != 0)
metadata_bytes += FPM_PAGE_SIZE - (metadata_bytes % FPM_PAGE_SIZE);
region_size = new_region_net_pages * FPM_PAGE_SIZE + metadata_bytes;
region->context = NULL;
region->fpm = (FreePageManager *)
(region_start + MAXALIGN(sizeof(AllocatorRegion)));
- region->pagemap = (BlockAllocatorMap *)
+ region->pagemap = (Size *)
(((char *) region->fpm) + MAXALIGN(sizeof(FreePageManager)));
region->contiguous_pages = new_region_net_pages + 1;
FreePageManagerInitialize(region->fpm, region->region_start, NULL, false);
FreePageManagerPut(region->fpm, metadata_bytes / FPM_PAGE_SIZE,
new_region_net_pages);
- BlockAllocatorMapInitialize(region->pagemap, NULL,
- metadata_bytes / FPM_PAGE_SIZE,
- new_region_net_pages);
region->contiguous_pages = new_region_net_pages; /* Now fix the value. */
freelist = contiguous_pages_to_freelist(new_region_net_pages);
dlist_push_head(&private_freelist[freelist], ®ion->fl_node);
BA_SCLASS_SPAN_LARGE);
if (lock != NULL)
LWLockRelease(lock);
- BlockAllocatorMapSet(region->pagemap, first_page, span);
+ region->pagemap[first_page] = ((char *) span) - base;
return ptr;
}
/* Locate the containing span. */
fpm_base = fpm_segment_base(aregion->fpm);
pageno = fpm_pointer_to_page(fpm_base, ptr);
- span = BlockAllocatorMapGet(aregion->pagemap, pageno);
/*
* If this is a shared-memory region, we might need locking. If so,
}
/* Compute the object size. */
+ span = (BlockAllocatorSpan *) (base + aregion->pagemap[pageno]);
size_class = span->size_class;
obsize = balloc_size_classes[size_class];
/* Locate the containing span. */
fpm_base = fpm_segment_base(aregion->fpm);
pageno = fpm_pointer_to_page(fpm_base, ptr);
- span = BlockAllocatorMapGet(aregion->pagemap, pageno);
+ base = aregion->seg != NULL ? fpm_base : NULL;
+ span = (BlockAllocatorSpan *) (base + aregion->pagemap[pageno]);
/*
* Extract relevant details from span. We can read this information
}
/* Ugly code to find context; see BlockAllocatorGetChunkContext. */
- base = aregion->seg != NULL ? fpm_base : NULL;
heap = relptr_access(base, span->parent);
heap0 = heap - span->size_class;
context = (BlockAllocatorContext *)
BlockAllocatorGetChunkSpace(AllocatorRegion *aregion, void *ptr)
{
char *fpm_base;
+ char *base;
BlockAllocatorSpan *span;
Size pageno;
uint16 size_class;
/* Locate the containing block. */
fpm_base = fpm_segment_base(aregion->fpm);
pageno = fpm_pointer_to_page(fpm_base, ptr);
- span = BlockAllocatorMapGet(aregion->pagemap, pageno);
+ base = aregion->seg != NULL ? fpm_base : NULL;
+ span = (BlockAllocatorSpan *) (base + aregion->pagemap[pageno]);
/* Work out the size of the allocation. */
size_class = span->size_class;
/* Locate the containing block. */
fpm_base = fpm_segment_base(aregion->fpm);
pageno = fpm_pointer_to_page(fpm_base, ptr);
- span = BlockAllocatorMapGet(aregion->pagemap, pageno);
+ base = aregion->seg != NULL ? fpm_base : NULL;
+ span = (BlockAllocatorSpan *) (base + aregion->pagemap[pageno]);
/* Follow the parent poiner to find the containing heap. */
base = aregion->seg != NULL ? fpm_base : NULL;
/* Initialize span and pagemap. */
BlockAllocatorInitSpan(base, span, heap, ptr, npages, size_class);
for (i = 0; i < npages; ++i)
- BlockAllocatorMapSet(region->pagemap, first_page + i, span);
+ region->pagemap[first_page + i] = ((char *) span) - base;
return true;
}
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * balloc_map.c
- * Block allocator page-mapping infrastructure.
- *
- * The block allocator does not store metadata with each chunk, and
- * therefore needs a way to find the metadata given only the pointer
- * address. The first step is to translate the pointer address to a
- * an offset relative to some base address, from which a page number
- * can be calculated. Then, this module is reponsible for mapping the
- * page number to an offset with the chunk where the associated span
- * object is stored. We do this in the simplest possible way: one big
- * array.
- *
- * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/backend/utils/mmgr/balloc_map.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "storage/shmem.h"
-#include "utils/balloc_map.h"
-#include "utils/freepage.h"
-
-const uint64 maxpages_4b = UINT64CONST(0x100000000) / FPM_PAGE_SIZE;
-
-struct BlockAllocatorMap
-{
- relptr(BlockAllocatorMap) self;
- Size offset;
- Size npages;
- bool use64;
-};
-
-/* Map layout for systems with 32-bit pointers, or shared segments < 4GB. */
-typedef struct BlockAllocatorMap32
-{
- BlockAllocatorMap hdr;
- uint32 map[FLEXIBLE_ARRAY_MEMBER];
-} BlockAllocatorMap32;
-
-/* Map layout for systems with 64-bit pointers, except shared segments < 4GB. */
-typedef struct BlockAllocatorMap64
-{
- BlockAllocatorMap hdr;
- uint64 map[FLEXIBLE_ARRAY_MEMBER];
-} BlockAllocatorMap64;
-
-#define balloc_map_base(m) \
- (((char *) m) - m->self.relptr_off)
-
-/*
- * Compute the amount of space required for an BlockAllocatorMap covering a
- * given number of pages. Note that for shared memory (i.e. when base != NULL),
- * we assume that the pointers will always point to addresses within that
- * same segment, but for backend-private memory that might not be the case.
- */
-Size
-BlockAllocatorMapSize(char *base, Size npages)
-{
- Size map_bytes;
-
- if (sizeof(Size) <= 4 || (base != NULL && npages < maxpages_4b))
- map_bytes = add_size(offsetof(BlockAllocatorMap32, map),
- mul_size(npages, sizeof(uint32)));
- else
- map_bytes = add_size(offsetof(BlockAllocatorMap64, map),
- mul_size(npages, sizeof(uint64)));
-
- return map_bytes;
-}
-
-/*
- * Initialize a BlockAllocatorMap. Storage is provided by the caller. Note
- * that we don't zero the array; the caller shouldn't try to get a value that
- * hasn't been set.
- */
-void
-BlockAllocatorMapInitialize(BlockAllocatorMap *m, char *base, Size offset,
- Size npages)
-{
- relptr_store(base, m->self, m);
- m->offset = offset;
- m->npages = npages;
- if (sizeof(Size) <= 4 || (base != NULL && npages < maxpages_4b))
- m->use64 = false;
- else
- m->use64 = true;
-}
-
-/*
- * Store a value into a BlockAllocatorMap.
- */
-void
-BlockAllocatorMapSet(BlockAllocatorMap *m, Size pageno, void *ptr)
-{
- char *base = balloc_map_base(m);
- Assert(pageno >= m->offset);
- pageno -= m->offset;
- Assert(pageno < m->npages);
-
- if (m->use64)
- ((BlockAllocatorMap64 *) m)->map[pageno] =
- (uint64) (((char *) ptr) - base);
- else
- ((BlockAllocatorMap32 *) m)->map[pageno] =
- (uint32) (((char *) ptr) - base);
-}
-
-/*
- * Get a value from a BlockAllocatorMap. Getting a value not previously stored
- * will produce an undefined result, so don't do that.
- */
-void *
-BlockAllocatorMapGet(BlockAllocatorMap *m, Size pageno)
-{
- char *base = balloc_map_base(m);
- Assert(pageno >= m->offset);
- pageno -= m->offset;
- Assert(pageno < m->npages);
-
- if (m->use64)
- return base + ((BlockAllocatorMap64 *) m)->map[pageno];
- else
- return base + ((BlockAllocatorMap32 *) m)->map[pageno];
-}
#include "storage/shm_toc.h"
#include "utils/freepage.h"
#include "utils/balloc.h"
-#include "utils/balloc_map.h"
/*
* An AllocatorRegion is a backend-private object used to track allocatable
dsm_segment *seg; /* DSM handle (if not private). */
BlockAllocatorContext *context; /* Shared allocator (if not private). */
FreePageManager *fpm; /* Free page manager for region (if any). */
- BlockAllocatorMap *pagemap; /* Page map for region (if any). */
+ Size *pagemap; /* Page map for region (if any). */
Size contiguous_pages; /* Last reported contiguous free pages. */
dlist_node fl_node; /* Freelist links. */
} AllocatorRegion;
typedef struct AllocatorSharedRegion
{
relptr(FreePageManager) fpm;
- relptr(BlockAllocatorMap) pagemap;
+ relptr(Size) pagemap;
relptr(BlockAllocatorContext) allocator;
int lwlock_tranche_id;
char lwlock_tranche_name[FLEXIBLE_ARRAY_MEMBER];
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * balloc_map.h
- * Block allocator page-mapping infrastructure.
- *
- * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/utils/ba_map.h
- *
- *-------------------------------------------------------------------------
- */
-
-#ifndef BALLOC_MAP_H
-#define BALLOC_MAP_H
-
-typedef struct BlockAllocatorMap BlockAllocatorMap;
-
-extern Size BlockAllocatorMapSize(char *base, Size npages);
-extern void BlockAllocatorMapInitialize(BlockAllocatorMap *, char *base,
- Size offset, Size npages);
-extern void BlockAllocatorMapSet(BlockAllocatorMap *, Size pageno, void *ptr);
-extern void *BlockAllocatorMapGet(BlockAllocatorMap *, Size pageno);
-
-#endif /* BALLOC_MAP_H */