]> granicus.if.org Git - postgresql/commitdiff
Code cleanup for InitProcGlobal.
authorRobert Haas <rhaas@postgresql.org>
Sun, 12 Jun 2011 04:07:04 +0000 (00:07 -0400)
committerRobert Haas <rhaas@postgresql.org>
Sun, 12 Jun 2011 04:07:04 +0000 (00:07 -0400)
The old code creates three separate arrays when only one is needed,
using two different shmem allocation functions for no obvious reason.
It also strangely splits up the initialization of AuxilaryProcs
between the top and bottom of the function to no evident purpose.

Review by Tom Lane.

src/backend/storage/lmgr/proc.c

index ee0331605086a7ac84e7473cafbad0d2ff3ddb1b..c7b1e45bb815d95aa0095cca7e559e2004e8b103 100644 (file)
@@ -160,75 +160,68 @@ InitProcGlobal(void)
        PGPROC     *procs;
        int                     i;
        bool            found;
+       uint32          TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS;
 
        /* Create the ProcGlobal shared structure */
        ProcGlobal = (PROC_HDR *)
                ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
        Assert(!found);
 
-       /*
-        * Create the PGPROC structures for auxiliary (bgwriter) processes, too.
-        * These do not get linked into the freeProcs list.
-        */
-       AuxiliaryProcs = (PGPROC *)
-               ShmemInitStruct("AuxiliaryProcs", NUM_AUXILIARY_PROCS * sizeof(PGPROC),
-                                               &found);
-       Assert(!found);
-
        /*
         * Initialize the data structures.
         */
+       ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
        ProcGlobal->freeProcs = NULL;
        ProcGlobal->autovacFreeProcs = NULL;
 
-       ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
-
-       /*
-        * Pre-create the PGPROC structures and create a semaphore for each.
-        */
-       procs = (PGPROC *) ShmemAlloc((MaxConnections) * sizeof(PGPROC));
-       if (!procs)
-               ereport(FATAL,
-                               (errcode(ERRCODE_OUT_OF_MEMORY),
-                                errmsg("out of shared memory")));
-       MemSet(procs, 0, MaxConnections * sizeof(PGPROC));
-       for (i = 0; i < MaxConnections; i++)
-       {
-               PGSemaphoreCreate(&(procs[i].sem));
-               procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
-               ProcGlobal->freeProcs = &procs[i];
-               InitSharedLatch(&procs[i].waitLatch);
-       }
-
        /*
-        * Likewise for the PGPROCs reserved for autovacuum.
+        * Create and initialize all the PGPROC structures we'll need (except for
+        * those used for 2PC, which are embedded within a GlobalTransactionData
+        * struct).
         *
-        * Note: the "+1" here accounts for the autovac launcher
+        * There are three separate consumers of PGPROC structures: (1) normal
+        * backends, (2) autovacuum workers and the autovacuum launcher, and (3)
+        * auxiliary processes.  Each PGPROC structure is dedicated to exactly
+        * one of these purposes, and they do not move between groups.
         */
-       procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers + 1) * sizeof(PGPROC));
+       procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
        if (!procs)
                ereport(FATAL,
                                (errcode(ERRCODE_OUT_OF_MEMORY),
                                 errmsg("out of shared memory")));
-       MemSet(procs, 0, (autovacuum_max_workers + 1) * sizeof(PGPROC));
-       for (i = 0; i < autovacuum_max_workers + 1; i++)
+       MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
+       for (i = 0; i < TotalProcs; i++)
        {
+               /* Common initialization for all PGPROCs, regardless of type. */
                PGSemaphoreCreate(&(procs[i].sem));
-               procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
-               ProcGlobal->autovacFreeProcs = &procs[i];
                InitSharedLatch(&procs[i].waitLatch);
+
+               /*
+                * Newly created PGPROCs for normal backends or for autovacuum must
+                * be queued up on the appropriate free list.  Because there can only
+                * ever be a small, fixed number of auxiliary processes, no free
+                * list is used in that case; InitAuxiliaryProcess() instead uses a
+                * linear search.
+                */
+               if (i < MaxConnections)
+               {
+                       /* PGPROC for normal backend, add to freeProcs list */
+                       procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
+                       ProcGlobal->freeProcs = &procs[i];
+               }
+               else if (i < MaxBackends)
+               {
+                       /* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
+                       procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
+                       ProcGlobal->autovacFreeProcs = &procs[i];
+               }
        }
 
        /*
-        * And auxiliary procs.
+        * Save a pointer to the block of PGPROC structures reserved for
+        * auxiliary proceses.
         */
-       MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
-       for (i = 0; i < NUM_AUXILIARY_PROCS; i++)
-       {
-               AuxiliaryProcs[i].pid = 0;              /* marks auxiliary proc as not in use */
-               PGSemaphoreCreate(&(AuxiliaryProcs[i].sem));
-               InitSharedLatch(&procs[i].waitLatch);
-       }
+       AuxiliaryProcs = &procs[MaxBackends];
 
        /* Create ProcStructLock spinlock, too */
        ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));