]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Move some code from shmem.c and shmem.h
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 5 Apr 2026 23:12:48 +0000 (02:12 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 5 Apr 2026 23:12:48 +0000 (02:12 +0300)
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

src/backend/postmaster/launch_backend.c
src/backend/storage/ipc/Makefile
src/backend/storage/ipc/ipci.c
src/backend/storage/ipc/meson.build
src/backend/storage/ipc/shmem.c
src/backend/storage/ipc/shmem_hash.c [new file with mode: 0644]
src/include/storage/shmem.h
src/include/storage/shmem_internal.h [new file with mode: 0644]

index 434e06430220e29db68642cec1e42cd763fd3bcd..15b136ea29d4d37c2361f77de46b949ceb32ce50 100644 (file)
@@ -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"
 
index 9a07f6e1d92ab4a664959ff1ca68c19235d8de5f..f71653bbe482e36a57f2cfad93bd6a975c2aef66 100644 (file)
@@ -22,6 +22,7 @@ OBJS = \
        shm_mq.o \
        shm_toc.o \
        shmem.o \
+       shmem_hash.o \
        signalfuncs.o \
        sinval.o \
        sinvaladt.o \
index 7aab5da3386071e7139585c13f60a0a101ee675b..ca4e472748921c1269713ca2650c8cb227329055 100644 (file)
@@ -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"
index 9c1ca954d9d3875f5c4dad71c23327050d3ef2ae..b8c31e29967dad06a7b991584dc53c2b8a63fd97 100644 (file)
@@ -14,6 +14,7 @@ backend_sources += files(
   'shm_mq.c',
   'shm_toc.c',
   'shmem.c',
+  'shmem_hash.c',
   'signalfuncs.c',
   'sinval.c',
   'sinvaladt.c',
index 3cb51ad62f8bf41719d9121f023810dea0baa271..e91c47d4d97ab10dbd770a58decf3f8b45f8429c 100644 (file)
@@ -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.
  *
diff --git a/src/backend/storage/ipc/shmem_hash.c b/src/backend/storage/ipc/shmem_hash.c
new file mode 100644 (file)
index 0000000..1ca4a32
--- /dev/null
@@ -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;
+}
index a2eb499d63c42921ea3b675cb58559deee72b889..81d05381f8f923e2a0a395530772f2dc302dba6e 100644 (file)
@@ -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
 
 
 /* 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 */
diff --git a/src/include/storage/shmem_internal.h b/src/include/storage/shmem_internal.h
new file mode 100644 (file)
index 0000000..e063813
--- /dev/null
@@ -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 */