diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 7a7d204bf5ff6b39563eb17506324ed99c42bc6d..302dd80fcb482ff56f6632c1633a397e507ab71a 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.35 2004/09/28 20:46:27 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.36 2004/09/29 15:15:54 tgl Exp $
  *
  *
  * NOTES:
@@ -330,7 +330,7 @@ FreeSpaceShmemSize(void)
 	size = MAXALIGN(sizeof(FSMHeader));
 
 	/* hash table, including the FSMRelation objects */
-	size += hash_estimate_size(MaxFSMRelations, sizeof(FSMRelation));
+	size += hash_estimate_size(MaxFSMRelations + 1, sizeof(FSMRelation));
 
 	/* page-storage arena */
 	nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 8787ab2df8200a3c3efa8cc21ddbf31735a271bd..1a11508adf18edf17f8070d53cc3126b2651a92c 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.71 2004/08/29 05:06:48 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.72 2004/09/29 15:15:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -69,6 +69,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate,
 		size = hash_estimate_size(SHMEM_INDEX_SIZE, sizeof(ShmemIndexEnt));
 		size += BufferShmemSize();
 		size += LockShmemSize(maxBackends);
+		size += ProcGlobalShmemSize(maxBackends);
 		size += XLOGShmemSize();
 		size += CLOGShmemSize();
 		size += SUBTRANSShmemSize();
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 9699469e6d3e56c9fbf2dc4bf2823a1656f28a74..e53415cc5f862e073e9d38ef4af86bad26684efe 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.141 2004/09/28 20:46:32 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.142 2004/09/29 15:15:55 tgl Exp $
  *
  * NOTES
  *	  Outside modules can create a lock table and acquire/release
@@ -1689,15 +1689,17 @@ LockReassignCurrentOwner(void)
 }
 
 
+/*
+ * Estimate shared-memory space used for lock tables
+ */
 int
 LockShmemSize(int maxBackends)
 {
 	int			size = 0;
 	long		max_table_size = NLOCKENTS(maxBackends);
 
-	size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
-	size += maxBackends * MAXALIGN(sizeof(PGPROC));		/* each MyProc */
-	size += MAX_LOCK_METHODS * MAXALIGN(sizeof(LockMethodData));		/* each lock method */
+	/* lock method headers */
+	size += MAX_LOCK_METHODS * MAXALIGN(sizeof(LockMethodData));
 
 	/* lockHash table */
 	size += hash_estimate_size(max_table_size, sizeof(LOCK));
@@ -1706,6 +1708,9 @@ LockShmemSize(int maxBackends)
 	size += hash_estimate_size(max_table_size, sizeof(PROCLOCK));
 
 	/*
+	 * Note we count only one pair of hash tables, since the userlocks
+	 * table actually overlays the main one.
+	 *
 	 * Since the lockHash entry count above is only an estimate, add 10%
 	 * safety margin.
 	 */
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 8d05a293d2a7b95ed10cac944de301549b02b67f..ac04b5e80423493b073e6a5cca6022d7391dd9fc 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.153 2004/08/29 05:06:48 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.154 2004/09/29 15:15:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -89,6 +89,22 @@ static void DummyProcKill(int code, Datum arg);
 static bool CheckStatementTimeout(void);
 
 
+/*
+ * Report shared-memory space needed by InitProcGlobal.
+ */
+int
+ProcGlobalShmemSize(int maxBackends)
+{
+	int			size = 0;
+
+	size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
+	size += MAXALIGN(NUM_DUMMY_PROCS * sizeof(PGPROC));	/* DummyProcs */
+	size += MAXALIGN(maxBackends * sizeof(PGPROC));		/* MyProcs */
+	size += MAXALIGN(sizeof(slock_t)); /* ProcStructLock */
+
+	return size;
+}
+
 /*
  * Report number of semaphores needed by InitProcGlobal.
  */
@@ -134,7 +150,7 @@ InitProcGlobal(int maxBackends)
 	 * processes, too.	These do not get linked into the freeProcs list.
 	 */
 	DummyProcs = (PGPROC *)
-		ShmemInitStruct("DummyProcs", sizeof(PGPROC) * NUM_DUMMY_PROCS,
+		ShmemInitStruct("DummyProcs", NUM_DUMMY_PROCS * sizeof(PGPROC),
 						&foundDummy);
 
 	if (foundProcGlobal || foundDummy)
@@ -147,6 +163,7 @@ InitProcGlobal(int maxBackends)
 		/*
 		 * We're the first - initialize.
 		 */
+		PGPROC	   *procs;
 		int			i;
 
 		ProcGlobal->freeProcs = INVALID_OFFSET;
@@ -155,22 +172,20 @@ InitProcGlobal(int maxBackends)
 		 * Pre-create the PGPROC structures and create a semaphore for
 		 * each.
 		 */
+		procs = (PGPROC *) ShmemAlloc(maxBackends * sizeof(PGPROC));
+		if (!procs)
+			ereport(FATAL,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("out of shared memory")));
+		MemSet(procs, 0, maxBackends * sizeof(PGPROC));
 		for (i = 0; i < maxBackends; i++)
 		{
-			PGPROC	   *proc;
-
-			proc = (PGPROC *) ShmemAlloc(sizeof(PGPROC));
-			if (!proc)
-				ereport(FATAL,
-						(errcode(ERRCODE_OUT_OF_MEMORY),
-						 errmsg("out of shared memory")));
-			MemSet(proc, 0, sizeof(PGPROC));
-			PGSemaphoreCreate(&proc->sem);
-			proc->links.next = ProcGlobal->freeProcs;
-			ProcGlobal->freeProcs = MAKE_OFFSET(proc);
+			PGSemaphoreCreate(&(procs[i].sem));
+			procs[i].links.next = ProcGlobal->freeProcs;
+			ProcGlobal->freeProcs = MAKE_OFFSET(&procs[i]);
 		}
 
-		MemSet(DummyProcs, 0, sizeof(PGPROC) * NUM_DUMMY_PROCS);
+		MemSet(DummyProcs, 0, NUM_DUMMY_PROCS * sizeof(PGPROC));
 		for (i = 0; i < NUM_DUMMY_PROCS; i++)
 		{
 			DummyProcs[i].pid = 0;		/* marks dummy proc as not in use */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 4cff8d2432080208b27f799a8c210e097a1b9476..7457a6eabac6fc0aa61e3fe8704efcfe7f838400 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.75 2004/08/29 05:06:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.76 2004/09/29 15:15:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,6 +122,7 @@ extern int	StatementTimeout;
  * Function Prototypes
  */
 extern int	ProcGlobalSemas(int maxBackends);
+extern int	ProcGlobalShmemSize(int maxBackends);
 extern void InitProcGlobal(int maxBackends);
 extern void InitProcess(void);
 extern void InitDummyProcess(int proctype);