Refactor CreateSharedMemoryAndSemaphores
authorHeikki Linnakangas <[email protected]>
Sun, 3 Dec 2023 14:09:42 +0000 (16:09 +0200)
committerHeikki Linnakangas <[email protected]>
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 */