mirror of
https://github.com/postgres/postgres.git
synced 2025-08-17 01:02:17 +03:00
Redesign the patch for allocation of shmem space and LWLocks for add-on
modules; the first try was not usable in EXEC_BACKEND builds (e.g., Windows). Instead, just provide some entry points to increase the allocation requests during postmaster start, and provide a dedicated LWLock that can be used to synchronize allocation operations performed by backends. Per discussion with Marc Munro.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.97 2006/10/04 00:29:57 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.98 2006/10/15 22:04:07 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -53,7 +53,7 @@
|
||||
* postmaster. However, this does not work in the EXEC_BACKEND case.
|
||||
* In ports using EXEC_BACKEND, new backends have to set up their local
|
||||
* pointers using the method described in (b) above.
|
||||
|
||||
*
|
||||
* (d) memory allocation model: shared memory can never be
|
||||
* freed, once allocated. Each hash table has its own free list,
|
||||
* so hash buckets can be reused when an item is deleted. However,
|
||||
@@ -61,15 +61,6 @@
|
||||
* cannot be redistributed to other tables. We could build a simple
|
||||
* hash bucket garbage collector if need be. Right now, it seems
|
||||
* unnecessary.
|
||||
*
|
||||
* (e) Add-ins can request their own logical shared memory segments
|
||||
* by calling RegisterAddinContext() from the preload-libraries hook.
|
||||
* Each call establishes a uniquely named add-in shared memopry
|
||||
* context which will be set up as part of postgres intialisation.
|
||||
* Memory can be allocated from these contexts using
|
||||
* ShmemAllocFromContext(), and can be reset to its initial condition
|
||||
* using ShmemResetContext(). Also, RegisterAddinLWLock(LWLockid *lock_ptr)
|
||||
* can be used to request that a LWLock be allocated, placed into *lock_ptr.
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -95,19 +86,6 @@ slock_t *ShmemLock; /* spinlock for shared memory and LWLock
|
||||
|
||||
static HTAB *ShmemIndex = NULL; /* primary index hashtable for shmem */
|
||||
|
||||
/* Structures and globals for managing add-in shared memory contexts */
|
||||
typedef struct context
|
||||
{
|
||||
char *name;
|
||||
Size size;
|
||||
PGShmemHeader *seg_hdr;
|
||||
struct context *next;
|
||||
} ContextNode;
|
||||
|
||||
static ContextNode *addin_contexts = NULL;
|
||||
static Size addin_contexts_size = 0;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* InitShmemAccess() --- set up basic pointers to shared memory.
|
||||
@@ -162,99 +140,7 @@ InitShmemAllocation(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* RegisterAddinContext -- Register the requirement for a named shared
|
||||
* memory context.
|
||||
*/
|
||||
void
|
||||
RegisterAddinContext(const char *name, Size size)
|
||||
{
|
||||
char *newstr = malloc(strlen(name) + 1);
|
||||
ContextNode *node = malloc(sizeof(ContextNode));
|
||||
|
||||
strcpy(newstr, name);
|
||||
node->name = newstr;
|
||||
|
||||
/* Round up to typical page size */
|
||||
node->size = add_size(size, 8192 - (size % 8192));
|
||||
node->next = addin_contexts;
|
||||
|
||||
addin_contexts = node;
|
||||
addin_contexts_size = add_size(addin_contexts_size, node->size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ContextFromName -- Return the ContextNode for the given named
|
||||
* context, or NULL if not found.
|
||||
*/
|
||||
static ContextNode *
|
||||
ContextFromName(const char *name)
|
||||
{
|
||||
ContextNode *context = addin_contexts;
|
||||
|
||||
while (context)
|
||||
{
|
||||
if (strcmp(name, context->name) == 0)
|
||||
return context;
|
||||
context = context->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* InitAddinContexts -- Initialise the registered addin shared memory
|
||||
* contexts.
|
||||
*/
|
||||
void
|
||||
InitAddinContexts(void *start)
|
||||
{
|
||||
PGShmemHeader *next_segment = (PGShmemHeader *) start;
|
||||
ContextNode *context = addin_contexts;
|
||||
|
||||
while (context)
|
||||
{
|
||||
context->seg_hdr = next_segment;
|
||||
|
||||
next_segment->totalsize = context->size;
|
||||
next_segment->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
|
||||
|
||||
next_segment = (PGShmemHeader *)
|
||||
((char *) next_segment + context->size);
|
||||
context = context->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemResetContext -- Re-initialise the named addin shared memory context.
|
||||
*/
|
||||
void
|
||||
ShmemResetContext(const char *name)
|
||||
{
|
||||
PGShmemHeader *segment;
|
||||
ContextNode *context = ContextFromName(name);
|
||||
|
||||
if (!context)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("cannot reset unknown shared memory context %s",
|
||||
name)));
|
||||
|
||||
segment = context->seg_hdr;
|
||||
segment->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
|
||||
}
|
||||
|
||||
/*
|
||||
* AddinShmemSize -- Report how much shared memory has been registered
|
||||
* for add-ins.
|
||||
*/
|
||||
Size
|
||||
AddinShmemSize(void)
|
||||
{
|
||||
return addin_contexts_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemAllocFromContext -- allocate max-aligned chunk from shared memory
|
||||
* ShmemAlloc -- allocate max-aligned chunk from shared memory
|
||||
*
|
||||
* Assumes ShmemLock and ShmemSegHdr are initialized.
|
||||
*
|
||||
@@ -263,30 +149,15 @@ AddinShmemSize(void)
|
||||
* to be compatible with malloc().
|
||||
*/
|
||||
void *
|
||||
ShmemAllocFromContext(Size size, const char *context_name)
|
||||
ShmemAlloc(Size size)
|
||||
{
|
||||
Size newStart;
|
||||
Size newFree;
|
||||
void *newSpace;
|
||||
ContextNode *context;
|
||||
|
||||
/* use volatile pointer to prevent code rearrangement */
|
||||
volatile PGShmemHeader *shmemseghdr = ShmemSegHdr;
|
||||
|
||||
/*
|
||||
* if context_name is provided, allocate from the named context
|
||||
*/
|
||||
if (context_name)
|
||||
{
|
||||
context = ContextFromName(context_name);
|
||||
if (!context)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("cannot reset unknown shared memory context %s",
|
||||
context_name)));
|
||||
shmemseghdr = context->seg_hdr;
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure all space is adequately aligned.
|
||||
*/
|
||||
@@ -305,7 +176,7 @@ ShmemAllocFromContext(Size size, const char *context_name)
|
||||
newFree = newStart + size;
|
||||
if (newFree <= shmemseghdr->totalsize)
|
||||
{
|
||||
newSpace = (void *) MAKE_PTRFROM((SHMEM_OFFSET) shmemseghdr, newStart);
|
||||
newSpace = (void *) MAKE_PTR(newStart);
|
||||
shmemseghdr->freeoffset = newFree;
|
||||
}
|
||||
else
|
||||
@@ -321,22 +192,6 @@ ShmemAllocFromContext(Size size, const char *context_name)
|
||||
return newSpace;
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemAlloc -- allocate max-aligned chunk from shared memory
|
||||
*
|
||||
* Assumes ShmemLock and ShmemSegHdr are initialized.
|
||||
*
|
||||
* Returns: real pointer to memory or NULL if we are out
|
||||
* of space. Has to return a real pointer in order
|
||||
* to be compatible with malloc().
|
||||
*/
|
||||
|
||||
void *
|
||||
ShmemAlloc(Size size)
|
||||
{
|
||||
return ShmemAllocFromContext(size, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemIsValid -- test if an offset refers to valid shared memory
|
||||
*
|
||||
|
Reference in New Issue
Block a user