Get rid of PID entries in shmem hash table; there is no longer any need
authorTom Lane
Fri, 7 Sep 2001 00:27:30 +0000 (00:27 +0000)
committerTom Lane
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 ae33c40cc2d1fa1a1d02a53d810941177add3e1c..e1ee603f80e3d19e661a4a594762d4384a6e28e3 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 6130e6d72b26335397f74f9ded769c223cc43781..83fc1bf118f5c8b5bb6cc51e3ff53650c9938626 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 
 #include 
 #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;
index 98fcc28993de0c610150d20ef3acddcef628f2a2..a25ba759ee36e6780eefec05c30703fcb0fbf05c 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 
 #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;
index 7a588b1fc3c2842f32c3ae34459d9c26aca4102e..31521f5de43759ae7868136cc222623c352560e6 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 caf94bda46c6cfa5c805c3377f2a28ff3e93140c..dd86609875ef98d6b188340b679ac33552c659e3 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -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
index 82679eb65cb0b3b7ba2aee482beb190627e7e778..2d14245a09d48ad9be2637e8a6a72a56aed537e4 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 71f85cbe58ff56eb22fa18e48a7a9c09c9575849..00c1f59c07f7612d7d067ddbf827c33ab2205454 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)
@@ -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);
    }
 }
index edaf3893e9ea75a2d0e3806d3eb754a23b909ee5..51c95fb141527e0cce951ee27ec1963deb576181 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 b0bb99817d125e965ca711f2c4723f2c40b52379..b1299df06730fea4e78a30fc5aa9364c40a199fc 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 .
@@ -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 30a3834261d3563cac612a573eece4773d8c3615..1cd0ba7e3c3a600c7b5d23bc92a192d19c17a757 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.
index f35144e69190b04d3a857699ec75684039feb182..0b318ec0a54f01be8a88378e343009b4abdde656 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 2768a772d663cc97e907efab461c09952633fcf3..e01a0f014355eb40b8574c8a0e366d8db167786e 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);