]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Refactor CreateSharedMemoryAndSemaphores
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 3 Dec 2023 14:09:42 +0000 (16:09 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 3 Dec 2023 14:09:42 +0000 (16:09 +0200)
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

src/backend/postmaster/postmaster.c
src/backend/replication/walreceiver.c
src/backend/storage/ipc/ipci.c
src/backend/storage/lmgr/proc.c
src/include/storage/ipc.h

index ccc12f91a1675d0c0923515caa22bea1dbac0da2..39fdcff3e24cd66946050c96e050c02777d0750c 100644 (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);
index 2398167f495aa06e8712ce8ea606874fd4c9ec15..26ded928a716f018b8770758263811efa345d523 100644 (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);
 
        /*
index a3d8eacb8dcc822aa23e0e0d2b96188da1a214cf..2225a4a6e6049d090041c95f7b0b7ea1da7b7b7c 100644 (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();
 }
 
 /*
index 01f7019b10c7af1906e0d410c8569d42816e7dd0..6648c6e5e7e2223fdf8c43e5b56a5a024ba5b2ff 100644 (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)
index 888c08b30675e59d86516774cae44fe4884788ec..e282dcad962472d68785bc27cbf1a4f9435c63c2 100644 (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 */