Move the shared memory size calculation to its own function

This change refactors the shared memory size calculation in
CreateSharedMemoryAndSemaphores() to its own function.  This is intended
for use in a future change related to the setup of huge pages and shared
memory with some GUCs, while useful on its own for extensions.

Author: Nathan Bossart
Discussion: https://postgr.es/m/F2772387-CE0F-46BF-B5F1-CC55516EB885@amazon.com
This commit is contained in:
Michael Paquier 2021-09-06 10:59:20 +09:00
parent 5fcb23c18f
commit 0bd305ee1d
2 changed files with 84 additions and 59 deletions

View File

@ -75,30 +75,19 @@ RequestAddinShmemSpace(Size size)
total_addin_request = add_size(total_addin_request, size); total_addin_request = add_size(total_addin_request, size);
} }
/* /*
* CreateSharedMemoryAndSemaphores * CalculateShmemSize
* Creates and initializes shared memory and semaphores. * Calculates the amount of shared memory and number of semaphores needed.
* *
* This is called by the postmaster or by a standalone backend. * If num_semaphores is not NULL, it will be set to the number of semaphores
* It is also called by a backend forked from the postmaster in the * required.
* EXEC_BACKEND case. In the latter case, the shared memory segment *
* already exists and has been physically attached to, but we have to * Note that this function freezes the additional shared memory request size
* initialize pointers in local memory that reference the shared structures, * from loadable modules.
* because we didn't inherit the correct pointer values from the postmaster
* as we do in the fork() scenario. The easiest way to do that is to run
* through the same code as before. (Note that the called routines mostly
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
* This is a bit code-wasteful and could be cleaned up.)
*/ */
void Size
CreateSharedMemoryAndSemaphores(void) CalculateShmemSize(int *num_semaphores)
{ {
PGShmemHeader *shim = NULL;
if (!IsUnderPostmaster)
{
PGShmemHeader *seghdr;
Size size; Size size;
int numSemas; int numSemas;
@ -106,14 +95,18 @@ CreateSharedMemoryAndSemaphores(void)
numSemas = ProcGlobalSemas(); numSemas = ProcGlobalSemas();
numSemas += SpinlockSemas(); numSemas += SpinlockSemas();
/* 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 * Size of the Postgres shared-memory block is estimated via moderately-
* moderately-accurate estimates for the big hogs, plus 100K for the * accurate estimates for the big hogs, plus 100K for the stuff that's too
* stuff that's too small to bother with estimating. * small to bother with estimating.
* *
* We take some care during this phase to ensure that the total size * We take some care to ensure that the total size request doesn't
* request doesn't overflow size_t. If this gets through, we don't * overflow size_t. If this gets through, we don't need to be so careful
* need to be so careful during the actual allocation phase. * during the actual allocation phase.
*/ */
size = 100000; size = 100000;
size = add_size(size, PGSemaphoreShmemSize(numSemas)); size = add_size(size, PGSemaphoreShmemSize(numSemas));
@ -161,6 +154,37 @@ CreateSharedMemoryAndSemaphores(void)
/* might as well round it off to a multiple of a typical page size */ /* might as well round it off to a multiple of a typical page size */
size = add_size(size, 8192 - (size % 8192)); size = add_size(size, 8192 - (size % 8192));
return size;
}
/*
* CreateSharedMemoryAndSemaphores
* Creates and initializes shared memory and semaphores.
*
* This is called by the postmaster or by a standalone backend.
* It is also called by a backend forked from the postmaster in the
* EXEC_BACKEND case. In the latter case, the shared memory segment
* already exists and has been physically attached to, but we have to
* initialize pointers in local memory that reference the shared structures,
* because we didn't inherit the correct pointer values from the postmaster
* as we do in the fork() scenario. The easiest way to do that is to run
* through the same code as before. (Note that the called routines mostly
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
* This is a bit code-wasteful and could be cleaned up.)
*/
void
CreateSharedMemoryAndSemaphores(void)
{
PGShmemHeader *shim = NULL;
if (!IsUnderPostmaster)
{
PGShmemHeader *seghdr;
Size size;
int numSemas;
/* Compute the size of the shared-memory block */
size = CalculateShmemSize(&numSemas);
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size); elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
/* /*

View File

@ -77,6 +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 void CreateSharedMemoryAndSemaphores(void); extern void CreateSharedMemoryAndSemaphores(void);
#endif /* IPC_H */ #endif /* IPC_H */