mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
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
This commit is contained in:
@@ -215,12 +215,8 @@ PGReserveSemaphores(int maxSemas)
|
|||||||
elog(PANIC, "out of memory");
|
elog(PANIC, "out of memory");
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*
|
|
||||||
* We must use ShmemAllocUnlocked(), since the spinlock protecting
|
|
||||||
* ShmemAlloc() won't be ready yet.
|
|
||||||
*/
|
|
||||||
sharedSemas = (PGSemaphore)
|
sharedSemas = (PGSemaphore)
|
||||||
ShmemAllocUnlocked(PGSemaphoreShmemSize(maxSemas));
|
ShmemAlloc(PGSemaphoreShmemSize(maxSemas));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
numSems = 0;
|
numSems = 0;
|
||||||
|
|||||||
@@ -343,12 +343,8 @@ PGReserveSemaphores(int maxSemas)
|
|||||||
errmsg("could not stat data directory \"%s\": %m",
|
errmsg("could not stat data directory \"%s\": %m",
|
||||||
DataDir)));
|
DataDir)));
|
||||||
|
|
||||||
/*
|
|
||||||
* We must use ShmemAllocUnlocked(), since the spinlock protecting
|
|
||||||
* ShmemAlloc() won't be ready yet.
|
|
||||||
*/
|
|
||||||
sharedSemas = (PGSemaphore)
|
sharedSemas = (PGSemaphore)
|
||||||
ShmemAllocUnlocked(PGSemaphoreShmemSize(maxSemas));
|
ShmemAlloc(PGSemaphoreShmemSize(maxSemas));
|
||||||
numSharedSemas = 0;
|
numSharedSemas = 0;
|
||||||
maxSharedSemas = maxSemas;
|
maxSharedSemas = maxSemas;
|
||||||
|
|
||||||
|
|||||||
@@ -81,23 +81,12 @@ RequestAddinShmemSpace(Size size)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* CalculateShmemSize
|
* CalculateShmemSize
|
||||||
* Calculates the amount of shared memory and number of semaphores needed.
|
* Calculates the amount of shared memory needed.
|
||||||
*
|
|
||||||
* If num_semaphores is not NULL, it will be set to the number of semaphores
|
|
||||||
* required.
|
|
||||||
*/
|
*/
|
||||||
Size
|
Size
|
||||||
CalculateShmemSize(int *num_semaphores)
|
CalculateShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size;
|
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-
|
* Size of the Postgres shared-memory block is estimated via moderately-
|
||||||
@@ -109,7 +98,6 @@ CalculateShmemSize(int *num_semaphores)
|
|||||||
* during the actual allocation phase.
|
* during the actual allocation phase.
|
||||||
*/
|
*/
|
||||||
size = 100000;
|
size = 100000;
|
||||||
size = add_size(size, PGSemaphoreShmemSize(numSemas));
|
|
||||||
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
|
size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
|
||||||
sizeof(ShmemIndexEnt)));
|
sizeof(ShmemIndexEnt)));
|
||||||
size = add_size(size, dsm_estimate_size());
|
size = add_size(size, dsm_estimate_size());
|
||||||
@@ -204,12 +192,11 @@ CreateSharedMemoryAndSemaphores(void)
|
|||||||
PGShmemHeader *shim;
|
PGShmemHeader *shim;
|
||||||
PGShmemHeader *seghdr;
|
PGShmemHeader *seghdr;
|
||||||
Size size;
|
Size size;
|
||||||
int numSemas;
|
|
||||||
|
|
||||||
Assert(!IsUnderPostmaster);
|
Assert(!IsUnderPostmaster);
|
||||||
|
|
||||||
/* Compute the size of the shared-memory block */
|
/* Compute the size of the shared-memory block */
|
||||||
size = CalculateShmemSize(&numSemas);
|
size = CalculateShmemSize();
|
||||||
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
|
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -226,13 +213,6 @@ CreateSharedMemoryAndSemaphores(void)
|
|||||||
|
|
||||||
InitShmemAccess(seghdr);
|
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
|
* Set up shared memory allocation mechanism
|
||||||
*/
|
*/
|
||||||
@@ -363,12 +343,11 @@ InitializeShmemGUCs(void)
|
|||||||
Size size_b;
|
Size size_b;
|
||||||
Size size_mb;
|
Size size_mb;
|
||||||
Size hp_size;
|
Size hp_size;
|
||||||
int num_semas;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the shared memory size and round up to the nearest megabyte.
|
* 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);
|
size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
|
||||||
sprintf(buf, "%zu", size_mb);
|
sprintf(buf, "%zu", size_mb);
|
||||||
SetConfigOption("shared_memory_size", buf,
|
SetConfigOption("shared_memory_size", buf,
|
||||||
@@ -388,6 +367,6 @@ InitializeShmemGUCs(void)
|
|||||||
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
|
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);
|
SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@
|
|||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
static void *ShmemAllocRaw(Size size, Size *allocated_size);
|
static void *ShmemAllocRaw(Size size, Size *allocated_size);
|
||||||
|
static void *ShmemAllocUnlocked(Size size);
|
||||||
|
|
||||||
/* shared memory global variables */
|
/* shared memory global variables */
|
||||||
|
|
||||||
@@ -234,7 +235,7 @@ ShmemAllocRaw(Size size, Size *allocated_size)
|
|||||||
*
|
*
|
||||||
* We consider maxalign, rather than cachealign, sufficient here.
|
* We consider maxalign, rather than cachealign, sufficient here.
|
||||||
*/
|
*/
|
||||||
void *
|
static void *
|
||||||
ShmemAllocUnlocked(Size size)
|
ShmemAllocUnlocked(Size size)
|
||||||
{
|
{
|
||||||
Size newStart;
|
Size newStart;
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ ProcGlobalShmemSize(void)
|
|||||||
size = add_size(size, sizeof(PROC_HDR));
|
size = add_size(size, sizeof(PROC_HDR));
|
||||||
size = add_size(size, sizeof(slock_t));
|
size = add_size(size, sizeof(slock_t));
|
||||||
|
|
||||||
|
size = add_size(size, PGSemaphoreShmemSize(ProcGlobalSemas()));
|
||||||
size = add_size(size, PGProcShmemSize());
|
size = add_size(size, PGProcShmemSize());
|
||||||
size = add_size(size, FastPathLockShmemSize());
|
size = add_size(size, FastPathLockShmemSize());
|
||||||
|
|
||||||
@@ -287,6 +288,9 @@ InitProcGlobal(void)
|
|||||||
/* For asserts checking we did not overflow. */
|
/* For asserts checking we did not overflow. */
|
||||||
fpEndPtr = fpPtr + requestSize;
|
fpEndPtr = fpPtr + requestSize;
|
||||||
|
|
||||||
|
/* Reserve space for semaphores. */
|
||||||
|
PGReserveSemaphores(ProcGlobalSemas());
|
||||||
|
|
||||||
for (i = 0; i < TotalProcs; i++)
|
for (i = 0; i < TotalProcs; i++)
|
||||||
{
|
{
|
||||||
PGPROC *proc = &procs[i];
|
PGPROC *proc = &procs[i];
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ extern void check_on_shmem_exit_lists_are_empty(void);
|
|||||||
/* ipci.c */
|
/* ipci.c */
|
||||||
extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;
|
extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;
|
||||||
|
|
||||||
extern Size CalculateShmemSize(int *num_semaphores);
|
extern Size CalculateShmemSize(void);
|
||||||
extern void CreateSharedMemoryAndSemaphores(void);
|
extern void CreateSharedMemoryAndSemaphores(void);
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
extern void AttachSharedMemoryStructs(void);
|
extern void AttachSharedMemoryStructs(void);
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ extern void InitShmemAccess(PGShmemHeader *seghdr);
|
|||||||
extern void InitShmemAllocation(void);
|
extern void InitShmemAllocation(void);
|
||||||
extern void *ShmemAlloc(Size size);
|
extern void *ShmemAlloc(Size size);
|
||||||
extern void *ShmemAllocNoError(Size size);
|
extern void *ShmemAllocNoError(Size size);
|
||||||
extern void *ShmemAllocUnlocked(Size size);
|
|
||||||
extern bool ShmemAddrIsValid(const void *addr);
|
extern bool ShmemAddrIsValid(const void *addr);
|
||||||
extern void InitShmemIndex(void);
|
extern void InitShmemIndex(void);
|
||||||
extern HTAB *ShmemInitHash(const char *name, int64 init_size, int64 max_size,
|
extern HTAB *ShmemInitHash(const char *name, int64 init_size, int64 max_size,
|
||||||
|
|||||||
Reference in New Issue
Block a user