mirror of
https://github.com/postgres/postgres.git
synced 2026-04-15 22:10:45 -04:00
Move some code from shmem.c and shmem.h
A little refactoring in preparation for the next commit, to make the material changes in that commit more clear. Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com> Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com
This commit is contained in:
parent
5a79e78501
commit
6ef9bee293
8 changed files with 194 additions and 138 deletions
|
|
@ -50,6 +50,7 @@
|
|||
#include "storage/dsm.h"
|
||||
#include "storage/io_worker.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/shmem_internal.h"
|
||||
#include "tcop/backend_startup.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ OBJS = \
|
|||
shm_mq.o \
|
||||
shm_toc.o \
|
||||
shmem.o \
|
||||
shmem_hash.o \
|
||||
signalfuncs.o \
|
||||
sinval.o \
|
||||
sinvaladt.o \
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/shmem_internal.h"
|
||||
#include "storage/sinvaladt.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/injection_point.h"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ backend_sources += files(
|
|||
'shm_mq.c',
|
||||
'shm_toc.c',
|
||||
'shmem.c',
|
||||
'shmem_hash.c',
|
||||
'signalfuncs.c',
|
||||
'sinval.c',
|
||||
'sinvaladt.c',
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
#include "storage/lwlock.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/shmem_internal.h"
|
||||
#include "storage/spin.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/tuplestore.h"
|
||||
|
|
@ -96,9 +97,6 @@ typedef struct ShmemAllocatorData
|
|||
|
||||
#define ShmemIndexLock (&ShmemAllocator->index_lock)
|
||||
|
||||
static HTAB *shmem_hash_create(void *location, size_t size, bool found,
|
||||
const char *name, int64 nelems, HASHCTL *infoP, int hash_flags);
|
||||
static void *ShmemHashAlloc(Size size, void *alloc_arg);
|
||||
static void *ShmemAllocRaw(Size size, Size *allocated_size);
|
||||
|
||||
/* shared memory global variables */
|
||||
|
|
@ -115,16 +113,6 @@ static bool firstNumaTouch = true;
|
|||
|
||||
Datum pg_numa_available(PG_FUNCTION_ARGS);
|
||||
|
||||
/*
|
||||
* A very simple allocator used to carve out different parts of a hash table
|
||||
* from a previously allocated contiguous shared memory area.
|
||||
*/
|
||||
typedef struct shmem_hash_allocator
|
||||
{
|
||||
char *next; /* start of free space in the area */
|
||||
char *end; /* end of the shmem area */
|
||||
} shmem_hash_allocator;
|
||||
|
||||
/*
|
||||
* InitShmemAllocator() --- set up basic pointers to shared memory.
|
||||
*
|
||||
|
|
@ -257,29 +245,6 @@ ShmemAllocNoError(Size size)
|
|||
return ShmemAllocRaw(size, &allocated_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemHashAlloc -- alloc callback for shared memory hash tables
|
||||
*
|
||||
* Carve out the allocation from a pre-allocated region. All shared memory
|
||||
* hash tables are initialized with HASH_FIXED_SIZE, so all the allocations
|
||||
* happen upfront during initialization and no locking is required.
|
||||
*/
|
||||
static void *
|
||||
ShmemHashAlloc(Size size, void *alloc_arg)
|
||||
{
|
||||
shmem_hash_allocator *allocator = (shmem_hash_allocator *) alloc_arg;
|
||||
void *result;
|
||||
|
||||
size = MAXALIGN(size);
|
||||
|
||||
if (allocator->end - allocator->next < size)
|
||||
return NULL;
|
||||
result = allocator->next;
|
||||
allocator->next += size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemAllocRaw -- allocate align chunk and return allocated size
|
||||
*
|
||||
|
|
@ -341,88 +306,6 @@ ShmemAddrIsValid(const void *addr)
|
|||
return (addr >= ShmemBase) && (addr < ShmemEnd);
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemInitHash -- Create and initialize, or attach to, a
|
||||
* shared memory hash table.
|
||||
*
|
||||
* We assume caller is doing some kind of synchronization
|
||||
* so that two processes don't try to create/initialize the same
|
||||
* table at once. (In practice, all creations are done in the postmaster
|
||||
* process; child processes should always be attaching to existing tables.)
|
||||
*
|
||||
* nelems is the maximum number of hashtable entries.
|
||||
*
|
||||
* *infoP and hash_flags must specify at least the entry sizes and key
|
||||
* comparison semantics (see hash_create()). Flag bits and values specific
|
||||
* to shared-memory hash tables are added here, except that callers may
|
||||
* choose to specify HASH_PARTITION.
|
||||
*
|
||||
* Note: before Postgres 9.0, this function returned NULL for some failure
|
||||
* cases. Now, it always throws error instead, so callers need not check
|
||||
* for NULL.
|
||||
*/
|
||||
HTAB *
|
||||
ShmemInitHash(const char *name, /* table string name for shmem index */
|
||||
int64 nelems, /* size of the table */
|
||||
HASHCTL *infoP, /* info about key and bucket size */
|
||||
int hash_flags) /* info about infoP */
|
||||
{
|
||||
bool found;
|
||||
size_t size;
|
||||
void *location;
|
||||
|
||||
size = hash_estimate_size(nelems, infoP->entrysize);
|
||||
|
||||
/* look it up in the shmem index or allocate */
|
||||
location = ShmemInitStruct(name, size, &found);
|
||||
|
||||
return shmem_hash_create(location, size, found,
|
||||
name, nelems, infoP, hash_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize or attach to a shared hash table in the given shmem region.
|
||||
*
|
||||
* This is extracted from ShmemInitHash() to allow InitShmemAllocator() to
|
||||
* share the logic for bootstrapping the ShmemIndex hash table.
|
||||
*/
|
||||
static HTAB *
|
||||
shmem_hash_create(void *location, size_t size, bool found,
|
||||
const char *name, int64 nelems, HASHCTL *infoP, int hash_flags)
|
||||
{
|
||||
shmem_hash_allocator allocator;
|
||||
|
||||
/*
|
||||
* Hash tables allocated in shared memory have a fixed directory and have
|
||||
* all elements allocated upfront. We don't support growing because we'd
|
||||
* need to grow the underlying shmem region with it.
|
||||
*
|
||||
* The shared memory allocator must be specified too.
|
||||
*/
|
||||
infoP->alloc = ShmemHashAlloc;
|
||||
infoP->alloc_arg = NULL;
|
||||
hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_FIXED_SIZE;
|
||||
|
||||
/*
|
||||
* if it already exists, attach to it rather than allocate and initialize
|
||||
* new space
|
||||
*/
|
||||
if (!found)
|
||||
{
|
||||
allocator.next = (char *) location;
|
||||
allocator.end = (char *) location + size;
|
||||
infoP->alloc_arg = &allocator;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pass location of hashtable header to hash_create */
|
||||
infoP->hctl = (HASHHDR *) location;
|
||||
hash_flags |= HASH_ATTACH;
|
||||
}
|
||||
|
||||
return hash_create(name, nelems, infoP, hash_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemInitStruct -- Create/attach to a structure in shared memory.
|
||||
*
|
||||
|
|
|
|||
139
src/backend/storage/ipc/shmem_hash.c
Normal file
139
src/backend/storage/ipc/shmem_hash.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* shmem_hash.c
|
||||
* hash table implementation in shared memory
|
||||
*
|
||||
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* A shared memory hash table implementation on top of the named, fixed-size
|
||||
* shared memory areas managed by shmem.c. Each hash table has its own free
|
||||
* list, so hash buckets can be reused when an item is deleted.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/storage/ipc/shmem_hash.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/shmem_internal.h"
|
||||
|
||||
/*
|
||||
* A very simple allocator used to carve out different parts of a hash table
|
||||
* from a previously allocated contiguous shared memory area.
|
||||
*/
|
||||
typedef struct shmem_hash_allocator
|
||||
{
|
||||
char *next; /* start of free space in the area */
|
||||
char *end; /* end of the shmem area */
|
||||
} shmem_hash_allocator;
|
||||
|
||||
static void *ShmemHashAlloc(Size size, void *alloc_arg);
|
||||
|
||||
/*
|
||||
* ShmemInitHash -- Create and initialize, or attach to, a
|
||||
* shared memory hash table.
|
||||
*
|
||||
* We assume caller is doing some kind of synchronization
|
||||
* so that two processes don't try to create/initialize the same
|
||||
* table at once. (In practice, all creations are done in the postmaster
|
||||
* process; child processes should always be attaching to existing tables.)
|
||||
*
|
||||
* nelems is the maximum number of hashtable entries.
|
||||
*
|
||||
* *infoP and hash_flags must specify at least the entry sizes and key
|
||||
* comparison semantics (see hash_create()). Flag bits and values specific
|
||||
* to shared-memory hash tables are added here, except that callers may
|
||||
* choose to specify HASH_PARTITION.
|
||||
*
|
||||
* Note: before Postgres 9.0, this function returned NULL for some failure
|
||||
* cases. Now, it always throws error instead, so callers need not check
|
||||
* for NULL.
|
||||
*/
|
||||
HTAB *
|
||||
ShmemInitHash(const char *name, /* table string name for shmem index */
|
||||
int64 nelems, /* size of the table */
|
||||
HASHCTL *infoP, /* info about key and bucket size */
|
||||
int hash_flags) /* info about infoP */
|
||||
{
|
||||
bool found;
|
||||
size_t size;
|
||||
void *location;
|
||||
|
||||
size = hash_estimate_size(nelems, infoP->entrysize);
|
||||
|
||||
/* look it up in the shmem index or allocate */
|
||||
location = ShmemInitStruct(name, size, &found);
|
||||
|
||||
return shmem_hash_create(location, size, found,
|
||||
name, nelems, infoP, hash_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize or attach to a shared hash table in the given shmem region.
|
||||
*
|
||||
* This is extracted from ShmemInitHash() to allow InitShmemAllocator() to
|
||||
* share the logic for bootstrapping the ShmemIndex hash table.
|
||||
*/
|
||||
HTAB *
|
||||
shmem_hash_create(void *location, size_t size, bool found,
|
||||
const char *name, int64 nelems, HASHCTL *infoP, int hash_flags)
|
||||
{
|
||||
shmem_hash_allocator allocator;
|
||||
|
||||
/*
|
||||
* Hash tables allocated in shared memory have a fixed directory and have
|
||||
* all elements allocated upfront. We don't support growing because we'd
|
||||
* need to grow the underlying shmem region with it.
|
||||
*
|
||||
* The shared memory allocator must be specified too.
|
||||
*/
|
||||
infoP->alloc = ShmemHashAlloc;
|
||||
infoP->alloc_arg = NULL;
|
||||
hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_FIXED_SIZE;
|
||||
|
||||
/*
|
||||
* if it already exists, attach to it rather than allocate and initialize
|
||||
* new space
|
||||
*/
|
||||
if (!found)
|
||||
{
|
||||
allocator.next = (char *) location;
|
||||
allocator.end = (char *) location + size;
|
||||
infoP->alloc_arg = &allocator;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pass location of hashtable header to hash_create */
|
||||
infoP->hctl = (HASHHDR *) location;
|
||||
hash_flags |= HASH_ATTACH;
|
||||
}
|
||||
|
||||
return hash_create(name, nelems, infoP, hash_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* ShmemHashAlloc -- alloc callback for shared memory hash tables
|
||||
*
|
||||
* Carve out the allocation from a pre-allocated region. All shared memory
|
||||
* hash tables are initialized with HASH_FIXED_SIZE, so all the allocations
|
||||
* happen upfront during initialization and no locking is required.
|
||||
*/
|
||||
static void *
|
||||
ShmemHashAlloc(Size size, void *alloc_arg)
|
||||
{
|
||||
shmem_hash_allocator *allocator = (shmem_hash_allocator *) alloc_arg;
|
||||
void *result;
|
||||
|
||||
size = MAXALIGN(size);
|
||||
|
||||
if (allocator->end - allocator->next < size)
|
||||
return NULL;
|
||||
result = allocator->next;
|
||||
allocator->next += size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -3,6 +3,11 @@
|
|||
* shmem.h
|
||||
* shared memory management structures
|
||||
*
|
||||
* This file contains public functions for other core subsystems and
|
||||
* extensions to allocate shared memory. Internal functions for the shmem
|
||||
* allocator itself and hooking it to the rest of the system are in
|
||||
* shmem_internal.h
|
||||
*
|
||||
* Historical note:
|
||||
* A long time ago, Postgres' shared memory region was allowed to be mapped
|
||||
* at a different address in each process, and shared memory "pointers" were
|
||||
|
|
@ -25,36 +30,20 @@
|
|||
|
||||
|
||||
/* shmem.c */
|
||||
typedef struct PGShmemHeader PGShmemHeader; /* avoid including
|
||||
* storage/pg_shmem.h here */
|
||||
extern void InitShmemAllocator(PGShmemHeader *seghdr);
|
||||
extern void *ShmemAlloc(Size size);
|
||||
extern void *ShmemAllocNoError(Size size);
|
||||
extern bool ShmemAddrIsValid(const void *addr);
|
||||
extern HTAB *ShmemInitHash(const char *name, int64 nelems,
|
||||
HASHCTL *infoP, int hash_flags);
|
||||
extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr);
|
||||
extern Size add_size(Size s1, Size s2);
|
||||
extern Size mul_size(Size s1, Size s2);
|
||||
|
||||
extern PGDLLIMPORT Size pg_get_shmem_pagesize(void);
|
||||
|
||||
/* shmem_hash.c */
|
||||
extern HTAB *ShmemInitHash(const char *name, int64 nelems,
|
||||
HASHCTL *infoP, int hash_flags);
|
||||
|
||||
/* ipci.c */
|
||||
extern void RequestAddinShmemSpace(Size size);
|
||||
|
||||
/* size constants for the shmem index table */
|
||||
/* max size of data structure string name */
|
||||
#define SHMEM_INDEX_KEYSIZE (48)
|
||||
/* max number of named shmem structures and hash tables */
|
||||
#define SHMEM_INDEX_SIZE (256)
|
||||
|
||||
/* this is a hash bucket in the shmem index table */
|
||||
typedef struct
|
||||
{
|
||||
char key[SHMEM_INDEX_KEYSIZE]; /* string name */
|
||||
void *location; /* location in shared mem */
|
||||
Size size; /* # bytes requested for the structure */
|
||||
Size allocated_size; /* # bytes actually allocated */
|
||||
} ShmemIndexEnt;
|
||||
|
||||
#endif /* SHMEM_H */
|
||||
|
|
|
|||
41
src/include/storage/shmem_internal.h
Normal file
41
src/include/storage/shmem_internal.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* shmem_internal.h
|
||||
* Internal functions related to shmem allocation
|
||||
*
|
||||
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/storage/shmem_internal.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SHMEM_INTERNAL_H
|
||||
#define SHMEM_INTERNAL_H
|
||||
|
||||
#include "storage/shmem.h"
|
||||
#include "utils/hsearch.h"
|
||||
|
||||
typedef struct PGShmemHeader PGShmemHeader; /* avoid including
|
||||
* storage/pg_shmem.h here */
|
||||
extern void InitShmemAllocator(PGShmemHeader *seghdr);
|
||||
|
||||
extern HTAB *shmem_hash_create(void *location, size_t size, bool found,
|
||||
const char *name, int64 nelems, HASHCTL *infoP, int hash_flags);
|
||||
|
||||
/* size constants for the shmem index table */
|
||||
/* max size of data structure string name */
|
||||
#define SHMEM_INDEX_KEYSIZE (48)
|
||||
/* max number of named shmem structures and hash tables */
|
||||
#define SHMEM_INDEX_SIZE (256)
|
||||
|
||||
/* this is a hash bucket in the shmem index table */
|
||||
typedef struct
|
||||
{
|
||||
char key[SHMEM_INDEX_KEYSIZE]; /* string name */
|
||||
void *location; /* location in shared mem */
|
||||
Size size; /* # bytes requested for the structure */
|
||||
Size allocated_size; /* # bytes actually allocated */
|
||||
} ShmemIndexEnt;
|
||||
|
||||
#endif /* SHMEM_INTERNAL_H */
|
||||
Loading…
Reference in a new issue