From 395a95e9934286869b1fe8d45dc5a155ea9be030 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Tue, 10 Feb 2026 20:26:31 +0530
Subject: [PATCH 2/3] Get rid of global shared memory pointer macro
 declarations

---
 .../pg_stat_statements/pg_stat_statements.c   | 10 ++++---
 src/backend/access/transam/varsup.c           |  5 ++++
 src/backend/storage/ipc/dsm.c                 |  5 ++--
 src/backend/storage/ipc/dsm_registry.c        |  4 ++-
 src/backend/storage/ipc/pmsignal.c            | 18 +++++-------
 src/backend/storage/ipc/procarray.c           | 13 +++++----
 src/backend/storage/ipc/procsignal.c          |  4 ++-
 src/backend/storage/ipc/shmem.c               | 29 ++++++++++++-------
 src/backend/storage/ipc/sinvaladt.c           |  7 +++--
 src/backend/storage/lmgr/proc.c               | 25 ++++++++++------
 src/include/access/transam.h                  |  2 +-
 src/include/storage/shmem.h                   |  6 ++--
 12 files changed, 77 insertions(+), 51 deletions(-)

diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 71debc8b47f..73fdf561419 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -258,24 +258,26 @@ typedef struct pgssSharedState
 	pgssGlobalStats stats;		/* global statistics for pgss */
 } pgssSharedState;
 
+/* Links to shared memory state */
+pgssSharedState *pgss = NULL;
+HTAB *pgss_hash = NULL;
+
 static void pgss_shmem_init(void *arg);
 
 static ShmemStructDesc pgssSharedStateShmemDesc = {
 	.name = "pg_stat_statements",
 	.size = sizeof(pgssSharedState),
 	.init_fn = pgss_shmem_init,
+	.ptr = (void *) &pgss,
 };
 
 static ShmemHashDesc pgssSharedHashDesc = {
 	.name = "pg_stat_statements hash",
 	.init_size = 0,		/* set from 'pgss_max' */
 	.max_size = 0,		/* set from 'pgss_max' */
+	.ptr = &pgss_hash,
 };
 
-/* Links to shared memory state */
-#define pgss ((pgssSharedState *) pgssSharedStateShmemDesc.ptr)
-#define pgss_hash (pgssSharedHashDesc.ptr)
-
 
 /*---- Local variables ----*/
 
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 11ad90e7372..3dfda875e80 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -32,10 +32,14 @@
 
 static void VarsupShmemInit(void *arg);
 
+/* pointer to variables struct in shared memory */
+TransamVariablesData *TransamVariables = NULL;
+
 ShmemStructDesc TransamVariablesShmemDesc = {
 	.name = "TransamVariables",
 	.size = sizeof(TransamVariablesData),
 	.init_fn = VarsupShmemInit,
+	.ptr = (void **) &TransamVariables,
 };
 
 /*
@@ -49,6 +53,7 @@ VarsupShmemRegister(void)
 
 static void
 VarsupShmemInit(void *arg)
+
 {
 	memset(TransamVariables, 0, sizeof(TransamVariablesData));
 }
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 55f46c7687e..73644ec3bbb 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -110,14 +110,15 @@ static bool dsm_init_done = false;
 /* Preallocated DSM space in the main shared memory region. */
 static void dsm_main_space_init(void *);
 
+static void *dsm_main_space_begin = NULL;
+
 static ShmemStructDesc dsm_main_space_shmem_desc = {
 	.name = "Preallocated DSM",
 	.size = 0, /* dynamic */
 	.init_fn = dsm_main_space_init,
+	.ptr = &dsm_main_space_begin,
 };
 
-#define dsm_main_space_begin (dsm_main_space_shmem_desc.ptr)
-
 /*
  * List of dynamic shared memory segments used by this backend.
  *
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index 882af83b7b2..1659e1dd71d 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -56,13 +56,15 @@ typedef struct DSMRegistryCtxStruct
 
 static void DSMRegistryCtxShmemInit(void *arg);
 
+DSMRegistryCtxStruct *DSMRegistryCtx = NULL;
+
 static ShmemStructDesc DSMRegistryCtxShmemDesc = {
 	.name = "DSM Registry Data",
 	.size = sizeof(DSMRegistryCtxStruct),
 	.init_fn = DSMRegistryCtxShmemInit,
+	.ptr = (void **) &DSMRegistryCtx,
 };
 
-#define DSMRegistryCtx ((DSMRegistryCtxStruct *) DSMRegistryCtxShmemDesc.ptr)
 
 typedef struct NamedDSMState
 {
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 23752500d16..3aa0380eadd 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -82,21 +82,17 @@ struct PMSignalData
 
 static void PMSignalShmemInit(void *);
 
-static ShmemStructDesc PMSignalShmemDesc = {
-	.name = "PMSignalState",
-	.size = 0, /* dynamic */
-	.init_fn = PMSignalShmemInit,
-};
-
 /*
  * PMSignalState pointer is valid in both postmaster and child processes
- *
- * This is a stand-alone variable rather than just a #define over
- * PMSignalShmemDesc.ptr because it is needed early at backend startup and
- * passed as a backend parameter in EXEC_BACKEND mode
  */
 NON_EXEC_STATIC volatile PMSignalData *PMSignalState = NULL;
 
+static ShmemStructDesc PMSignalShmemDesc = {
+	.name = "PMSignalState",
+	.size = 0, /* dynamic */
+	.init_fn = PMSignalShmemInit,
+	.ptr = (void **) &PMSignalState,
+};
 
 /*
  * Local copy of PMSignalState->num_child_flags, only valid in the
@@ -156,7 +152,7 @@ static void
 PMSignalShmemInit(void *arg)
 {
 	/* initialize all flags to zeroes */
-	PMSignalState = PMSignalShmemDesc.ptr;
+	Assert(PMSignalState);
 	MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemDesc.size);
 	num_child_flags = MaxLivePostmasterChildren();
 	PMSignalState->num_child_flags = num_child_flags;
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 08c63bcb2a7..736504d3a3e 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -104,15 +104,16 @@ typedef struct ProcArrayStruct
 static void ProcArrayShmemInit(void *arg);
 static void ProcArrayShmemAttach(void *arg);
 
+ProcArrayStruct *procArray = NULL;
+
 static ShmemStructDesc ProcArrayShmemDesc = {
 	.name = "Proc Array",
 	.size = 0, /* dynamic */
 	.init_fn = ProcArrayShmemInit,
 	.attach_fn = ProcArrayShmemAttach,
+	.ptr = (void **) &procArray,
 };
 
-#define procArray ((ProcArrayStruct *) ProcArrayShmemDesc.ptr)
-
 /*
  * State for the GlobalVisTest* family of functions. Those functions can
  * e.g. be used to decide if a deleted row can be removed without violating
@@ -290,22 +291,24 @@ static TransactionId cachedXidIsNotInProgress = InvalidTransactionId;
  * Bookkeeping for tracking emulated transactions in recovery
  */
 
+TransactionId *KnownAssignedXids = NULL;
+
 static ShmemStructDesc KnownAssignedXidsShmemDesc = {
 	.name = "KnownAssignedXids",
 	.size = 0, /* dynamic */
 	.init_fn = NULL,
+	.ptr = (void **) &KnownAssignedXids,
 };
 
-#define KnownAssignedXids ((TransactionId *) KnownAssignedXidsShmemDesc.ptr)
+bool *KnownAssignedXidsValid = NULL;
 
 static ShmemStructDesc KnownAssignedXidsValidShmemDesc = {
 	.name = "KnownAssignedXidsValid",
 	.size = 0, /* dynamic */
 	.init_fn = NULL,
+	.ptr = (void **) &KnownAssignedXidsValid,
 };
 
-#define KnownAssignedXidsValid ((bool *) KnownAssignedXidsValidShmemDesc.ptr)
-
 static TransactionId latestObservedXid = InvalidTransactionId;
 
 /*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 5743f088324..eec04eae3f4 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -104,13 +104,15 @@ struct ProcSignalHeader
 
 static void ProcSignalShmemInit(void *arg);
 
+ProcSignalHeader *ProcSignal = NULL;
+
 static ShmemStructDesc ProcSignalShmemDesc = {
 	.name = "ProcSignal",
 	.size = 0, /* dynamic */
 	.init_fn = ProcSignalShmemInit,
+	.ptr = (void **) &ProcSignal,
 };
 
-#define ProcSignal ((ProcSignalHeader *) ProcSignalShmemDesc.ptr)
 
 static ProcSignalSlot *MyProcSignalSlot = NULL;
 
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index faa0fcbd21e..e73ac489b2b 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -118,17 +118,18 @@ static void *ShmemEnd;			/* end+1 address of shared memory */
 
 static ShmemAllocatorData *ShmemAllocator;
 slock_t    *ShmemLock;			/* points to ShmemAllocator->shmem_lock */
+ /* primary index hashtable for shmem */
+HTAB *ShmemIndex = NULL;
+
 
 
 static ShmemHashDesc ShmemIndexHashDesc = {
 	.name = "ShmemIndex",
 	.init_size = SHMEM_INDEX_SIZE,
 	.max_size = SHMEM_INDEX_SIZE,
+	.ptr = &ShmemIndex
 };
 
- /* primary index hashtable for shmem */
-#define ShmemIndex (ShmemIndexHashDesc.ptr)
-
 
 /* To get reliable results for NUMA inquiry we need to "touch pages" once */
 static bool firstNumaTouch = true;
@@ -205,7 +206,7 @@ ShmemInitRegistered(void)
 		result->allocated_size = allocated_size;
 		result->location = structPtr;
 
-		registry[i]->ptr = structPtr;
+		*(registry[i]->ptr) = structPtr;
 		if (registry[i]->init_fn)
 			registry[i]->init_fn(registry[i]->init_fn_arg);
 	}
@@ -239,7 +240,7 @@ ShmemAttachRegistered(void)
 							registry[i]->name)));
 		}
 
-		registry[i]->ptr = result->location;
+		*registry[i]->ptr = result->location;
 
 		if (registry[i]->attach_fn)
 			registry[i]->attach_fn(registry[i]->attach_fn_arg);
@@ -425,10 +426,11 @@ InitShmemIndex(void)
 	info.keysize = SHMEM_INDEX_KEYSIZE;
 	info.entrysize = sizeof(ShmemIndexEnt);
 
-	ShmemIndex = ShmemInitHash("ShmemIndex",
+	*ShmemIndexHashDesc.ptr = ShmemInitHash("ShmemIndex",
 							   SHMEM_INDEX_SIZE, SHMEM_INDEX_SIZE,
 							   &info,
 							   HASH_ELEM | HASH_STRINGS);
+	Assert(ShmemIndex != NULL && *ShmemIndexHashDesc.ptr == ShmemIndex);
 }
 
 /*
@@ -482,6 +484,12 @@ ShmemRegisterHash(ShmemHashDesc *desc,		/* configuration */
 	desc->base_desc.init_fn_arg = desc;
 	desc->base_desc.attach_fn = shmem_hash_attach;
 	desc->base_desc.attach_fn_arg = desc;
+	/*
+	 * We need a stable pointer to hold the pointer to the shared memory. Use
+	 * the one passed in the descriptor now. It will be replaced with the hash
+	 * table header by init or attach function.
+	 */
+	desc->base_desc.ptr = (void **) desc->ptr;
 
 	desc->base_desc.extra_size = hash_estimate_size(desc->max_size, infoP->entrysize) - desc->base_desc.size;
 
@@ -499,10 +507,9 @@ shmem_hash_init(void *arg)
 	int			hash_flags = desc->hash_flags;
 
 	/* Pass location of hashtable header to hash_create */
-	desc->ptr = desc->base_desc.ptr;
-	desc->infoP->hctl = (HASHHDR *) desc->ptr;
+	desc->infoP->hctl = (HASHHDR *) *desc->base_desc.ptr;
 
-	desc->ptr = hash_create(desc->name, desc->init_size, desc->infoP, hash_flags);
+	*desc->ptr = hash_create(desc->name, desc->init_size, desc->infoP, hash_flags);
 }
 
 static void
@@ -518,9 +525,9 @@ shmem_hash_attach(void *arg)
 	hash_flags |= HASH_ATTACH;
 
 	/* Pass location of hashtable header to hash_create */
-	desc->infoP->hctl = (HASHHDR *) desc->ptr;
+	desc->infoP->hctl = (HASHHDR *) *desc->base_desc.ptr;
 
-	desc->ptr = hash_create(desc->name, desc->init_size, desc->infoP, hash_flags);
+	*desc->ptr = hash_create(desc->name, desc->init_size, desc->infoP, hash_flags);
 }
 
 /*
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 0fe0f256971..8321bd9b52d 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -205,15 +205,16 @@ typedef struct SISeg
 
 static void SharedInvalShmemInit(void *arg);
 
+/* pointer to the shared inval buffer */
+SISeg *shmInvalBuffer = NULL;
+
 static ShmemStructDesc SharedInvalShmemDesc = {
 	.name = "shmInvalBuffer",
 	.size = 0,	/* dynamic */
 	.init_fn = SharedInvalShmemInit,
+	.ptr = (void **) &shmInvalBuffer,
 };
 
-/* pointer to the shared inval buffer */
-#define shmInvalBuffer ((SISeg *) SharedInvalShmemDesc.ptr)
-
 
 static LocalTransactionId nextLocalTransactionId;
 
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 85375b5195e..a3d6557aa9d 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -77,27 +77,33 @@ PGPROC	   *MyProc = NULL;
 
 static void ProcGlobalShmemInit(void *arg);
 
+/* Pointers to shared-memory structures */
+PROC_HDR   *ProcGlobal = NULL;
+void *tmpAllProcs = NULL;
+void *tmpFastPathLockArray = NULL;
+NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL;
+PGPROC	   *PreparedXactProcs = NULL;
+
+
 static ShmemStructDesc ProcGlobalShmemDesc = {
 	.name = "Proc Header",
 	.size = sizeof(PROC_HDR),
 	.init_fn = ProcGlobalShmemInit,
+	.ptr = (void **) &ProcGlobal,
 };
 
 static ShmemStructDesc ProcGlobalAllProcsShmemDesc = {
 	.name = "PGPROC structures",
 	.size = 0, /* dynamic */
+	.ptr = (void **) &tmpAllProcs,
 };
 
 static ShmemStructDesc FastPathLockArrayShmemDesc = {
 	.name = "Fast-Path Lock Array",
 	.size = 0, /* dynamic */
+	.ptr = (void **) &tmpFastPathLockArray,
 };
 
-/* Pointers to shared-memory structures */
-PROC_HDR   *ProcGlobal = NULL;
-NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL;
-PGPROC	   *PreparedXactProcs = NULL;
-
 static uint32 TotalProcs;
 
 static DeadLockState deadlock_state = DS_NOT_YET_CHECKED;
@@ -222,8 +228,7 @@ ProcGlobalShmemInit(void *arg)
 	Size		fpLockBitsSize,
 				fpRelIdSize;
 
-	ProcGlobal = ProcGlobalShmemDesc.ptr;
-
+	Assert(ProcGlobal);
 	ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
 	dlist_init(&ProcGlobal->freeProcs);
 	dlist_init(&ProcGlobal->autovacFreeProcs);
@@ -236,7 +241,8 @@ ProcGlobalShmemInit(void *arg)
 	pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER);
 	SpinLockInit(ProcStructLock);
 
-	ptr = ProcGlobalAllProcsShmemDesc.ptr;
+	Assert(tmpAllProcs);
+	ptr = tmpAllProcs;
 	requestSize = ProcGlobalAllProcsShmemDesc.size;
 	memset(ptr, 0, requestSize);
 
@@ -274,7 +280,8 @@ ProcGlobalShmemInit(void *arg)
 	fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
 	fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
 
-	fpPtr = FastPathLockArrayShmemDesc.ptr;
+	Assert(tmpFastPathLockArray);
+	fpPtr = tmpFastPathLockArray;
 	requestSize = FastPathLockArrayShmemDesc.size;
 	memset(fpPtr, 0, requestSize);
 
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 49d476e9d5c..6e5a546f411 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -334,7 +334,7 @@ extern bool TransactionStartedDuringRecovery(void);
 /* in transam/varsup.c */
 #ifndef FRONTEND
 extern PGDLLIMPORT struct ShmemStructDesc TransamVariablesShmemDesc;
-#define TransamVariables ((TransamVariablesData *) TransamVariablesShmemDesc.ptr)
+extern PGDLLIMPORT TransamVariablesData *TransamVariables;
 #endif
 
 /*
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index 40e2fc17056..cbd4ef8d03f 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -50,8 +50,8 @@ typedef struct ShmemStructDesc
 	 */
 	size_t		extra_size;
 
-	/* Pointer to the shared memory area, when it's allocated. */
-	void	   *ptr;
+	/* Pointer to the variable to which pointer to this shared memory area is assigned after allocation. */
+	void	   **ptr;
 } ShmemStructDesc;
 
 /*
@@ -67,7 +67,7 @@ typedef struct ShmemHashDesc
 	size_t		max_size;		/* max number of entries */
 	HASHCTL	   *infoP;
 
-	HTAB	   *ptr;
+	HTAB	   **ptr;
 
 	ShmemStructDesc	base_desc;
 } ShmemHashDesc;
-- 
2.34.1

