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.
}
int
-user_unlock_all()
+user_unlock_all(void)
{
- PROC *proc;
- SHMEM_OFFSET location;
-
- ShmemPIDLookup(MyProcPid, &location);
- if (location == INVALID_OFFSET)
- {
- elog(NOTICE, "UserUnlockAll: unable to get proc ptr");
- return -1;
- }
-
- proc = (PROC *) MAKE_PTR(location);
- return LockReleaseAll(USER_LOCKMETHOD, proc, false, InvalidTransactionId);
+ return LockReleaseAll(USER_LOCKMETHOD, MyProc, false,
+ InvalidTransactionId);
}
/* end of file */
* - this required changing sem_info from containig an array of sem_t to an array of sem_t*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.3 2001/03/22 03:59:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.4 2001/09/07 00:27:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
+#include "postgres.h"
#include <errno.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
-#include "postgres.h"
+
+#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "port/darwin/sem.h"
#define SEMMAX IPC_NMAXSEM
-#define SETMAX ((MAXBACKENDS + SEMMAX - 1) / SEMMAX)
#define OPMAX 8
#define MODE 0700
int idx; /* index of first free array member */
};
+struct sem_set_info
+{
+ key_t key;
+ int nsems;
+ sem_t *sem[SEMMAX]; /* array of POSIX semaphores */
+ struct sem semV[SEMMAX]; /* array of System V semaphore
+ * structures */
+ struct pending_ops pendingOps[SEMMAX]; /* array of pending
+ * operations */
+};
+
struct sem_info
{
sem_t *sem;
- struct
- {
- key_t key;
- int nsems;
- sem_t *sem[SEMMAX];/* array of POSIX semaphores */
- struct sem semV[SEMMAX]; /* array of System V semaphore
- * structures */
- struct pending_ops pendingOps[SEMMAX]; /* array of pending
- * operations */
- } set[SETMAX];
+ int nsets;
+ /* there are actually nsets of these: */
+ struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
};
static struct sem_info *SemInfo = (struct sem_info *) - 1;
sem_wait(SemInfo->sem);
- if (semid < 0 || semid >= SETMAX ||
+ if (semid < 0 || semid >= SemInfo->nsets ||
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
{
sem_post(SemInfo->sem);
{
int fd,
semid,
- semnum /* , semnum1 */ ;
+ semnum,
+ nsets;
int exist = 0;
+ Size sem_info_size;
char semname[64];
if (nsems < 0 || nsems > SEMMAX)
return fd;
shm_unlink(SHM_INFO_NAME);
/* The size may only be set once. Ignore errors. */
- ftruncate(fd, sizeof(struct sem_info));
- SemInfo = mmap(NULL, sizeof(struct sem_info),
+ nsets = PROC_SEM_MAP_ENTRIES(MaxBackends);
+ sem_info_size = sizeof(struct sem_info) + (nsets-1) * sizeof(struct sem_set_info);
+ ftruncate(fd, sem_info_size);
+ SemInfo = mmap(NULL, sem_info_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (SemInfo == MAP_FAILED)
return -1;
if (!exist)
{
+ /* initialize shared memory */
+ memset(SemInfo, 0, sem_info_size);
+ SemInfo->nsets = nsets;
+ for (semid = 0; semid < nsets; semid++)
+ SemInfo->set[semid].key = -1;
/* create semaphore for locking */
sprintf(semname, "%s-map", SEM_NAME);
#ifdef DEBUG_IPC
#endif
SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1);
sem_unlink(semname);
- sem_wait(SemInfo->sem);
- /* initilize shared memory */
- memset(SemInfo->set, 0, sizeof(SemInfo->set));
- for (semid = 0; semid < SETMAX; semid++)
- SemInfo->set[semid].key = -1;
- sem_post(SemInfo->sem);
}
}
sem_wait(SemInfo->sem);
+ nsets = SemInfo->nsets;
if (key != IPC_PRIVATE)
{
/* search existing element */
semid = 0;
- while (semid < SETMAX && SemInfo->set[semid].key != key)
+ while (semid < nsets && SemInfo->set[semid].key != key)
semid++;
- if (!(semflg & IPC_CREAT) && semid >= SETMAX)
+ if (!(semflg & IPC_CREAT) && semid >= nsets)
{
sem_post(SemInfo->sem);
errno = ENOENT;
return -1;
}
- else if (semid < SETMAX)
+ else if (semid < nsets)
{
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
{
/* search first free element */
semid = 0;
- while (semid < SETMAX && SemInfo->set[semid].key != -1)
+ while (semid < nsets && SemInfo->set[semid].key != -1)
semid++;
- if (semid >= SETMAX)
+ if (semid >= nsets)
{
#ifdef DEBUG_IPC
- fprintf(stderr, "darwin semget failed because all keys were -1 up to SETMAX\n");
+ fprintf(stderr, "darwin semget failed because all keys were -1\n");
#endif
sem_post(SemInfo->sem);
errno = ENOSPC;
SemInfo->set[semid].sem[semnum] = sem_open(semname, O_CREAT, semflg & 0777, 0);
sem_unlink(semname);
-/* Currently sem_init always returns -1.
- if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
- for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
- sem_close( SemInfo->set[semid].sem[semnum1] );
- }
- sem_post( SemInfo->sem );
- return -1;
- }
-*/
+ /* Currently sem_init always returns -1. */
+#ifdef NOT_USED
+ if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
+ int semnum1;
+
+ for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
+ sem_close( SemInfo->set[semid].sem[semnum1] );
+ }
+ sem_post( SemInfo->sem );
+ return -1;
+ }
+#endif
}
SemInfo->set[semid].key = key;
sem_wait(SemInfo->sem);
- if (semid < 0 || semid >= SETMAX)
+ if (semid < 0 || semid >= SemInfo->nsets)
{
sem_post(SemInfo->sem);
errno = EINVAL;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.6 2001/08/24 14:07:49 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.7 2001/09/07 00:27:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
-#include "storage/ipc.h"
-#include "storage/proc.h"
#include <sys/sem.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include "miscadmin.h"
+#include "storage/ipc.h"
+#include "storage/proc.h"
+
-#define SETMAX ((MAXBACKENDS + PROC_NSEMS_PER_SET + 1) / PROC_NSEMS_PER_SET)
#define SEMMAX (PROC_NSEMS_PER_SET+1)
#define OPMAX 8
int idx; /* index of first free array member */
};
+struct sem_set_info
+{
+ key_t key;
+ int nsems;
+ sem_t sem[SEMMAX]; /* array of POSIX semaphores */
+ struct sem semV[SEMMAX]; /* array of System V semaphore
+ * structures */
+ struct pending_ops pendingOps[SEMMAX]; /* array of pending
+ * operations */
+};
+
struct sem_info
{
sem_t sem;
- struct
- {
- key_t key;
- int nsems;
- sem_t sem[SEMMAX];/* array of POSIX semaphores */
- struct sem semV[SEMMAX]; /* array of System V semaphore
- * structures */
- struct pending_ops pendingOps[SEMMAX]; /* array of pending
- * operations */
- } set[SETMAX];
+ int nsets;
+ /* there are actually nsets of these: */
+ struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
};
static struct sem_info *SemInfo = (struct sem_info *) - 1;
sem_wait(&SemInfo->sem);
- if (semid < 0 || semid >= SETMAX ||
+ if (semid < 0 || semid >= SemInfo->nsets ||
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
{
sem_post(&SemInfo->sem);
{
int fd,
semid,
- semnum /* , semnum1 */ ;
+ semnum,
+ nsets;
int exist = 0;
- struct stat statbuf;
+ Size sem_info_size;
+ struct stat statbuf;
if (nsems < 0 || nsems > SEMMAX)
{
if (fd == -1)
return fd;
/* The size may only be set once. Ignore errors. */
- ltrunc(fd, sizeof(struct sem_info), SEEK_SET);
- if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */
- { /* error is EBADF */
- close( fd );
- return -1;
- }
+ nsets = PROC_SEM_MAP_ENTRIES(MaxBackends);
+ sem_info_size = sizeof(struct sem_info) + (nsets-1) * sizeof(struct sem_set_info);
+ ltrunc(fd, sem_info_size, SEEK_SET);
+ if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */
+ { /* error is EBADF */
+ close( fd );
+ return -1;
+ }
/*
* size is rounded by proc to the next __PAGESIZE
*/
if ( statbuf.st_size !=
- ((( sizeof(struct sem_info) /__PAGESIZE)+1) * __PAGESIZE) )
+ (((sem_info_size/__PAGESIZE)+1) * __PAGESIZE) )
{
fprintf( stderr,
"Found a pre-existing shared memory block for the semaphore memory\n"
"of a different size (%ld instead %ld). Make sure that all executables\n"
"are from the same release or remove the file \"/dev/shmem/%s\"\n"
- "left by a previous version.\n", statbuf.st_size,
- sizeof(struct sem_info), SHM_INFO_NAME);
+ "left by a previous version.\n",
+ (long) statbuf.st_size,
+ (long) sem_info_size,
+ SHM_INFO_NAME);
errno = EACCES;
return -1;
}
- SemInfo = mmap(NULL, sizeof(struct sem_info),
+ SemInfo = mmap(NULL, sem_info_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (SemInfo == MAP_FAILED)
return -1;
if (!exist)
{
+ /* initialize shared memory */
+ memset(SemInfo, 0, sem_info_size);
+ SemInfo->nsets = nsets;
+ for (semid = 0; semid < nsets; semid++)
+ SemInfo->set[semid].key = -1;
/* create semaphore for locking */
sem_init(&SemInfo->sem, 1, 1);
- sem_wait(&SemInfo->sem);
- /* initilize shared memory */
- memset(SemInfo->set, 0, sizeof(SemInfo->set));
- for (semid = 0; semid < SETMAX; semid++)
- SemInfo->set[semid].key = -1;
- sem_post(&SemInfo->sem);
- on_proc_exit( semclean, NULL );
+ on_proc_exit( semclean, 0 );
}
}
sem_wait(&SemInfo->sem);
+ nsets = SemInfo->nsets;
if (key != IPC_PRIVATE)
{
/* search existing element */
semid = 0;
- while (semid < SETMAX && SemInfo->set[semid].key != key)
+ while (semid < nsets && SemInfo->set[semid].key != key)
semid++;
- if (!(semflg & IPC_CREAT) && semid >= SETMAX)
+ if (!(semflg & IPC_CREAT) && semid >= nsets)
{
sem_post(&SemInfo->sem);
errno = ENOENT;
return -1;
}
- else if (semid < SETMAX)
+ else if (semid < nsets)
{
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
{
/* search first free element */
semid = 0;
- while (semid < SETMAX && SemInfo->set[semid].key != -1)
+ while (semid < nsets && SemInfo->set[semid].key != -1)
semid++;
- if (semid >= SETMAX)
+ if (semid >= nsets)
{
sem_post(&SemInfo->sem);
errno = ENOSPC;
for (semnum = 0; semnum < nsems; semnum++)
{
sem_init(&SemInfo->set[semid].sem[semnum], 1, 0);
-/* Currently sem_init always returns -1.
- if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
- for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
- sem_destroy( &SemInfo->set[semid].sem[semnum1] );
- }
- sem_post( &SemInfo->sem );
- return -1;
- }
-*/
+/* Currently sem_init always returns -1. */
+#ifdef NOT_USED
+ if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
+ int semnum1;
+
+ for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
+ sem_destroy( &SemInfo->set[semid].sem[semnum1] );
+ }
+ sem_post( &SemInfo->sem );
+ return -1;
+ }
+#endif
}
SemInfo->set[semid].key = key;
sem_wait(&SemInfo->sem);
- if (semid < 0 || semid >= SETMAX)
+ if (semid < 0 || semid >= SemInfo->nsets)
{
sem_post(&SemInfo->sem);
errno = EINVAL;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.237 2001/08/30 19:02:42 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.238 2001/09/07 00:27:29 tgl Exp $
*
* NOTES
*
char *VirtualHost;
/*
- * MaxBackends is the actual limit on the number of backends we will
- * start. The default is established by configure, but it can be
- * readjusted from 1..MAXBACKENDS with the postmaster -N switch. Note
+ * MaxBackends is the limit on the number of backends we can start.
+ * The default is established by configure, but it can be altered at
+ * postmaster start with the postmaster's -N switch. Note
* that a larger MaxBackends value will increase the size of the shared
* memory area as well as cause the postmaster to grab more kernel
* semaphores, even if you never actually use that many backends.
#ifdef USE_SSL
printf(gettext(" -l enable SSL connections\n"));
#endif
- printf(gettext(" -N MAX-CONNECT maximum number of allowed connections (1..%d, default %d)\n"),
- MAXBACKENDS, DEF_MAXBACKENDS);
+ printf(gettext(" -N MAX-CONNECT maximum number of allowed connections (default %d)\n"),
+ DEF_MAXBACKENDS);
printf(gettext(" -o OPTIONS pass 'OPTIONS' to each backend server\n"));
printf(gettext(" -p PORT port number to listen on (default %d)\n"), DEF_PGPORT);
printf(gettext(" -S silent mode (start in background without logging output)\n"));
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
}
/*
- * 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.
*
if (!ShmemIndex)
{
-
/*
* If the shmem index doesn't exist, we are bootstrapping: we must
* be trying to init the shmem index itself.
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
*
*
* 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
void
DumpLocks(void)
{
- SHMEM_OFFSET location;
PROC *proc;
SHM_QUEUE *procHolders;
HOLDER *holder;
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);
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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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.
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;
}
/*
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;
IPCProtection,
1,
false);
- ProcGlobal->procSemIds[i] = semId;
+ ProcGlobal->procSemMap[i].procSemId = semId;
}
}
}
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
* 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)
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
* tense about errors.
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
static void
ProcKill(void)
{
- SHMEM_OFFSET location;
-
- Assert(MyProc);
+ Assert(MyProc != NULL);
/* Release any spinlocks I am holding */
ProcReleaseSpins(MyProc);
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 */
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);
}
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;
/*
* 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;
}
{
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;
}
}
{
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);
}
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.89 2001/09/06 04:57:29 ishii Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.90 2001/09/07 00:27:29 tgl Exp $
*
*
*-------------------------------------------------------------------------
InitBackendSharedInvalidationState();
- if (MyBackendId > MAXBACKENDS || MyBackendId <= 0)
+ if (MyBackendId > MaxBackends || MyBackendId <= 0)
elog(FATAL, "InitPostgres: bad backend id %d", MyBackendId);
/*
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.46 2001/08/15 18:42:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.47 2001/09/07 00:27:29 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
* constraints here are partially unused.
*/
{"max_connections", PGC_POSTMASTER, &MaxBackends,
- DEF_MAXBACKENDS, 1, MAXBACKENDS, NULL, NULL},
+ DEF_MAXBACKENDS, 1, INT_MAX, NULL, NULL},
{"shared_buffers", PGC_POSTMASTER, &NBuffers,
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
* or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your
* changes will be overwritten the next time you run configure.
*
- * $Id: pg_config.h.in,v 1.3 2001/09/06 03:23:38 momjian Exp $
+ * $Id: pg_config.h.in,v 1.4 2001/09/07 00:27:29 tgl Exp $
*/
#ifndef PG_CONFIG_H
*/
/*
- * Hard limit on number of backend server processes per postmaster.
- * Increasing this costs about 32 bytes per process slot as of v 6.5.
- */
-#define MAXBACKENDS (DEF_MAXBACKENDS > 1024 ? DEF_MAXBACKENDS : 1024)
-
-/*
* Default number of buffers in shared buffer pool (each of size BLCKSZ).
* This is just the default setting for the postmaster's -B switch.
* Perhaps it ought to be configurable from a configure switch.
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: proc.h,v 1.45 2001/07/06 21:04:26 tgl Exp $
+ * $Id: proc.h,v 1.46 2001/09/07 00:27:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* in each set for identification purposes.)
*
* PROC_SEM_MAP_ENTRIES is the number of semaphore sets we need to allocate
- * to keep track of up to MAXBACKENDS backends.
+ * to keep track of up to maxBackends backends.
*/
#define PROC_NSEMS_PER_SET 16
-#define PROC_SEM_MAP_ENTRIES ((MAXBACKENDS-1)/PROC_NSEMS_PER_SET+1)
+#define PROC_SEM_MAP_ENTRIES(maxBackends) (((maxBackends)-1)/PROC_NSEMS_PER_SET+1)
+
+typedef struct
+{
+ /* info about a single set of per-process semaphores */
+ IpcSemaphoreId procSemId;
+ int32 freeSemMap;
+ /*
+ * In freeSemMap, bit i is set if the i'th semaphore of this sema
+ * set is allocated to a process. (i counts from 0 at the LSB)
+ */
+} SEM_MAP_ENTRY;
typedef struct procglobal
{
SHMEM_OFFSET freeProcs;
/* Info about semaphore sets used for per-process semaphores */
- IpcSemaphoreId procSemIds[PROC_SEM_MAP_ENTRIES];
- int32 freeSemMap[PROC_SEM_MAP_ENTRIES];
-
+ int semMapEntries;
/*
- * In each freeSemMap entry, bit i is set if the i'th semaphore of the
- * set is allocated to a process. (i counts from 0 at the LSB)
+ * VARIABLE LENGTH ARRAY: actual length is semMapEntries.
+ * THIS MUST BE LAST IN THE STRUCT DECLARATION.
*/
+ SEM_MAP_ENTRY procSemMap[1];
} PROC_HDR;
/*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: shmem.h,v 1.29 2001/06/18 21:38:02 momjian Exp $
+ * $Id: shmem.h,v 1.30 2001/09/07 00:27:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern bool ShmemIsValid(unsigned long addr);
extern HTAB *ShmemInitHash(char *name, long init_size, long max_size,
HASHCTL *infoP, int hash_flags);
-extern bool ShmemPIDLookup(int pid, SHMEM_OFFSET *locationPtr);
-extern SHMEM_OFFSET ShmemPIDDestroy(int pid);
extern void *ShmemInitStruct(char *name, Size size, bool *foundPtr);