1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-09 13:09:39 +03:00

Get rid of PID entries in shmem hash table; there is no longer any need

for them, and making them just wastes time during backend startup/shutdown.
Also, remove compile-time MAXBACKENDS limit per long-ago proposal.
You can now set MaxBackends as high as your kernel can stand without
any reconfiguration/recompilation.
This commit is contained in:
Tom Lane
2001-09-07 00:27:30 +00:00
parent 0059c4216c
commit 863aceb54f
12 changed files with 213 additions and 316 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.57 2001/03/22 03:59:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.58 2001/09/07 00:27:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -259,92 +259,6 @@ ShmemInitHash(char *name, /* table string name for shmem index */
return hash_create(init_size, infoP, hash_flags);
}
/*
* ShmemPIDLookup -- lookup process data structure using process id
*
* Returns: TRUE if no error. locationPtr is initialized if PID is
* found in the shmem index.
*
* NOTES:
* only information about success or failure is the value of
* locationPtr.
*/
bool
ShmemPIDLookup(int pid, SHMEM_OFFSET *locationPtr)
{
ShmemIndexEnt *result,
item;
bool found;
Assert(ShmemIndex);
MemSet(item.key, 0, SHMEM_INDEX_KEYSIZE);
sprintf(item.key, "PID %d", pid);
SpinAcquire(ShmemIndexLock);
result = (ShmemIndexEnt *)
hash_search(ShmemIndex, (char *) &item, HASH_ENTER, &found);
if (!result)
{
SpinRelease(ShmemIndexLock);
elog(ERROR, "ShmemInitPID: ShmemIndex corrupted");
return FALSE;
}
if (found)
*locationPtr = result->location;
else
result->location = *locationPtr;
SpinRelease(ShmemIndexLock);
return TRUE;
}
/*
* ShmemPIDDestroy -- destroy shmem index entry for process
* using process id
*
* Returns: offset of the process struct in shared memory or
* INVALID_OFFSET if not found.
*
* Side Effect: removes the entry from the shmem index
*/
SHMEM_OFFSET
ShmemPIDDestroy(int pid)
{
ShmemIndexEnt *result,
item;
bool found;
SHMEM_OFFSET location = 0;
Assert(ShmemIndex);
MemSet(item.key, 0, SHMEM_INDEX_KEYSIZE);
sprintf(item.key, "PID %d", pid);
SpinAcquire(ShmemIndexLock);
result = (ShmemIndexEnt *)
hash_search(ShmemIndex, (char *) &item, HASH_REMOVE, &found);
if (found)
location = result->location;
SpinRelease(ShmemIndexLock);
if (!result)
{
elog(ERROR, "ShmemPIDDestroy: PID table corrupted");
return INVALID_OFFSET;
}
if (found)
return location;
else
return INVALID_OFFSET;
}
/*
* ShmemInitStruct -- Create/attach to a structure in shared
* memory.
@@ -373,7 +287,6 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
if (!ShmemIndex)
{
/*
* If the shmem index doesn't exist, we are bootstrapping: we must
* be trying to init the shmem index itself.
@@ -400,7 +313,6 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
if (*foundPtr)
{
/*
* Structure is in the shmem index so someone else has allocated
* it already. The size better be the same as the size we are

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.93 2001/08/29 19:14:39 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.94 2001/09/07 00:27:29 tgl Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
@@ -1430,7 +1430,6 @@ LockShmemSize(int maxBackends)
void
DumpLocks(void)
{
SHMEM_OFFSET location;
PROC *proc;
SHM_QUEUE *procHolders;
HOLDER *holder;
@@ -1438,12 +1437,10 @@ DumpLocks(void)
int lockmethod = DEFAULT_LOCKMETHOD;
LOCKMETHODTABLE *lockMethodTable;
ShmemPIDLookup(MyProcPid, &location);
if (location == INVALID_OFFSET)
return;
proc = (PROC *) MAKE_PTR(location);
if (proc != MyProc)
proc = MyProc;
if (proc == NULL)
return;
procHolders = &proc->procHolders;
Assert(lockmethod < NumLockMethods);
@@ -1477,22 +1474,16 @@ DumpLocks(void)
void
DumpAllLocks(void)
{
SHMEM_OFFSET location;
PROC *proc;
HOLDER *holder = NULL;
LOCK *lock;
int pid;
int lockmethod = DEFAULT_LOCKMETHOD;
LOCKMETHODTABLE *lockMethodTable;
HTAB *holderTable;
HASH_SEQ_STATUS status;
pid = getpid();
ShmemPIDLookup(pid, &location);
if (location == INVALID_OFFSET)
return;
proc = (PROC *) MAKE_PTR(location);
if (proc != MyProc)
proc = MyProc;
if (proc == NULL)
return;
Assert(lockmethod < NumLockMethods);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.106 2001/09/04 21:42:17 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.107 2001/09/07 00:27:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -124,11 +124,18 @@ static void ProcFreeAllSemaphores(void);
void
InitProcGlobal(int maxBackends)
{
int semMapEntries;
Size procGlobalSize;
bool found = false;
/* attach to the free list */
/* Compute size for ProcGlobal structure */
Assert(maxBackends > 0);
semMapEntries = PROC_SEM_MAP_ENTRIES(maxBackends);
procGlobalSize = sizeof(PROC_HDR) + (semMapEntries-1) * sizeof(SEM_MAP_ENTRY);
/* Create or attach to the ProcGlobal shared structure */
ProcGlobal = (PROC_HDR *)
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
ShmemInitStruct("Proc Header", procGlobalSize, &found);
/* --------------------
* We're the first - initialize.
@@ -141,10 +148,12 @@ InitProcGlobal(int maxBackends)
int i;
ProcGlobal->freeProcs = INVALID_OFFSET;
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
ProcGlobal->semMapEntries = semMapEntries;
for (i = 0; i < semMapEntries; i++)
{
ProcGlobal->procSemIds[i] = -1;
ProcGlobal->freeSemMap[i] = 0;
ProcGlobal->procSemMap[i].procSemId = -1;
ProcGlobal->procSemMap[i].freeSemMap = 0;
}
/*
@@ -157,11 +166,9 @@ InitProcGlobal(int maxBackends)
on_shmem_exit(ProcFreeAllSemaphores, 0);
/*
* Pre-create the semaphores for the first maxBackends processes.
* Pre-create the semaphores.
*/
Assert(maxBackends > 0 && maxBackends <= MAXBACKENDS);
for (i = 0; i < ((maxBackends - 1) / PROC_NSEMS_PER_SET + 1); i++)
for (i = 0; i < semMapEntries; i++)
{
IpcSemaphoreId semId;
@@ -169,7 +176,7 @@ InitProcGlobal(int maxBackends)
IPCProtection,
1,
false);
ProcGlobal->procSemIds[i] = semId;
ProcGlobal->procSemMap[i].procSemId = semId;
}
}
}
@@ -182,9 +189,17 @@ InitProcGlobal(int maxBackends)
void
InitProcess(void)
{
bool found = false;
unsigned long location,
myOffset;
SHMEM_OFFSET myOffset;
/*
* ProcGlobal should be set by a previous call to InitProcGlobal
* (if we are a backend, we inherit this by fork() from the postmaster).
*/
if (ProcGlobal == NULL)
elog(STOP, "InitProcess: Proc Header uninitialized");
if (MyProc != NULL)
elog(ERROR, "InitProcess: you already exist");
/*
* ProcStructLock protects the freelist of PROC entries and the map
@@ -196,27 +211,9 @@ InitProcess(void)
* this routine, be careful to release the lock manually before any
* elog(), else you'll have a stuck spinlock to add to your woes.
*/
SpinAcquire(ProcStructLock);
/* attach to the ProcGlobal structure */
ProcGlobal = (PROC_HDR *)
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
if (!found)
{
/* this should not happen. InitProcGlobal() is called before this. */
SpinRelease(ProcStructLock);
elog(STOP, "InitProcess: Proc Header uninitialized");
}
if (MyProc != NULL)
{
SpinRelease(ProcStructLock);
elog(ERROR, "InitProcess: you already exist");
}
/* try to get a proc struct from the free list first */
myOffset = ProcGlobal->freeProcs;
if (myOffset != INVALID_OFFSET)
@@ -263,23 +260,6 @@ InitProcess(void)
MemSet(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
MyProc->sLocks[ProcStructLock] = 1;
/*
* Release the lock while accessing shmem index; we still haven't
* installed ProcKill and so we don't want to hold lock if there's
* an error.
*/
SpinRelease(ProcStructLock);
/*
* Install ourselves in the shmem index table. The name to use is
* determined by the OS-assigned process id. That allows the cleanup
* process to find us after any untimely exit.
*/
location = MAKE_OFFSET(MyProc);
if ((!ShmemPIDLookup(MyProcPid, &location)) ||
(location != MAKE_OFFSET(MyProc)))
elog(STOP, "InitProcess: ShmemPID table broken");
/*
* Arrange to clean up at backend exit. Once we do this, owned
* spinlocks will be released on exit, and so we can be a lot less
@@ -288,20 +268,21 @@ InitProcess(void)
on_shmem_exit(ProcKill, 0);
/*
* Set up a wait-semaphore for the proc. (Do this last so that we
* can rely on ProcKill to clean up if it fails.)
* Set up a wait-semaphore for the proc. (We rely on ProcKill to clean
* up if this fails.)
*/
if (IsUnderPostmaster)
{
SpinAcquire(ProcStructLock);
ProcGetNewSemIdAndNum(&MyProc->sem.semId, &MyProc->sem.semNum);
SpinRelease(ProcStructLock);
/*
* We might be reusing a semaphore that belongs to a dead backend.
* So be careful and reinitialize its value here.
*/
/* Done with freelist and sem map */
SpinRelease(ProcStructLock);
/*
* We might be reusing a semaphore that belongs to a dead backend.
* So be careful and reinitialize its value here.
*/
if (MyProc->sem.semId >= 0)
ZeroProcSemaphore(MyProc);
}
/*
* Now that we have a PROC, we could try to acquire locks, so
@@ -416,9 +397,7 @@ ProcReleaseLocks(bool isCommit)
static void
ProcKill(void)
{
SHMEM_OFFSET location;
Assert(MyProc);
Assert(MyProc != NULL);
/* Release any spinlocks I am holding */
ProcReleaseSpins(MyProc);
@@ -434,11 +413,6 @@ ProcKill(void)
LockReleaseAll(USER_LOCKMETHOD, MyProc, true, InvalidTransactionId);
#endif
/* Remove my PROC struct from the shmem hash table */
location = ShmemPIDDestroy(MyProcPid);
Assert(location != INVALID_OFFSET);
Assert(MyProc == (PROC *) MAKE_PTR(location));
SpinAcquire(ProcStructLock);
/* Free up my wait semaphore, if I got one */
@@ -449,9 +423,10 @@ ProcKill(void)
MyProc->links.next = ProcGlobal->freeProcs;
ProcGlobal->freeProcs = MAKE_OFFSET(MyProc);
SpinRelease(ProcStructLock);
/* PROC struct isn't mine anymore; stop tracking spinlocks with it! */
MyProc = NULL;
SpinRelease(ProcStructLock);
}
@@ -987,8 +962,8 @@ static void
ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum)
{
int i;
IpcSemaphoreId *procSemIds = ProcGlobal->procSemIds;
int32 *freeSemMap = ProcGlobal->freeSemMap;
int semMapEntries = ProcGlobal->semMapEntries;
SEM_MAP_ENTRY *procSemMap = ProcGlobal->procSemMap;
int32 fullmask = (1 << PROC_NSEMS_PER_SET) - 1;
/*
@@ -996,24 +971,24 @@ ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum)
* the bitmap to look for a free semaphore.
*/
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
for (i = 0; i < semMapEntries; i++)
{
int mask = 1;
int j;
if (freeSemMap[i] == fullmask)
if (procSemMap[i].freeSemMap == fullmask)
continue; /* this set is fully allocated */
if (procSemIds[i] < 0)
if (procSemMap[i].procSemId < 0)
continue; /* this set hasn't been initialized */
for (j = 0; j < PROC_NSEMS_PER_SET; j++)
{
if ((freeSemMap[i] & mask) == 0)
if ((procSemMap[i].freeSemMap & mask) == 0)
{
/* A free semaphore found. Mark it as allocated. */
freeSemMap[i] |= mask;
procSemMap[i].freeSemMap |= mask;
*semId = procSemIds[i];
*semId = procSemMap[i].procSemId;
*semNum = j;
return;
}
@@ -1039,14 +1014,15 @@ ProcFreeSem(IpcSemaphoreId semId, int semNum)
{
int32 mask;
int i;
int semMapEntries = ProcGlobal->semMapEntries;
mask = ~(1 << semNum);
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
for (i = 0; i < semMapEntries; i++)
{
if (ProcGlobal->procSemIds[i] == semId)
if (ProcGlobal->procSemMap[i].procSemId == semId)
{
ProcGlobal->freeSemMap[i] &= mask;
ProcGlobal->procSemMap[i].freeSemMap &= mask;
return;
}
}
@@ -1064,9 +1040,9 @@ ProcFreeAllSemaphores(void)
{
int i;
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
for (i = 0; i < ProcGlobal->semMapEntries; i++)
{
if (ProcGlobal->procSemIds[i] >= 0)
IpcSemaphoreKill(ProcGlobal->procSemIds[i]);
if (ProcGlobal->procSemMap[i].procSemId >= 0)
IpcSemaphoreKill(ProcGlobal->procSemMap[i].procSemId);
}
}