diff --git a/contrib/userlock/user_locks.c b/contrib/userlock/user_locks.c index ae33c40cc2..e1ee603f80 100644 --- a/contrib/userlock/user_locks.c +++ b/contrib/userlock/user_locks.c @@ -73,20 +73,10 @@ user_write_unlock_oid(Oid oid) } 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 */ diff --git a/src/backend/port/darwin/sem.c b/src/backend/port/darwin/sem.c index 6130e6d72b..83fc1bf118 100644 --- a/src/backend/port/darwin/sem.c +++ b/src/backend/port/darwin/sem.c @@ -10,10 +10,11 @@ * - 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 #include @@ -22,13 +23,13 @@ #include #include #include -#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 @@ -41,19 +42,23 @@ struct pending_ops 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; @@ -66,7 +71,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg) 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); @@ -132,8 +137,10 @@ semget(key_t key, int nsems, int semflg) { int fd, semid, - semnum /* , semnum1 */ ; + semnum, + nsets; int exist = 0; + Size sem_info_size; char semname[64]; if (nsems < 0 || nsems > SEMMAX) @@ -163,13 +170,20 @@ semget(key_t key, int nsems, int semflg) 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 @@ -177,30 +191,25 @@ semget(key_t key, int nsems, int semflg) #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) { @@ -228,12 +237,12 @@ semget(key_t key, int nsems, int semflg) /* 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; @@ -249,15 +258,18 @@ semget(key_t key, int nsems, int semflg) 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; @@ -279,7 +291,7 @@ semop(int semid, struct sembuf * sops, size_t nsops) sem_wait(SemInfo->sem); - if (semid < 0 || semid >= SETMAX) + if (semid < 0 || semid >= SemInfo->nsets) { sem_post(SemInfo->sem); errno = EINVAL; diff --git a/src/backend/port/qnx4/sem.c b/src/backend/port/qnx4/sem.c index 98fcc28993..a25ba759ee 100644 --- a/src/backend/port/qnx4/sem.c +++ b/src/backend/port/qnx4/sem.c @@ -7,7 +7,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -21,14 +21,15 @@ #include #include #include -#include "storage/ipc.h" -#include "storage/proc.h" #include #include #include +#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 @@ -42,19 +43,23 @@ struct pending_ops 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; @@ -78,7 +83,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg) 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); @@ -144,9 +149,11 @@ semget(key_t key, int nsems, int semflg) { 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) { @@ -167,60 +174,64 @@ semget(key_t key, int nsems, int semflg) 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) { @@ -244,9 +255,9 @@ semget(key_t key, int nsems, int semflg) /* 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; @@ -256,15 +267,18 @@ semget(key_t key, int nsems, int semflg) 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; @@ -286,7 +300,7 @@ semop(int semid, struct sembuf * sops, size_t nsops) sem_wait(&SemInfo->sem); - if (semid < 0 || semid >= SETMAX) + if (semid < 0 || semid >= SemInfo->nsets) { sem_post(&SemInfo->sem); errno = EINVAL; diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 7a588b1fc3..31521f5de4 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * 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 * @@ -138,9 +138,9 @@ char *UnixSocketDir; 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. @@ -777,8 +777,8 @@ usage(const char *progname) #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")); diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index caf94bda46..dd86609875 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -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 diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 82679eb65c..2d14245a09 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -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); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 71f85cbe58..00c1f59c07 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -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); } } diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index edaf3893e9..51c95fb141 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * 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 $ * * *------------------------------------------------------------------------- @@ -281,7 +281,7 @@ InitPostgres(const char *dbname, const char *username) InitBackendSharedInvalidationState(); - if (MyBackendId > MAXBACKENDS || MyBackendId <= 0) + if (MyBackendId > MaxBackends || MyBackendId <= 0) elog(FATAL, "InitPostgres: bad backend id %d", MyBackendId); /* diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b0bb99817d..b1299df067 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4,7 +4,7 @@ * 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 . @@ -286,7 +286,7 @@ static struct config_int * 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}, diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 30a3834261..1cd0ba7e3c 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -8,7 +8,7 @@ * 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 @@ -106,12 +106,6 @@ *------------------------------------------------------------------------ */ -/* - * 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. diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index f35144e691..0b318ec0a5 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -7,7 +7,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -104,10 +104,21 @@ do { \ * 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 { @@ -115,13 +126,12 @@ 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; /* diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h index 2768a772d6..e01a0f0143 100644 --- a/src/include/storage/shmem.h +++ b/src/include/storage/shmem.h @@ -7,7 +7,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -71,8 +71,6 @@ extern void *ShmemAlloc(Size size); 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);