summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2025-11-06 14:45:00 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2025-11-06 14:45:00 +0200
commitaa9c5fd3e3d7f1e6154474e39ab71377136d463a (patch)
treef061ab14e14dacd5f360ce892cca2a1b7038c096 /src
parentdaf3d99d2b8bebb3361163a11ef3d232002127c9 (diff)
Refactor shared memory allocation for semaphores
Before commit e25626677f, spinlocks were implemented using semaphores on some platforms (--disable-spinlocks). That made it necessary to initialize semaphores early, before any spinlocks could be used. Now that we don't support --disable-spinlocks anymore, we can allocate the shared memory needed for semaphores the same way as other shared memory structures. Since the semaphores are used only in the PGPROC array, move the semaphore shmem size estimation and initialization calls to ProcGlobalShmemSize() and InitProcGlobal(). Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://www.postgresql.org/message-id/CAExHW5seSZpPx-znjidVZNzdagGHOk06F+Ds88MpPUbxd1kTaA@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/port/posix_sema.c6
-rw-r--r--src/backend/port/sysv_sema.c6
-rw-r--r--src/backend/storage/ipc/ipci.c31
-rw-r--r--src/backend/storage/ipc/shmem.c3
-rw-r--r--src/backend/storage/lmgr/proc.c4
-rw-r--r--src/include/storage/ipc.h2
-rw-r--r--src/include/storage/shmem.h1
7 files changed, 14 insertions, 39 deletions
diff --git a/src/backend/port/posix_sema.c b/src/backend/port/posix_sema.c
index 269c7460817..d7fb0c0c4da 100644
--- a/src/backend/port/posix_sema.c
+++ b/src/backend/port/posix_sema.c
@@ -215,12 +215,8 @@ PGReserveSemaphores(int maxSemas)
elog(PANIC, "out of memory");
#else
- /*
- * We must use ShmemAllocUnlocked(), since the spinlock protecting
- * ShmemAlloc() won't be ready yet.
- */
sharedSemas = (PGSemaphore)
- ShmemAllocUnlocked(PGSemaphoreShmemSize(maxSemas));
+ ShmemAlloc(PGSemaphoreShmemSize(maxSemas));
#endif
numSems = 0;
diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c
index 6ac83ea1a82..9faaeeefc79 100644
--- a/src/backend/port/sysv_sema.c
+++ b/src/backend/port/sysv_sema.c
@@ -343,12 +343,8 @@ PGReserveSemaphores(int maxSemas)
errmsg("could not stat data directory \"%s\": %m",
DataDir)));
- /*
- * We must use ShmemAllocUnlocked(), since the spinlock protecting
- * ShmemAlloc() won't be ready yet.
- */
sharedSemas = (PGSemaphore)
- ShmemAllocUnlocked(PGSemaphoreShmemSize(maxSemas));
+ ShmemAlloc(PGSemaphoreShmemSize(maxSemas));
numSharedSemas = 0;
maxSharedSemas = maxSemas;
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 19f9c774488..b23d0c19360 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -81,23 +81,12 @@ RequestAddinShmemSpace(Size size)
/*
* CalculateShmemSize
- * Calculates the amount of shared memory and number of semaphores needed.
- *
- * If num_semaphores is not NULL, it will be set to the number of semaphores
- * required.
+ * Calculates the amount of shared memory needed.
*/
Size
-CalculateShmemSize(int *num_semaphores)
+CalculateShmemSize(void)
{
Size size;
- int numSemas;
-
- /* Compute number of semaphores we'll need */
- numSemas = ProcGlobalSemas();
-
- /* Return the number of semaphores if requested by the caller */
- if (num_semaphores)
- *num_semaphores = numSemas;
/*
* Size of the Postgres shared-memory block is estimated via moderately-
@@ -109,7 +98,6 @@ CalculateShmemSize(int *num_semaphores)
* during the actual allocation phase.
*/
size = 100000;
- size = add_size(size, PGSemaphoreShmemSize(numSemas));
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
sizeof(ShmemIndexEnt)));
size = add_size(size, dsm_estimate_size());
@@ -204,12 +192,11 @@ CreateSharedMemoryAndSemaphores(void)
PGShmemHeader *shim;
PGShmemHeader *seghdr;
Size size;
- int numSemas;
Assert(!IsUnderPostmaster);
/* Compute the size of the shared-memory block */
- size = CalculateShmemSize(&numSemas);
+ size = CalculateShmemSize();
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
/*
@@ -227,13 +214,6 @@ CreateSharedMemoryAndSemaphores(void)
InitShmemAccess(seghdr);
/*
- * Create semaphores. (This is done here for historical reasons. We used
- * to support emulating spinlocks with semaphores, which required
- * initializing semaphores early.)
- */
- PGReserveSemaphores(numSemas);
-
- /*
* Set up shared memory allocation mechanism
*/
InitShmemAllocation();
@@ -363,12 +343,11 @@ InitializeShmemGUCs(void)
Size size_b;
Size size_mb;
Size hp_size;
- int num_semas;
/*
* Calculate the shared memory size and round up to the nearest megabyte.
*/
- size_b = CalculateShmemSize(&num_semas);
+ size_b = CalculateShmemSize();
size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
sprintf(buf, "%zu", size_mb);
SetConfigOption("shared_memory_size", buf,
@@ -388,6 +367,6 @@ InitializeShmemGUCs(void)
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
}
- sprintf(buf, "%d", num_semas);
+ sprintf(buf, "%d", ProcGlobalSemas());
SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
}
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index b3d0a10792d..0f18beb6ad4 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -76,6 +76,7 @@
#include "utils/builtins.h"
static void *ShmemAllocRaw(Size size, Size *allocated_size);
+static void *ShmemAllocUnlocked(Size size);
/* shared memory global variables */
@@ -234,7 +235,7 @@ ShmemAllocRaw(Size size, Size *allocated_size)
*
* We consider maxalign, rather than cachealign, sufficient here.
*/
-void *
+static void *
ShmemAllocUnlocked(Size size)
{
Size newStart;
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 26b201eadb8..1504fafe6d8 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -145,6 +145,7 @@ ProcGlobalShmemSize(void)
size = add_size(size, sizeof(PROC_HDR));
size = add_size(size, sizeof(slock_t));
+ size = add_size(size, PGSemaphoreShmemSize(ProcGlobalSemas()));
size = add_size(size, PGProcShmemSize());
size = add_size(size, FastPathLockShmemSize());
@@ -287,6 +288,9 @@ InitProcGlobal(void)
/* For asserts checking we did not overflow. */
fpEndPtr = fpPtr + requestSize;
+ /* Reserve space for semaphores. */
+ PGReserveSemaphores(ProcGlobalSemas());
+
for (i = 0; i < TotalProcs; i++)
{
PGPROC *proc = &procs[i];
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index 3baf418b3d1..2a8a8f0eabd 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -77,7 +77,7 @@ extern void check_on_shmem_exit_lists_are_empty(void);
/* ipci.c */
extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;
-extern Size CalculateShmemSize(int *num_semaphores);
+extern Size CalculateShmemSize(void);
extern void CreateSharedMemoryAndSemaphores(void);
#ifdef EXEC_BACKEND
extern void AttachSharedMemoryStructs(void);
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index cd683a9d2d9..70a5b8b172c 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -33,7 +33,6 @@ extern void InitShmemAccess(PGShmemHeader *seghdr);
extern void InitShmemAllocation(void);
extern void *ShmemAlloc(Size size);
extern void *ShmemAllocNoError(Size size);
-extern void *ShmemAllocUnlocked(Size size);
extern bool ShmemAddrIsValid(const void *addr);
extern void InitShmemIndex(void);
extern HTAB *ShmemInitHash(const char *name, int64 init_size, int64 max_size,