v20260406-0004-Avoid-creating-ABI-incompatibility-because.patch
text/x-patch
Filename: v20260406-0004-Avoid-creating-ABI-incompatibility-because.patch
Type: text/x-patch
Part: 2
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v20260406-0004
Subject: Avoid creating ABI incompatibility because of HAVE_RESIZABLE_SHMEM
| File | + | − |
|---|---|---|
| src/backend/port/sysv_shmem.c | 12 | 2 |
| src/backend/port/win32_shmem.c | 22 | 0 |
| src/backend/storage/ipc/shmem.c | 17 | 31 |
| src/include/storage/pg_shmem.h | 0 | 2 |
| src/include/storage/shmem.h | 0 | 5 |
| src/test/modules/resizable_shmem/resizable_shmem.c | 12 | 10 |
| src/test/modules/test_shmem/test_shmem.c | 0 | 6 |
From 45696d8f2371cceca1e38719ef49036cdd67c250 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Mon, 6 Apr 2026 13:00:00 +0530
Subject: [PATCH v20260406 4/6] Avoid creating ABI incompatibility because of
HAVE_RESIZABLE_SHMEM
Per the suggestion at https://www.postgresql.org/message-id/CAEze2Wjn2cpQEPwzLajc0XdcMy8T=d1AWjg3UAmMUT2TmHkQkA@mail.gmail.com
---
src/backend/port/sysv_shmem.c | 14 +++++-
src/backend/port/win32_shmem.c | 22 +++++++++
src/backend/storage/ipc/shmem.c | 48 +++++++------------
src/include/storage/pg_shmem.h | 2 -
src/include/storage/shmem.h | 5 --
.../modules/resizable_shmem/resizable_shmem.c | 22 +++++----
src/test/modules/test_shmem/test_shmem.c | 6 ---
7 files changed, 63 insertions(+), 56 deletions(-)
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index 8d859dfbbfb..bb2a81417c6 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -1013,7 +1013,6 @@ PGSharedMemoryDetach(void)
}
}
-#ifdef HAVE_RESIZABLE_SHMEM
/*
* Make sure that the memory of given size from the given address is released.
*
@@ -1024,6 +1023,11 @@ PGSharedMemoryDetach(void)
void
PGSharedMemoryEnsureFreed(void *addr, Size size)
{
+#ifndef HAVE_RESIZABLE_SHMEM
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("resizable shared memory is not supported on this platform")));
+#else
if (!AnonymousShmem)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1035,6 +1039,7 @@ PGSharedMemoryEnsureFreed(void *addr, Size size)
if (madvise(addr, size, MADV_REMOVE) == -1)
ereport(ERROR,
(errmsg("could not free shared memory: %m")));
+#endif
}
/*
@@ -1047,6 +1052,11 @@ PGSharedMemoryEnsureFreed(void *addr, Size size)
void
PGSharedMemoryEnsureAllocated(void *addr, Size size)
{
+#ifndef HAVE_RESIZABLE_SHMEM
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("resizable shared memory is not supported on this platform")));
+#else
if (!AnonymousShmem)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1058,5 +1068,5 @@ PGSharedMemoryEnsureAllocated(void *addr, Size size)
if (madvise(addr, size, MADV_POPULATE_WRITE) == -1)
ereport(ERROR,
(errmsg("could not allocate shared memory: %m")));
+#endif
}
-#endif /* HAVE_RESIZABLE_SHMEM */
diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
index dc2ee018845..c1f30665e66 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -671,3 +671,25 @@ GetOSPageSize(void)
return os_page_size;
}
+
+/*
+ * PGSharedMemoryEnsureFreed / PGSharedMemoryEnsureAllocated
+ *
+ * Not supported on Windows. These are only meaningful on platforms with
+ * resizable shared memory (mmap + madvise).
+ */
+void
+PGSharedMemoryEnsureFreed(void *addr, Size size)
+{
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("resizable shared memory is not supported on this platform")));
+}
+
+void
+PGSharedMemoryEnsureAllocated(void *addr, Size size)
+{
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("resizable shared memory is not supported on this platform")));
+}
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 03de5d88d51..4a3e8a8769e 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -185,14 +185,12 @@ typedef struct
/*
* A convenient macro to get the space required for a shmem request consistently.
* A resizable structure, requested by non-zero maximum_size, requires space for
- * its maximum size.
+ * its maximum size. Please note that on the platforms that do not support
+ * resizable shmem, the maximum_size is ensured to be 0 i.e. all the structures
+ * are treated as fixed-size structures.
*/
-#ifdef HAVE_RESIZABLE_SHMEM
#define SHMEM_REQUEST_SPACE_SIZE(request) \
((request)->options->maximum_size > 0 ? (request)->options->maximum_size : (request)->options->size)
-#else
-#define SHMEM_REQUEST_SPACE_SIZE(request) ((request)->options->size)
-#endif
static List *pending_shmem_requests;
@@ -296,10 +294,8 @@ typedef struct
void *location; /* location in shared mem */
Size size; /* # bytes requested for the structure */
Size allocated_size; /* # bytes actually allocated */
-#ifdef HAVE_RESIZABLE_SHMEM
Size maximum_size; /* the maximum size the structure can grow to */
Size reserved_space; /* the total address space reserved */
-#endif
} ShmemIndexEnt;
/* To get reliable results for NUMA inquiry we need to "touch pages" once */
@@ -308,9 +304,7 @@ static bool firstNumaTouch = true;
static void CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks);
static void InitShmemIndexEntry(ShmemRequest *request);
static bool AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok);
-#ifdef HAVE_RESIZABLE_SHMEM
static Size EstimateAllocatedSize(ShmemIndexEnt *entry);
-#endif
Datum pg_numa_available(PG_FUNCTION_ARGS);
@@ -376,16 +370,22 @@ ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind)
if (options->name == NULL)
elog(ERROR, "shared memory request is missing 'name' option");
+#ifndef HAVE_RESIZABLE_SHMEM
+ if (options->maximum_size > 0)
+ elog(ERROR, "resizable shared memory is not supported on this platform");
+#else
+ if (options->maximum_size > 0 && shared_memory_type != SHMEM_TYPE_MMAP)
+ elog(ERROR, "resizable shared memory requires shared_memory_type = mmap");
+#endif
+
if (IsUnderPostmaster)
{
if (options->size <= 0 && options->size != SHMEM_ATTACH_UNKNOWN_SIZE)
elog(ERROR, "invalid size %zd for shared memory request for \"%s\"",
options->size, options->name);
-#ifdef HAVE_RESIZABLE_SHMEM
if (options->maximum_size < 0 && options->maximum_size != SHMEM_ATTACH_UNKNOWN_SIZE)
elog(ERROR, "invalid maximum_size %zd for shared memory request for \"%s\"",
options->maximum_size, options->name);
-#endif
}
else
{
@@ -394,28 +394,21 @@ ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind)
if (options->size <= 0)
elog(ERROR, "invalid size %zd for shared memory request for \"%s\"",
options->size, options->name);
-#ifdef HAVE_RESIZABLE_SHMEM
if (options->maximum_size == SHMEM_ATTACH_UNKNOWN_SIZE)
elog(ERROR, "SHMEM_ATTACH_UNKNOWN_SIZE cannot be used during startup");
if (options->maximum_size < 0)
elog(ERROR, "invalid maximum_size %zd for shared memory request for \"%s\"",
options->maximum_size, options->name);
-#endif
}
if (options->alignment != 0 && pg_nextpower2_size_t(options->alignment) != options->alignment)
elog(ERROR, "invalid alignment %zu for shared memory request for \"%s\"",
options->alignment, options->name);
-#ifdef HAVE_RESIZABLE_SHMEM
if (options->maximum_size > 0 && options->size > options->maximum_size)
elog(ERROR, "resizable shared memory structure \"%s\" should have maximum size (%zd) greater than size (%zd)",
options->name, options->maximum_size, options->size);
- if (options->maximum_size > 0 && shared_memory_type != SHMEM_TYPE_MMAP)
- elog(ERROR, "resizable shared memory requires shared_memory_type = mmap");
-#endif
-
/* Check that we're in the right state */
if (shmem_request_state != SRS_REQUESTING)
elog(ERROR, "ShmemRequestStruct can only be called from a shmem_request callback");
@@ -620,7 +613,6 @@ InitShmemIndexEntry(ShmemRequest *request)
index_entry->size = request->options->size;
index_entry->allocated_size = allocated_size;
index_entry->location = structPtr;
-#ifdef HAVE_RESIZABLE_SHMEM
index_entry->reserved_space = allocated_size;
index_entry->maximum_size = request->options->maximum_size;
if (request->options->maximum_size > 0)
@@ -628,7 +620,6 @@ InitShmemIndexEntry(ShmemRequest *request)
/* Adjust allocated size of a resizable structure. */
index_entry->allocated_size = EstimateAllocatedSize(index_entry);
}
-#endif
/* Initialize depending on the kind of shmem area it is */
switch (request->kind)
@@ -683,7 +674,6 @@ AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok)
name, index_entry->size, request->options->size)));
}
-#ifdef HAVE_RESIZABLE_SHMEM
if (index_entry->maximum_size != request->options->maximum_size &&
request->options->maximum_size != SHMEM_ATTACH_UNKNOWN_SIZE)
{
@@ -693,7 +683,6 @@ AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok)
name, index_entry->maximum_size,
request->options->maximum_size)));
}
-#endif
/*
* Re-establish the caller's pointer variable, or do other actions to
@@ -716,7 +705,6 @@ AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok)
return true;
}
-#ifdef HAVE_RESIZABLE_SHMEM
/*
* Estimate the actual memory allocated for a resizable structure.
*
@@ -760,6 +748,11 @@ EstimateAllocatedSize(ShmemIndexEnt *entry)
void
ShmemResizeStruct(const char *name, Size new_size)
{
+#ifndef HAVE_RESIZABLE_SHMEM
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("resizable shared memory is not supported on this platform")));
+#else
ShmemIndexEnt *result;
bool found;
Size page_size = GetOSPageSize();
@@ -822,8 +815,8 @@ ShmemResizeStruct(const char *name, Size new_size)
result->allocated_size = EstimateAllocatedSize(result);
LWLockRelease(ShmemIndexLock);
+#endif
}
-#endif /* HAVE_RESIZABLE_SHMEM */
/*
* InitShmemAllocator() --- set up basic pointers to shared memory.
@@ -1300,7 +1293,6 @@ pg_get_shmem_allocations(PG_FUNCTION_ARGS)
values[1] = Int64GetDatum((char *) ent->location - (char *) ShmemSegHdr);
values[2] = Int64GetDatum(ent->size);
values[3] = Int64GetDatum(ent->allocated_size);
-#ifdef HAVE_RESIZABLE_SHMEM
values[4] = Int64GetDatum(ent->maximum_size);
values[5] = Int64GetDatum(ent->reserved_space);
@@ -1311,12 +1303,6 @@ pg_get_shmem_allocations(PG_FUNCTION_ARGS)
* the segment.
*/
named_allocated += ent->reserved_space;
-#else
- values[4] = Int64GetDatum(0);
- values[5] = Int64GetDatum(ent->allocated_size);
-
- named_allocated += ent->allocated_size;
-#endif
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
values, nulls);
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 3d5aceba59c..f0efbf2aec1 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -89,10 +89,8 @@ extern PGShmemHeader *PGSharedMemoryCreate(Size size,
PGShmemHeader **shim);
extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2);
extern void PGSharedMemoryDetach(void);
-#ifdef HAVE_RESIZABLE_SHMEM
extern void PGSharedMemoryEnsureFreed(void *addr, Size size);
extern void PGSharedMemoryEnsureAllocated(void *addr, Size size);
-#endif
extern void GetHugePageSize(Size *hugepagesize, int *mmap_flags);
extern Size GetOSPageSize(void);
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index f356027e500..8140a0255ae 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -57,8 +57,6 @@ typedef struct ShmemStructOpts
*/
size_t alignment;
-#ifdef HAVE_RESIZABLE_SHMEM
-
/*
* Maximum size this structure can grow upto in future. The memory is not
* allocated right away but the corresponding address space is reserved so
@@ -68,7 +66,6 @@ typedef struct ShmemStructOpts
* structures.
*/
ssize_t maximum_size;
-#endif
/*
* When the shmem area is initialized or attached to, pointer to it is
@@ -181,9 +178,7 @@ typedef struct ShmemCallbacks
extern void RegisterShmemCallbacks(const ShmemCallbacks *callbacks);
extern bool ShmemAddrIsValid(const void *addr);
-#ifdef HAVE_RESIZABLE_SHMEM
extern void ShmemResizeStruct(const char *name, Size new_size);
-#endif
/*
* These macros provide syntactic sugar for calling the underlying functions
diff --git a/src/test/modules/resizable_shmem/resizable_shmem.c b/src/test/modules/resizable_shmem/resizable_shmem.c
index 66754582b32..fb3dfd64b4b 100644
--- a/src/test/modules/resizable_shmem/resizable_shmem.c
+++ b/src/test/modules/resizable_shmem/resizable_shmem.c
@@ -135,20 +135,24 @@ resizable_shmem_request(void *arg)
{
Size initial_size = add_size(offsetof(TestResizableShmemStruct, data),
mul_size(test_initial_entries, TEST_ENTRY_SIZE));
+
+/*
+ * Create resizable structure on the platforms which support it. Otherwise create
+ * as a fixed-size structure. Other way would be to conditionally include
+ * .maximum_size in the call to ShmemRequestStruct().
+ */
#ifdef HAVE_RESIZABLE_SHMEM
Size max_size = add_size(offsetof(TestResizableShmemStruct, data),
mul_size(test_max_entries, TEST_ENTRY_SIZE));
- /* A preprocessor macro to conditionally include the maximum_size field. */
-#define MAXIMUM_SIZE_ARG .maximum_size = max_size,
#else
-#define MAXIMUM_SIZE_ARG
+ Size max_size = 0;
#endif
/* Register our resizable shared memory structure */
ShmemRequestStruct(.name = "resizable_shmem",
.size = use_unknown_size ? SHMEM_ATTACH_UNKNOWN_SIZE : initial_size,
- MAXIMUM_SIZE_ARG
+ .maximum_size = max_size,
.ptr = (void **) &resizable_shmem,
);
}
@@ -172,11 +176,14 @@ resizable_shmem_shmem_init(void *arg)
/*
* Resize the shared memory structure to accommodate the specified number of
* entries.
+ *
+ * On the plaforms which do not support resizable shared memory,
+ * ShmemResizeStruct() will raise an error, so this function will fail if the
+ * caller tries to resize the structure.
*/
Datum
resizable_shmem_resize(PG_FUNCTION_ARGS)
{
-#ifdef HAVE_RESIZABLE_SHMEM
int32 new_entries = PG_GETARG_INT32(0);
Size new_size;
@@ -191,11 +198,6 @@ resizable_shmem_resize(PG_FUNCTION_ARGS)
resizable_shmem->num_entries = new_entries;
PG_RETURN_VOID();
-#else
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("resizable shared memory is not supported on this platform")));
-#endif
}
/*
diff --git a/src/test/modules/test_shmem/test_shmem.c b/src/test/modules/test_shmem/test_shmem.c
index fc2fd67887f..0dd469891ee 100644
--- a/src/test/modules/test_shmem/test_shmem.c
+++ b/src/test/modules/test_shmem/test_shmem.c
@@ -108,14 +108,8 @@ PG_FUNCTION_INFO_V1(test_shmem_resize_fixed);
Datum
test_shmem_resize_fixed(PG_FUNCTION_ARGS)
{
-#ifdef HAVE_RESIZABLE_SHMEM
int32 new_size = PG_GETARG_INT32(0);
ShmemResizeStruct("test_shmem area", new_size);
PG_RETURN_VOID();
-#else
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("resizable shared memory is not supported on this platform")));
-#endif
}
--
2.34.1