Refactor CreateSharedMemoryAndSemaphores

For clarity, have separate functions for *creating* the shared memory
and semaphores at postmaster or single-user backend startup, and
for *attaching* to existing shared memory structures in EXEC_BACKEND
case. CreateSharedMemoryAndSemaphores() is now called only at
postmaster startup, and a new AttachSharedMemoryStructs() function is
called at backend startup in EXEC_BACKEND mode.

Reviewed-by: Tristan Partin, Andres Freund
Discussion: https://www.postgresql.org/message-id/7a59b073-5b5b-151e-7ed3-8b01ff7ce9ef@iki.fi
This commit is contained in:
Heikki Linnakangas 2023-12-03 16:09:42 +02:00
parent b19890d49d
commit 69d903367c
5 changed files with 117 additions and 89 deletions

View File

@ -4917,11 +4917,11 @@ SubPostmasterMain(int argc, char *argv[])
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
/* Need a PGPROC to run AttachSharedMemoryStructs */
InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores();
AttachSharedMemoryStructs();
/* And run the backend */
BackendRun(&port); /* does not return */
@ -4935,11 +4935,11 @@ SubPostmasterMain(int argc, char *argv[])
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
/* Need a PGPROC to run AttachSharedMemoryStructs */
InitAuxiliaryProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores();
AttachSharedMemoryStructs();
auxtype = atoi(argv[3]);
AuxiliaryProcessMain(auxtype); /* does not return */
@ -4949,11 +4949,11 @@ SubPostmasterMain(int argc, char *argv[])
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
/* Need a PGPROC to run AttachSharedMemoryStructs */
InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores();
AttachSharedMemoryStructs();
AutoVacLauncherMain(argc - 2, argv + 2); /* does not return */
}
@ -4962,11 +4962,11 @@ SubPostmasterMain(int argc, char *argv[])
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
/* Need a PGPROC to run AttachSharedMemoryStructs */
InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores();
AttachSharedMemoryStructs();
AutoVacWorkerMain(argc - 2, argv + 2); /* does not return */
}
@ -4980,11 +4980,11 @@ SubPostmasterMain(int argc, char *argv[])
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* Need a PGPROC to run CreateSharedMemoryAndSemaphores */
/* Need a PGPROC to run AttachSharedMemoryStructs */
InitProcess();
/* Attach process to shared data structures */
CreateSharedMemoryAndSemaphores();
AttachSharedMemoryStructs();
/* Fetch MyBgworkerEntry from shared memory */
shmem_slot = atoi(argv[1] + 15);

View File

@ -193,7 +193,7 @@ WalReceiverMain(void)
TimeLineID startpointTLI;
TimeLineID primaryTLI;
bool first_stream;
WalRcvData *walrcv = WalRcv;
WalRcvData *walrcv;
TimestampTz now;
char *err;
char *sender_host = NULL;
@ -203,6 +203,7 @@ WalReceiverMain(void)
* WalRcv should be set up already (if we are a backend, we inherit this
* by fork() or EXEC_BACKEND mechanism from the postmaster).
*/
walrcv = WalRcv;
Assert(walrcv != NULL);
/*

View File

@ -58,6 +58,8 @@ shmem_startup_hook_type shmem_startup_hook = NULL;
static Size total_addin_request = 0;
static void CreateOrAttachShmemStructs(void);
/*
* RequestAddinShmemSpace
* Request that extra shmem space be allocated for use by
@ -156,9 +158,106 @@ CalculateShmemSize(int *num_semaphores)
return size;
}
#ifdef EXEC_BACKEND
/*
* AttachSharedMemoryStructs
* Initialize a postmaster child process's access to shared memory
* structures.
*
* In !EXEC_BACKEND mode, we inherit everything through the fork, and this
* isn't needed.
*/
void
AttachSharedMemoryStructs(void)
{
/* InitProcess must've been called already */
Assert(MyProc != NULL);
Assert(IsUnderPostmaster);
CreateOrAttachShmemStructs();
/*
* Now give loadable modules a chance to set up their shmem allocations
*/
if (shmem_startup_hook)
shmem_startup_hook();
}
#endif
/*
* CreateSharedMemoryAndSemaphores
* Creates and initializes shared memory and semaphores.
*/
void
CreateSharedMemoryAndSemaphores(void)
{
PGShmemHeader *shim;
PGShmemHeader *seghdr;
Size size;
int numSemas;
Assert(!IsUnderPostmaster);
/* Compute the size of the shared-memory block */
size = CalculateShmemSize(&numSemas);
elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
/*
* Create the shmem segment
*/
seghdr = PGSharedMemoryCreate(size, &shim);
/*
* Make sure that huge pages are never reported as "unknown" while the
* server is running.
*/
Assert(strcmp("unknown",
GetConfigOption("huge_pages_status", false, false)) != 0);
InitShmemAccess(seghdr);
/*
* Create semaphores
*/
PGReserveSemaphores(numSemas);
/*
* If spinlocks are disabled, initialize emulation layer (which depends on
* semaphores, so the order is important here).
*/
#ifndef HAVE_SPINLOCKS
SpinlockSemaInit();
#endif
/*
* Set up shared memory allocation mechanism
*/
InitShmemAllocation();
/* Initialize subsystems */
CreateOrAttachShmemStructs();
#ifdef EXEC_BACKEND
/*
* Alloc the win32 shared backend array
*/
ShmemBackendArrayAllocation();
#endif
/* Initialize dynamic shared memory facilities. */
dsm_postmaster_startup(shim);
/*
* Now give loadable modules a chance to set up their shmem allocations
*/
if (shmem_startup_hook)
shmem_startup_hook();
}
/*
* Initialize various subsystems, setting up their data structures in
* shared memory.
*
* This is called by the postmaster or by a standalone backend.
* It is also called by a backend forked from the postmaster in the
@ -171,65 +270,9 @@ CalculateShmemSize(int *num_semaphores)
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
* This is a bit code-wasteful and could be cleaned up.)
*/
void
CreateSharedMemoryAndSemaphores(void)
static void
CreateOrAttachShmemStructs(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);
/*
* Create the shmem segment
*/
seghdr = PGSharedMemoryCreate(size, &shim);
/*
* Make sure that huge pages are never reported as "unknown" while the
* server is running.
*/
Assert(strcmp("unknown",
GetConfigOption("huge_pages_status", false, false)) != 0);
InitShmemAccess(seghdr);
/*
* Create semaphores
*/
PGReserveSemaphores(numSemas);
/*
* If spinlocks are disabled, initialize emulation layer (which
* depends on semaphores, so the order is important here).
*/
#ifndef HAVE_SPINLOCKS
SpinlockSemaInit();
#endif
}
else
{
/*
* We are reattaching to an existing shared memory segment. This
* should only be reached in the EXEC_BACKEND case.
*/
#ifndef EXEC_BACKEND
elog(PANIC, "should be attached to shared memory already");
#endif
}
/*
* Set up shared memory allocation mechanism
*/
if (!IsUnderPostmaster)
InitShmemAllocation();
/*
* Now initialize LWLocks, which do shared memory allocation and are
* needed for InitShmemIndex.
@ -302,25 +345,6 @@ CreateSharedMemoryAndSemaphores(void)
AsyncShmemInit();
StatsShmemInit();
WaitEventExtensionShmemInit();
#ifdef EXEC_BACKEND
/*
* Alloc the win32 shared backend array
*/
if (!IsUnderPostmaster)
ShmemBackendArrayAllocation();
#endif
/* Initialize dynamic shared memory facilities. */
if (!IsUnderPostmaster)
dsm_postmaster_startup(shim);
/*
* Now give loadable modules a chance to set up their shmem allocations
*/
if (shmem_startup_hook)
shmem_startup_hook();
}
/*

View File

@ -468,7 +468,7 @@ InitProcess(void)
*
* This is separate from InitProcess because we can't acquire LWLocks until
* we've created a PGPROC, but in the EXEC_BACKEND case ProcArrayAdd won't
* work until after we've done CreateSharedMemoryAndSemaphores.
* work until after we've done AttachSharedMemoryStructs.
*/
void
InitProcessPhase2(void)

View File

@ -79,6 +79,9 @@ extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;
extern Size CalculateShmemSize(int *num_semaphores);
extern void CreateSharedMemoryAndSemaphores(void);
#ifdef EXEC_BACKEND
extern void AttachSharedMemoryStructs(void);
#endif
extern void InitializeShmemGUCs(void);
#endif /* IPC_H */