OSDN Git Service

Get rid of PID entries in shmem hash table; there is no longer any need
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 7 Sep 2001 00:27:30 +0000 (00:27 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 7 Sep 2001 00:27:30 +0000 (00:27 +0000)
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.

12 files changed:
contrib/userlock/user_locks.c
src/backend/port/darwin/sem.c
src/backend/port/qnx4/sem.c
src/backend/postmaster/postmaster.c
src/backend/storage/ipc/shmem.c
src/backend/storage/lmgr/lock.c
src/backend/storage/lmgr/proc.c
src/backend/utils/init/postinit.c
src/backend/utils/misc/guc.c
src/include/pg_config.h.in
src/include/storage/proc.h
src/include/storage/shmem.h

index ae33c40..e1ee603 100644 (file)
@@ -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 */
index 6130e6d..83fc1bf 100644 (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
@@ -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;
index 98fcc28..a25ba75 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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
 
@@ -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;
index 7a588b1..31521f5 100644 (file)
@@ -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"));
index caf94bd..dd86609 100644 (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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -260,92 +260,6 @@ ShmemInitHash(char *name,          /* table string name for shmem index */
 }
 
 /*
- * 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
index 82679eb..2d14245 100644 (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);
index 71f85cb..00c1f59 100644 (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)
@@ -264,23 +261,6 @@ InitProcess(void)
        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.
@@ -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);
        }
 }
index edaf389..51c95fb 100644 (file)
@@ -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);
 
        /*
index b0bb998..b1299df 100644 (file)
@@ -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 <peter_e@gmx.net>.
@@ -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},
index 30a3834..1cd0ba7 100644 (file)
@@ -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
  */
 
 /*
- * 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.
index f35144e..0b318ec 100644 (file)
@@ -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;
 
 /*
index 2768a77..e01a0f0 100644 (file)
@@ -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);