@@ -160,75 +160,68 @@ InitProcGlobal(void)
160160PGPROC * procs ;
161161int i ;
162162bool found ;
163+ uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS ;
163164
164165/* Create the ProcGlobal shared structure */
165166ProcGlobal = (PROC_HDR * )
166167ShmemInitStruct ("Proc Header" ,sizeof (PROC_HDR ),& found );
167168Assert (!found );
168169
169- /*
170- * Create the PGPROC structures for auxiliary (bgwriter) processes, too.
171- * These do not get linked into the freeProcs list.
172- */
173- AuxiliaryProcs = (PGPROC * )
174- ShmemInitStruct ("AuxiliaryProcs" ,NUM_AUXILIARY_PROCS * sizeof (PGPROC ),
175- & found );
176- Assert (!found );
177-
178170/*
179171 * Initialize the data structures.
180172 */
173+ ProcGlobal -> spins_per_delay = DEFAULT_SPINS_PER_DELAY ;
181174ProcGlobal -> freeProcs = NULL ;
182175ProcGlobal -> autovacFreeProcs = NULL ;
183176
184- ProcGlobal -> spins_per_delay = DEFAULT_SPINS_PER_DELAY ;
185-
186- /*
187- * Pre-create the PGPROC structures and create a semaphore for each.
188- */
189- procs = (PGPROC * )ShmemAlloc ((MaxConnections )* sizeof (PGPROC ));
190- if (!procs )
191- ereport (FATAL ,
192- (errcode (ERRCODE_OUT_OF_MEMORY ),
193- errmsg ("out of shared memory" )));
194- MemSet (procs ,0 ,MaxConnections * sizeof (PGPROC ));
195- for (i = 0 ;i < MaxConnections ;i ++ )
196- {
197- PGSemaphoreCreate (& (procs [i ].sem ));
198- procs [i ].links .next = (SHM_QUEUE * )ProcGlobal -> freeProcs ;
199- ProcGlobal -> freeProcs = & procs [i ];
200- InitSharedLatch (& procs [i ].waitLatch );
201- }
202-
203177/*
204- * Likewise for the PGPROCs reserved for autovacuum.
178+ * Create and initialize all the PGPROC structures we'll need (except for
179+ * those used for 2PC, which are embedded within a GlobalTransactionData
180+ * struct).
205181 *
206- * Note: the "+1" here accounts for the autovac launcher
182+ * There are three separate consumers of PGPROC structures: (1) normal
183+ * backends, (2) autovacuum workers and the autovacuum launcher, and (3)
184+ * auxiliary processes. Each PGPROC structure is dedicated to exactly
185+ * one of these purposes, and they do not move between groups.
207186 */
208- procs = (PGPROC * )ShmemAlloc (( autovacuum_max_workers + 1 ) * sizeof (PGPROC ));
187+ procs = (PGPROC * )ShmemAlloc (TotalProcs * sizeof (PGPROC ));
209188if (!procs )
210189ereport (FATAL ,
211190(errcode (ERRCODE_OUT_OF_MEMORY ),
212191errmsg ("out of shared memory" )));
213- MemSet (procs ,0 ,( autovacuum_max_workers + 1 ) * sizeof (PGPROC ));
214- for (i = 0 ;i < autovacuum_max_workers + 1 ;i ++ )
192+ MemSet (procs ,0 ,TotalProcs * sizeof (PGPROC ));
193+ for (i = 0 ;i < TotalProcs ;i ++ )
215194{
195+ /* Common initialization for all PGPROCs, regardless of type. */
216196PGSemaphoreCreate (& (procs [i ].sem ));
217- procs [i ].links .next = (SHM_QUEUE * )ProcGlobal -> autovacFreeProcs ;
218- ProcGlobal -> autovacFreeProcs = & procs [i ];
219197InitSharedLatch (& procs [i ].waitLatch );
198+
199+ /*
200+ * Newly created PGPROCs for normal backends or for autovacuum must
201+ * be queued up on the appropriate free list. Because there can only
202+ * ever be a small, fixed number of auxiliary processes, no free
203+ * list is used in that case; InitAuxiliaryProcess() instead uses a
204+ * linear search.
205+ */
206+ if (i < MaxConnections )
207+ {
208+ /* PGPROC for normal backend, add to freeProcs list */
209+ procs [i ].links .next = (SHM_QUEUE * )ProcGlobal -> freeProcs ;
210+ ProcGlobal -> freeProcs = & procs [i ];
211+ }
212+ else if (i < MaxBackends )
213+ {
214+ /* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
215+ procs [i ].links .next = (SHM_QUEUE * )ProcGlobal -> autovacFreeProcs ;
216+ ProcGlobal -> autovacFreeProcs = & procs [i ];
217+ }
220218}
221219
222220/*
223- * And auxiliary procs.
221+ * Save a pointer to the block of PGPROC structures reserved for
222+ * auxiliary proceses.
224223 */
225- MemSet (AuxiliaryProcs ,0 ,NUM_AUXILIARY_PROCS * sizeof (PGPROC ));
226- for (i = 0 ;i < NUM_AUXILIARY_PROCS ;i ++ )
227- {
228- AuxiliaryProcs [i ].pid = 0 ;/* marks auxiliary proc as not in use */
229- PGSemaphoreCreate (& (AuxiliaryProcs [i ].sem ));
230- InitSharedLatch (& procs [i ].waitLatch );
231- }
224+ AuxiliaryProcs = & procs [MaxBackends ];
232225
233226/* Create ProcStructLock spinlock, too */
234227ProcStructLock = (slock_t * )ShmemAlloc (sizeof (slock_t ));